From 6599c3ad4ecf434de18167f471b919f79165acfa Mon Sep 17 00:00:00 2001 From: illua1 Date: Wed, 29 Mar 2023 16:34:17 +0300 Subject: [PATCH 1/2] init commit --- source/blender/modifiers/intern/MOD_nodes.cc | 212 +++++++++++++------ 1 file changed, 148 insertions(+), 64 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 564c270674b..befb6cef29a 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -12,6 +12,7 @@ #include "MEM_guardedalloc.h" #include "BLI_array.hh" +#include "BLI_hash.hh" #include "BLI_listbase.h" #include "BLI_math_vector_types.hh" #include "BLI_multi_value_map.hh" @@ -145,38 +146,80 @@ static void initData(ModifierData *md) MEMCPY_STRUCT_AFTER(nmd, DNA_struct_default_get(NodesModifierData), modifier); } -static void add_used_ids_from_sockets(const ListBase &sockets, Set &ids) +enum eNodeModifierIDRelation : int8_t { + OBJECT_GEOMETRY = 1 << 0, + OBJECT_TRANSFORM = 1 << 1, + OBJECT_LAYERS = 1 << 2, + COLLECTION = 1 << 3, + CURVES = 1 << 4, + ALL = ~0, +}; + +/* +template inline T operator~ (T a) { return (T)~(int)a; } +template inline T operator| (T a, T b) { return (T)((int)a | (int)b); } +template inline T operator& (T a, T b) { return (T)((int)a & (int)b); } +template inline T operator^ (T a, T b) { return (T)((int)a ^ (int)b); } +template inline T& operator&= (T& a, T b) { return (T&)((int&)a &= (int)b); } +template inline T& operator^= (T& a, T b) { return (T&)((int&)a ^= (int)b); } +*/ +template inline T &operator|=(T &a, T b) +{ + return (T &)((int8_t &)a |= (int8_t)b); +} + +struct IDRelation { + ID *id; + eNodeModifierIDRelation flag; + + uint64_t hash() const + { + return blender::get_default_hash_2(id, flag); + } + + bool operator==(const IDRelation &other) const + { + return (this->id == other.id) && (this->flag == other.flag); + } +}; + +static void add_used_ids_from_sockets(const ListBase &sockets, Set &ids) { LISTBASE_FOREACH (const bNodeSocket *, socket, &sockets) { switch (socket->type) { case SOCK_OBJECT: { if (Object *object = ((bNodeSocketValueObject *)socket->default_value)->value) { - ids.add(&object->id); + IDRelation relation{&object->id, ALL}; + ids.add(relation); } break; } case SOCK_COLLECTION: { if (Collection *collection = ((bNodeSocketValueCollection *)socket->default_value)->value) { - ids.add(&collection->id); + IDRelation relation{&collection->id, ALL}; + ids.add(relation); } break; } case SOCK_MATERIAL: { if (Material *material = ((bNodeSocketValueMaterial *)socket->default_value)->value) { - ids.add(&material->id); + IDRelation relation{&material->id, ALL}; + ids.add(relation); } break; } case SOCK_TEXTURE: { if (Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value) { - ids.add(&texture->id); + IDRelation relation{&texture->id, ALL}; + ids.add(relation); } break; } case SOCK_IMAGE: { if (Image *image = ((bNodeSocketValueImage *)socket->default_value)->value) { - ids.add(&image->id); + IDRelation relation{&image->id, ALL}; + ids.add(relation); } break; } @@ -190,60 +233,92 @@ static void add_used_ids_from_sockets(const ListBase &sockets, Set &ids) * more properties like whether the node is muted, but we would have to accept the cost of updating * relations when those properties are changed. */ -static bool node_needs_own_transform_relation(const bNode &node) -{ - if (node.type == GEO_NODE_COLLECTION_INFO) { - const NodeGeometryCollectionInfo &storage = *static_cast( - node.storage); - return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE; - } - - if (node.type == GEO_NODE_OBJECT_INFO) { - const NodeGeometryObjectInfo &storage = *static_cast( - node.storage); - return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE; - } - - if (node.type == GEO_NODE_SELF_OBJECT) { - return true; - } - if (node.type == GEO_NODE_DEFORM_CURVES_ON_SURFACE) { - return true; - } - - return false; -} - static void process_nodes_for_depsgraph(const bNodeTree &tree, - Set &ids, + Set &ids, bool &r_needs_own_transform_relation) { Set handled_groups; LISTBASE_FOREACH (const bNode *, node, &tree.nodes) { - add_used_ids_from_sockets(node->inputs, ids); - add_used_ids_from_sockets(node->outputs, ids); - - if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) { - const bNodeTree *group = (bNodeTree *)node->id; - if (group != nullptr && handled_groups.add(group)) { - process_nodes_for_depsgraph(*group, ids, r_needs_own_transform_relation); + switch (node->type) { + case (NODE_GROUP): + case (NODE_CUSTOM_GROUP): { + const bNodeTree *group = (bNodeTree *)node->id; + if (group != nullptr && handled_groups.add(group)) { + process_nodes_for_depsgraph(*group, ids, r_needs_own_transform_relation); + } + add_used_ids_from_sockets(node->inputs, ids); + add_used_ids_from_sockets(node->outputs, ids); + break; + } + case (GEO_NODE_COLLECTION_INFO): { + const NodeGeometryCollectionInfo &storage = + *static_cast(node->storage); + const bool own_transform_relation = storage.transform_space == + GEO_NODE_TRANSFORM_SPACE_RELATIVE; + bNodeSocket *collection_socket = nodeFindSocket(node, SOCK_IN, "Collection"); + BLI_assert(collection_socket); + Collection *collection = + collection_socket->default_value_typed()->value; + if (collection == nullptr) { + break; + } + IDRelation relation{&collection->id, OBJECT_GEOMETRY}; + if (own_transform_relation) { + relation.flag |= OBJECT_TRANSFORM; + r_needs_own_transform_relation = true; + } + ids.add(relation); + break; + } + case (GEO_NODE_OBJECT_INFO): { + const NodeGeometryObjectInfo &storage = *static_cast( + node->storage); + const bool own_transform_relation = storage.transform_space == + GEO_NODE_TRANSFORM_SPACE_RELATIVE; + bNodeSocket *object_socket = nodeFindSocket(node, SOCK_IN, "Object"); + BLI_assert(object_socket); + Object *object = object_socket->default_value_typed()->value; + if (object == nullptr) { + break; + } + IDRelation relation{&object->id, OBJECT_GEOMETRY}; + if (own_transform_relation) { + relation.flag |= OBJECT_TRANSFORM; + r_needs_own_transform_relation = true; + } + ids.add(relation); + break; + } + case (GEO_NODE_SELF_OBJECT): { + r_needs_own_transform_relation = true; + break; + } + case (GEO_NODE_DEFORM_CURVES_ON_SURFACE): { + r_needs_own_transform_relation = true; + break; + } + default: { + add_used_ids_from_sockets(node->inputs, ids); + add_used_ids_from_sockets(node->outputs, ids); + break; } } - r_needs_own_transform_relation |= node_needs_own_transform_relation(*node); } } -static void find_used_ids_from_settings(const NodesModifierSettings &settings, Set &ids) +static void find_used_ids_from_settings(const NodesModifierSettings &settings, + Set &ids) { IDP_foreach_property( settings.properties, IDP_TYPE_FILTER_ID, [](IDProperty *property, void *user_data) { - Set *ids = (Set *)user_data; + Set *ids = (Set *)user_data; ID *id = IDP_Id(property); if (id != nullptr) { - ids->add(id); + IDRelation relation{id, ALL}; + ids->add(relation); } }, &ids); @@ -257,23 +332,33 @@ static const CustomData_MeshMasks dependency_data_mask{CD_MASK_PROP_ALL | CD_MAS CD_MASK_PROP_ALL}; static void add_collection_relation(const ModifierUpdateDepsgraphContext *ctx, - Collection &collection) + const IDRelation &collection_relation) { - DEG_add_collection_geometry_relation(ctx->node, &collection, "Nodes Modifier"); - DEG_add_collection_geometry_customdata_mask(ctx->node, &collection, &dependency_data_mask); + Collection *collection = reinterpret_cast(collection_relation.id); + DEG_add_collection_geometry_relation(ctx->node, collection, "Nodes Modifier"); + DEG_add_collection_geometry_customdata_mask(ctx->node, collection, &dependency_data_mask); } -static void add_object_relation(const ModifierUpdateDepsgraphContext *ctx, Object &object) +static void add_object_relation(const ModifierUpdateDepsgraphContext *ctx, + const IDRelation &object_relation) { - DEG_add_object_relation(ctx->node, &object, DEG_OB_COMP_TRANSFORM, "Nodes Modifier"); - if (&(ID &)object != &ctx->object->id) { - if (object.type == OB_EMPTY && object.instance_collection != nullptr) { - add_collection_relation(ctx, *object.instance_collection); - } - else if (DEG_object_has_geometry_component(&object)) { - DEG_add_object_relation(ctx->node, &object, DEG_OB_COMP_GEOMETRY, "Nodes Modifier"); - DEG_add_customdata_mask(ctx->node, &object, &dependency_data_mask); - } + Object &object = *reinterpret_cast(object_relation.id); + + if (&(ID &)object == &ctx->object->id) { + return; + } + + if (object_relation.flag & OBJECT_TRANSFORM) { + DEG_add_object_relation(ctx->node, &object, DEG_OB_COMP_TRANSFORM, "Nodes Modifier"); + } + + if (object.type == OB_EMPTY && object.instance_collection != nullptr) { + add_collection_relation(ctx, object_relation); + return; + } + if (DEG_object_has_geometry_component(&object)) { + DEG_add_object_relation(ctx->node, &object, DEG_OB_COMP_GEOMETRY, "Nodes Modifier"); + DEG_add_customdata_mask(ctx->node, &object, &dependency_data_mask); } } @@ -287,32 +372,31 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte DEG_add_node_tree_output_relation(ctx->node, nmd->node_group, "Nodes Modifier"); bool needs_own_transform_relation = false; - Set used_ids; + Set used_ids; find_used_ids_from_settings(nmd->settings, used_ids); process_nodes_for_depsgraph(*nmd->node_group, used_ids, needs_own_transform_relation); if (ctx->object->type == OB_CURVES) { Curves *curves_id = static_cast(ctx->object->data); if (curves_id->surface != nullptr) { - used_ids.add(&curves_id->surface->id); + IDRelation relation{&curves_id->surface->id, CURVES}; + used_ids.add(relation); } } - for (ID *id : used_ids) { - switch ((ID_Type)GS(id->name)) { + for (const IDRelation &id_relation : used_ids) { + switch ((ID_Type)GS(id_relation.id->name)) { case ID_OB: { - Object *object = reinterpret_cast(id); - add_object_relation(ctx, *object); + add_object_relation(ctx, id_relation); break; } case ID_GR: { - Collection *collection = reinterpret_cast(id); - add_collection_relation(ctx, *collection); + add_collection_relation(ctx, id_relation); break; } case ID_IM: case ID_TE: { - DEG_add_generic_id_relation(ctx->node, id, "Nodes Modifier"); + DEG_add_generic_id_relation(ctx->node, id_relation.id, "Nodes Modifier"); break; } default: { -- 2.30.2 From 5cb999089e35c19685b1611ccf95be671a8d701c Mon Sep 17 00:00:00 2001 From: illua1 Date: Sat, 1 Apr 2023 01:15:42 +0300 Subject: [PATCH 2/2] progress --- source/blender/modifiers/intern/MOD_nodes.cc | 81 ++++++-------------- 1 file changed, 23 insertions(+), 58 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index befb6cef29a..83cfe50870d 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -155,71 +155,38 @@ enum eNodeModifierIDRelation : int8_t { ALL = ~0, }; -/* -template inline T operator~ (T a) { return (T)~(int)a; } -template inline T operator| (T a, T b) { return (T)((int)a | (int)b); } -template inline T operator& (T a, T b) { return (T)((int)a & (int)b); } -template inline T operator^ (T a, T b) { return (T)((int)a ^ (int)b); } -template inline T& operator&= (T& a, T b) { return (T&)((int&)a &= (int)b); } -template inline T& operator^= (T& a, T b) { return (T&)((int&)a ^= (int)b); } -*/ -template inline T &operator|=(T &a, T b) -{ - return (T &)((int8_t &)a |= (int8_t)b); -} - -struct IDRelation { - ID *id; - eNodeModifierIDRelation flag; - - uint64_t hash() const - { - return blender::get_default_hash_2(id, flag); - } - - bool operator==(const IDRelation &other) const - { - return (this->id == other.id) && (this->flag == other.flag); - } -}; - -static void add_used_ids_from_sockets(const ListBase &sockets, Set &ids) +static void add_used_ids_from_sockets(const ListBase &sockets, Map &ids) { LISTBASE_FOREACH (const bNodeSocket *, socket, &sockets) { switch (socket->type) { case SOCK_OBJECT: { if (Object *object = ((bNodeSocketValueObject *)socket->default_value)->value) { - IDRelation relation{&object->id, ALL}; - ids.add(relation); + ids.lookup_or_add_default(&object->id) = ALL; } break; } case SOCK_COLLECTION: { if (Collection *collection = ((bNodeSocketValueCollection *)socket->default_value)->value) { - IDRelation relation{&collection->id, ALL}; - ids.add(relation); + ids.lookup_or_add_default(&collection->id) = ALL; } break; } case SOCK_MATERIAL: { if (Material *material = ((bNodeSocketValueMaterial *)socket->default_value)->value) { - IDRelation relation{&material->id, ALL}; - ids.add(relation); + ids.lookup_or_add_default(&material->id) = ALL; } break; } case SOCK_TEXTURE: { if (Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value) { - IDRelation relation{&texture->id, ALL}; - ids.add(relation); + ids.lookup_or_add_default(&texture->id) = ALL; } break; } case SOCK_IMAGE: { if (Image *image = ((bNodeSocketValueImage *)socket->default_value)->value) { - IDRelation relation{&image->id, ALL}; - ids.add(relation); + ids.lookup_or_add_default(&image->id) = ALL; } break; } @@ -234,7 +201,7 @@ static void add_used_ids_from_sockets(const ListBase &sockets, Set & * relations when those properties are changed. */ static void process_nodes_for_depsgraph(const bNodeTree &tree, - Set &ids, + Map &ids, bool &r_needs_own_transform_relation) { Set handled_groups; @@ -263,12 +230,12 @@ static void process_nodes_for_depsgraph(const bNodeTree &tree, if (collection == nullptr) { break; } - IDRelation relation{&collection->id, OBJECT_GEOMETRY}; + eNodeModifierIDRelation &id_relation = ids.lookup_or_add_default(&collection->id); + id_relation = OBJECT_GEOMETRY; if (own_transform_relation) { - relation.flag |= OBJECT_TRANSFORM; + id_relation |= OBJECT_TRANSFORM; r_needs_own_transform_relation = true; } - ids.add(relation); break; } case (GEO_NODE_OBJECT_INFO): { @@ -282,12 +249,12 @@ static void process_nodes_for_depsgraph(const bNodeTree &tree, if (object == nullptr) { break; } - IDRelation relation{&object->id, OBJECT_GEOMETRY}; + eNodeModifierIDRelation &id_relation = ids.lookup_or_add_default(&collection->id); + id_relation = OBJECT_GEOMETRY; if (own_transform_relation) { - relation.flag |= OBJECT_TRANSFORM; + id_relation |= OBJECT_TRANSFORM; r_needs_own_transform_relation = true; } - ids.add(relation); break; } case (GEO_NODE_SELF_OBJECT): { @@ -308,17 +275,16 @@ static void process_nodes_for_depsgraph(const bNodeTree &tree, } static void find_used_ids_from_settings(const NodesModifierSettings &settings, - Set &ids) + Map &ids) { IDP_foreach_property( settings.properties, IDP_TYPE_FILTER_ID, [](IDProperty *property, void *user_data) { - Set *ids = (Set *)user_data; + Map *ids = (Map *)user_data; ID *id = IDP_Id(property); if (id != nullptr) { - IDRelation relation{id, ALL}; - ids->add(relation); + ids->lookup_or_add_default(id) = ALL; } }, &ids); @@ -372,31 +338,30 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte DEG_add_node_tree_output_relation(ctx->node, nmd->node_group, "Nodes Modifier"); bool needs_own_transform_relation = false; - Set used_ids; + Map used_ids; find_used_ids_from_settings(nmd->settings, used_ids); process_nodes_for_depsgraph(*nmd->node_group, used_ids, needs_own_transform_relation); if (ctx->object->type == OB_CURVES) { Curves *curves_id = static_cast(ctx->object->data); if (curves_id->surface != nullptr) { - IDRelation relation{&curves_id->surface->id, CURVES}; - used_ids.add(relation); + used_ids.lookup_or_add_default(&curves_id->surface->id) = CURVES; } } - for (const IDRelation &id_relation : used_ids) { - switch ((ID_Type)GS(id_relation.id->name)) { + for (const auto [id, relation] : used_ids.items()) { + switch ((ID_Type)GS(id.id->name)) { case ID_OB: { - add_object_relation(ctx, id_relation); + add_object_relation(ctx, id); break; } case ID_GR: { - add_collection_relation(ctx, id_relation); + add_collection_relation(ctx, id); break; } case ID_IM: case ID_TE: { - DEG_add_generic_id_relation(ctx->node, id_relation.id, "Nodes Modifier"); + DEG_add_generic_id_relation(ctx->node, id.id, "Nodes Modifier"); break; } default: { -- 2.30.2