Revert "Fix simulation"

This reverts commit 468f43c7a6.

Revert "Add initial dynamic declarations"

This reverts commit 50a2c77c4e.

Revert "Add initial simulation state items array to output node"

This reverts commit 3f1027567d.
This commit is contained in:
Hans Goudey 2022-12-19 12:03:42 -06:00
parent 38567bc023
commit 508fd044b4
Notes: blender-bot 2023-02-14 07:39:44 +01:00
Referenced by issue #103841, [Geometry nodes] Normals not recalculating after deformation - Simulation nodes branch only
Referenced by issue #103596, Blender 3.5: Cursor warping usable on windows remote desktop (RDP)
8 changed files with 79 additions and 246 deletions

View File

@ -1124,12 +1124,12 @@ static void node_init(const bContext *C, bNodeTree *ntree, bNode *node)
BLI_strncpy(node->name, DATA_(ntype->ui_name), NODE_MAXSTR);
nodeUniqueName(ntree, node);
node_add_sockets_from_type(ntree, node, ntype);
if (ntype->initfunc != nullptr) {
ntype->initfunc(ntree, node);
}
node_add_sockets_from_type(ntree, node, ntype);
if (ntree->typeinfo && ntree->typeinfo->node_add_init) {
ntree->typeinfo->node_add_init(ntree, node);
}
@ -3620,7 +3620,7 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree * /*ntree*/, bNode *node)
}
if (node->typeinfo->declaration_is_dynamic) {
node->runtime->declaration = new blender::nodes::NodeDeclaration();
blender::nodes::build_node_declaration_dynamic(*node, *node->runtime->declaration);
blender::nodes::build_node_declaration(*node->typeinfo, *node->runtime->declaration);
}
else {
/* Declaration should have been created in #nodeRegisterType. */

View File

@ -1579,24 +1579,12 @@ typedef struct NodeGeometryUVUnwrap {
uint8_t method;
} NodeGeometryUVUnwrap;
typedef struct SimulationStateItem {
char *name;
/* TODO: Use a different enum instead to support Byte colors, geometry, etc. */
/* eNodeSocketDatatype */
int8_t data_type;
char _pad[7];
} SimulationStateItem;
typedef struct NodeGeometrySimulationInput {
int32_t output_node_id;
} NodeGeometrySimulationInput;
typedef struct NodeGeometrySimulationOutput {
SimulationStateItem *state_items;
int state_items_num;
int8_t use_persistent_cache;
char _pad[3];
} NodeGeometrySimulationOutput;
typedef struct NodeGeometryDistributePointsInVolume {

View File

@ -9695,18 +9695,8 @@ static void def_geo_set_curve_normal(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void rna_def_simulation_state_item(BlenderRNA *brna)
static void def_geo_simulation_input(StructRNA *srna)
{
StructRNA *srna = RNA_def_struct(brna, "SimulationStateItem", NULL);
RNA_def_struct_ui_text(srna, "Simulation Sate Item", "");
RNA_def_struct_sdna(srna, "SimulationStateItem");
PropertyRNA *prop;
// prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
// RNA_def_property_ui_text(prop, "Name", "");
// RNA_def_struct_name_property(srna, prop);
// RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
}
static void def_geo_simulation_output(StructRNA *srna)
@ -9718,11 +9708,6 @@ static void def_geo_simulation_output(StructRNA *srna)
prop = RNA_def_property(srna, "use_persistent_cache", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Persistent Cache", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "state_items", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "state_items", "state_items_num");
RNA_def_property_struct_type(prop, "SimulationStateItem");
RNA_def_property_ui_text(prop, "Inputs", "");
}
static void def_geo_curve_handle_type_selection(StructRNA *srna)
@ -12998,7 +12983,6 @@ void RNA_def_nodetree(BlenderRNA *brna)
rna_def_shader_node(brna);
rna_def_compositor_node(brna);
rna_def_texture_node(brna);
rna_def_simulation_state_item(brna);
rna_def_geometry_node(brna);
rna_def_function_node(brna);

View File

@ -325,19 +325,11 @@ class NodeDeclaration {
class NodeDeclarationBuilder {
private:
NodeDeclaration &declaration_;
const bNode *node_;
Vector<std::unique_ptr<BaseSocketDeclarationBuilder>> builders_;
bool is_function_node_ = false;
public:
NodeDeclarationBuilder(NodeDeclaration &declaration);
NodeDeclarationBuilder(const bNode &node, NodeDeclaration &declaration);
/** Only valid for nodes with dynamic declarations. */
const bNode &node()
{
return *node_;
}
/**
* All inputs support fields, and all outputs are fields if any of the inputs is a field.
@ -369,7 +361,6 @@ void index(const bNode &node, void *r_value);
void id_or_index(const bNode &node, void *r_value);
} // namespace implicit_field_inputs
void build_node_declaration_dynamic(const bNode &node, NodeDeclaration &r_declaration);
void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration);
/* -------------------------------------------------------------------- */
@ -525,12 +516,6 @@ inline NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declarati
{
}
inline NodeDeclarationBuilder::NodeDeclarationBuilder(const bNode &node,
NodeDeclaration &declaration)
: declaration_(declaration), node_(&node)
{
}
template<typename DeclType>
inline typename DeclType::Builder &NodeDeclarationBuilder::add_input(StringRef name,
StringRef identifier)

View File

@ -412,7 +412,7 @@ DefNode(GeometryNode, GEO_NODE_SET_POSITION, 0, "SET_POSITION", SetPosition, "Se
DefNode(GeometryNode, GEO_NODE_SET_SHADE_SMOOTH, 0, "SET_SHADE_SMOOTH", SetShadeSmooth, "Set Shade Smooth", "Control the smoothness of mesh normals around each face by changing the \"shade smooth\" attribute")
DefNode(GeometryNode, GEO_NODE_SET_SPLINE_CYCLIC, 0, "SET_SPLINE_CYCLIC", SetSplineCyclic, "Set Spline Cyclic", "Control whether each spline loops back on itself by changing the \"cyclic\" attribute")
DefNode(GeometryNode, GEO_NODE_SET_SPLINE_RESOLUTION, 0, "SET_SPLINE_RESOLUTION", SetSplineResolution, "Set Spline Resolution", "Control how many evaluated points should be generated on every curve segment")
DefNode(GeometryNode, GEO_NODE_SIMULATION_INPUT, 0, "SIMULATION_INPUT", SimulationInput, "Simulation Input", "")
DefNode(GeometryNode, GEO_NODE_SIMULATION_INPUT, def_geo_simulation_input, "SIMULATION_INPUT", SimulationInput, "Simulation Input", "")
DefNode(GeometryNode, GEO_NODE_SIMULATION_OUTPUT, def_geo_simulation_output, "SIMULATION_OUTPUT", SimulationOutput, "Simulation Output", "")
DefNode(GeometryNode, GEO_NODE_SPLIT_EDGES, 0, "SPLIT_EDGES", SplitEdges, "Split Edges", "Duplicate mesh edges and break connections with the surrounding faces")
DefNode(GeometryNode, GEO_NODE_STORE_NAMED_ATTRIBUTE, def_geo_store_named_attribute, "STORE_NAMED_ATTRIBUTE", StoreNamedAttribute, "Store Named Attribute", "Store the result of a field on a geometry as an attribute with the specified name")

View File

@ -17,60 +17,25 @@ NODE_STORAGE_FUNCS(NodeGeometrySimulationInput);
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Float>(N_("Delta Time"));
const bNode &node = b.node();
const NodeGeometrySimulationInput &storage = node_storage(node);
const int32_t sim_output_node_id = storage.output_node_id;
/* TODO: Add node tree and ndoe as arguments to new dynamic declaration function. */
node.owner_tree().ensure_topology_cache();
const bNode *sim_output_node = node.owner_tree().node_by_id(sim_output_node_id);
if (!sim_output_node) {
return;
}
const NodeGeometrySimulationOutput &output_storage =
*static_cast<const NodeGeometrySimulationOutput *>(sim_output_node->storage);
const Span<SimulationStateItem> items(output_storage.state_items,
output_storage.state_items_num);
for (const int i : items.index_range()) {
const SimulationStateItem &item = items[i];
switch (item.data_type) {
case SOCK_FLOAT:
b.add_input<decl::Float>(item.name).supports_field();
b.add_output<decl::Float>(item.name).dependent_field({i});
break;
case SOCK_VECTOR:
b.add_input<decl::Vector>(item.name).supports_field();
b.add_output<decl::Vector>(item.name).dependent_field({i});
break;
case SOCK_RGBA:
b.add_input<decl::Color>(item.name).supports_field();
b.add_output<decl::Color>(item.name).dependent_field({i});
break;
case SOCK_BOOLEAN:
b.add_input<decl::Bool>(item.name).supports_field();
b.add_output<decl::Bool>(item.name).dependent_field({i});
break;
case SOCK_INT:
b.add_input<decl::Int>(item.name).supports_field();
b.add_output<decl::Int>(item.name).dependent_field({i});
break;
case SOCK_STRING:
b.add_input<decl::String>(item.name);
b.add_output<decl::String>(item.name);
break;
case SOCK_GEOMETRY:
b.add_input<decl::Geometry>(item.name);
b.add_output<decl::Geometry>(item.name);
break;
}
}
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Extend>("", N_("__extend__"));
b.add_output<decl::Float>(N_("Delta Time"));
b.add_output<decl::Geometry>(N_("Geometry"));
b.add_output<decl::Extend>("", N_("__extend__"));
}
static void node_layout(uiLayout * /*layout*/, bContext * /*C*/, PointerRNA * /*ptr*/)
{
// const NodeGeometrySimulationInput &storage = node_storage(
// *static_cast<const bNode *>(ptr->data));
// const bNodeTree &node_tree = *reinterpret_cast<const bNodeTree *>(ptr->owner_id);
// const bNode *sim_output = node_tree.node_by_id(storage.output_node_id);
// if (sim_output) {
// uiItemL(layout, sim_output->name, ICON_PHYSICS);
// }
}
static void node_init(bNodeTree *tree, bNode *node)
{
NodeGeometrySimulationInput *data = MEM_cnew<NodeGeometrySimulationInput>(__func__);
@ -103,19 +68,8 @@ static void node_init(bNodeTree *tree, bNode *node)
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
const NodeGeometrySimulationInput &storage = node_storage(node);
const NodeGeometrySimulationInput &storage = node_storage(params.node());
const int32_t sim_output_node_id = storage.output_node_id;
const bNode *sim_output_node = node.owner_tree().node_by_id(sim_output_node_id);
if (!sim_output_node) {
params.error_message_add(NodeWarningType::Error, TIP_("Missing simulation output node"));
params.set_default_remaining_outputs();
return;
}
const NodeGeometrySimulationOutput &output_storage =
*static_cast<const NodeGeometrySimulationOutput *>(sim_output_node->storage);
const Span<SimulationStateItem> items(output_storage.state_items,
output_storage.state_items_num);
const Scene *scene = DEG_get_input_scene(params.depsgraph());
const float scene_ctime = BKE_scene_ctime_get(scene);
@ -126,41 +80,31 @@ static void node_geo_exec(GeoNodeExecParams params)
const bke::NodeGroupComputeContext cache_context(lf_data.compute_context, sim_output_node_id);
bke::sim::SimulationCache *cache = all_caches.lookup_context(cache_context.hash());
if (!cache) {
params.set_output("Geometry", params.extract_input<GeometrySet>("Geometry"));
return;
}
if (params.lazy_output_is_required("Delta Time")) {
if (cache) {
const float time_diff = cache->is_empty() ? 0.0f :
scene_ctime - cache->last_run_time()->time;
const double frame_rate = (double(scene->r.frs_sec) / double(scene->r.frs_sec_base));
const float delta_time = float(std::max(0.0f, time_diff) / frame_rate);
params.set_output("Delta Time", delta_time);
}
else {
params.set_output("Delta Time", 0.0f);
}
const float time_diff = cache->is_empty() ? 0.0f : scene_ctime - cache->last_run_time()->time;
const double frame_rate = (double(scene->r.frs_sec) / double(scene->r.frs_sec_base));
const float delta_time = float(std::max(0.0f, time_diff) / frame_rate);
params.set_output("Delta Time", delta_time);
}
for (const SimulationStateItem &item : items) {
/* TODO: Generic data type. */
if (!cache) {
params.set_output(item.name, params.extract_input<GeometrySet>(item.name));
continue;
if (std::optional<GeometrySet> cached_value = cache->value_before_time("Geometry", time)) {
if (params.lazy_output_is_required("Geometry")) {
params.set_output("Geometry", std::move(*cached_value));
}
if (std::optional<GeometrySet> cached_value = cache->value_before_time(item.name, time)) {
if (params.lazy_output_is_required(item.name)) {
params.set_output(item.name, std::move(*cached_value));
}
continue;
}
if (params.lazy_require_input(item.name)) {
continue;
}
GeometrySet geometry_set = params.extract_input<GeometrySet>(item.name);
params.set_output(item.name, std::move(geometry_set));
return;
}
if (params.lazy_require_input("Geometry")) {
return;
}
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
params.set_output("Geometry", std::move(geometry_set));
}
} // namespace blender::nodes::node_geo_simulation_input_cc
@ -174,12 +118,13 @@ void register_node_type_geo_simulation_input()
ntype.initfunc = file_ns::node_init;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_layout;
node_type_storage(&ntype,
"NodeGeometrySimulationInput",
node_free_standard_storage,
node_copy_standard_storage);
ntype.geometry_node_execute_supports_laziness = true;
ntype.declaration_is_dynamic = true;
// ntype.declaration_is_dynamic = true;
nodeRegisterType(&ntype);
}

View File

@ -17,76 +17,17 @@ NODE_STORAGE_FUNCS(NodeGeometrySimulationOutput);
static void node_declare(NodeDeclarationBuilder &b)
{
const NodeGeometrySimulationOutput &storage = node_storage(b.node());
const Span<SimulationStateItem> items(storage.state_items, storage.state_items_num);
for (const int i : items.index_range()) {
const SimulationStateItem &item = items[i];
switch (item.data_type) {
case SOCK_FLOAT:
b.add_input<decl::Float>(item.name).supports_field();
b.add_output<decl::Float>(item.name).dependent_field({i});
break;
case SOCK_VECTOR:
b.add_input<decl::Vector>(item.name).supports_field();
b.add_output<decl::Vector>(item.name).dependent_field({i});
break;
case SOCK_RGBA:
b.add_input<decl::Color>(item.name).supports_field();
b.add_output<decl::Color>(item.name).dependent_field({i});
break;
case SOCK_BOOLEAN:
b.add_input<decl::Bool>(item.name).supports_field();
b.add_output<decl::Bool>(item.name).dependent_field({i});
break;
case SOCK_INT:
b.add_input<decl::Int>(item.name).supports_field();
b.add_output<decl::Int>(item.name).dependent_field({i});
break;
case SOCK_STRING:
b.add_input<decl::String>(item.name);
b.add_output<decl::String>(item.name);
break;
case SOCK_GEOMETRY:
b.add_input<decl::Geometry>(item.name);
b.add_output<decl::Geometry>(item.name);
break;
}
}
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Extend>("", N_("__extend__"));
b.add_output<decl::Geometry>(N_("Geometry"));
b.add_output<decl::Extend>("", N_("__extend__"));
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeGeometrySimulationOutput *storage = MEM_cnew<NodeGeometrySimulationOutput>(__func__);
storage->state_items = MEM_cnew_array<SimulationStateItem>(1, __func__);
storage->state_items[0].name = BLI_strdup(DATA_("Geometry"));
storage->state_items[0].data_type = SOCK_GEOMETRY;
storage->state_items_num = 1;
storage->use_persistent_cache = false;
node->storage = storage;
}
static void node_free_storage(bNode *node)
{
NodeGeometrySimulationOutput &storage = node_storage(*node);
for (SimulationStateItem &item : MutableSpan(storage.state_items, storage.state_items_num)) {
MEM_SAFE_FREE(item.name);
}
MEM_SAFE_FREE(storage.state_items);
}
static void node_copy_storage(bNodeTree * /*dest_ntree*/, bNode *dst_node, const bNode *src_node)
{
const NodeGeometrySimulationOutput &src = node_storage(*src_node);
NodeGeometrySimulationOutput *dst = MEM_cnew<NodeGeometrySimulationOutput>(__func__);
MEM_SAFE_FREE(dst->state_items);
dst->state_items = MEM_cnew_array<SimulationStateItem>(src.state_items_num, __func__);
dst->state_items_num = src.state_items_num;
for (const int i : IndexRange(dst->state_items_num)) {
dst->state_items[i].name = static_cast<char *>(MEM_dupallocN(src.state_items[i].name));
}
dst_node->storage = dst;
NodeGeometrySimulationOutput *data = MEM_cnew<NodeGeometrySimulationOutput>(__func__);
data->use_persistent_cache = false;
node->storage = data;
}
static void node_geo_exec(GeoNodeExecParams params)
@ -99,42 +40,39 @@ static void node_geo_exec(GeoNodeExecParams params)
const GeoNodesLFUserData &lf_data = *params.user_data();
bke::sim::ComputeCaches &all_caches = *lf_data.modifier_data->cache_per_frame;
const bke::NodeGroupComputeContext cache_context(lf_data.compute_context, node.identifier);
bke::sim::SimulationCache &cache = all_caches.ensure_for_context(cache_context.hash());
for (const SimulationStateItem &item : Span(storage.state_items, storage.state_items_num)) {
/* TODO: Generic data types. */
if (std::optional<GeometrySet> value = cache.value_at_time(item.name, time)) {
params.set_output(item.name, std::move(*value));
params.set_input_unused(item.name);
continue;
}
if (params.lazy_require_input(item.name)) {
continue;
}
GeometrySet geometry_set = params.extract_input<GeometrySet>(item.name);
geometry_set.ensure_owns_direct_data();
if (storage.use_persistent_cache) {
if (!cache.is_empty()) {
if (time.time < cache.start_time()->time) {
cache.clear();
}
}
/* If using the cache or there is no cached data yet, write the input in a new cache
* value.
*/
cache.store_persistent(item.name, time, geometry_set);
}
else {
/* TODO: Maybe don't clear the whole cache here. */
/* TODO: Move the geometry set here if the output isn't needed. */
cache.clear();
cache.store_temporary(item.name, time, geometry_set);
}
params.set_output(item.name, std::move(geometry_set));
if (std::optional<GeometrySet> value = cache.value_at_time("Geometry", time)) {
params.set_output("Geometry", std::move(*value));
params.set_input_unused("Geometry");
return;
}
if (params.lazy_require_input("Geometry")) {
return;
}
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
geometry_set.ensure_owns_direct_data();
if (storage.use_persistent_cache) {
if (!cache.is_empty()) {
if (time.time < cache.start_time()->time) {
cache.clear();
}
}
/* If using the cache or there is no cached data yet, write the input in a new cache value. */
cache.store_persistent("Geometry", time, geometry_set);
}
else {
/* TODO: Maybe don't clear the whole cache here. */
/* TODO: Move the geometry set here if the output isn't needed. */
cache.clear();
cache.store_temporary("Geometry", time, geometry_set);
}
params.set_output("Geometry", std::move(geometry_set));
}
} // namespace blender::nodes::node_geo_simulation_output_cc
@ -152,9 +90,9 @@ void register_node_type_geo_simulation_output()
ntype.declare = file_ns::node_declare;
node_type_storage(&ntype,
"NodeGeometrySimulationOutput",
file_ns::node_free_storage,
file_ns::node_copy_storage);
node_free_standard_storage,
node_copy_standard_storage);
ntype.geometry_node_execute_supports_laziness = true;
ntype.declaration_is_dynamic = true;
// ntype.declaration_is_dynamic = true;
nodeRegisterType(&ntype);
}

View File

@ -7,13 +7,6 @@
namespace blender::nodes {
void build_node_declaration_dynamic(const bNode &node, NodeDeclaration &r_declaration)
{
NodeDeclarationBuilder node_decl_builder{node, r_declaration};
node.typeinfo->declare(node_decl_builder);
node_decl_builder.finalize();
}
void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration)
{
NodeDeclarationBuilder node_decl_builder{r_declaration};