From 382b06c80cacb0ee940f2783f4619580b04aa502 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Apr 2021 11:23:28 +0200 Subject: Fix T85691: attributes used by geometry nodes were removed automatically This has technically been fixed by rB3e87d8a4315d794efff659e40f0bb9e34e2aec8a, but the fix there is questionable, because it disables an optimization for vertex groups entirely. This fix is a little bit more precise in that it only disables the optimization when the object is used by some geometry nodes modifier. --- source/blender/modifiers/intern/MOD_nodes.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source') diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 4a384063571..02a1dc07c93 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -179,6 +179,14 @@ static void add_object_relation(const ModifierUpdateDepsgraphContext *ctx, Objec } else if (ELEM(object.type, OB_MESH, OB_POINTCLOUD, OB_VOLUME)) { DEG_add_object_relation(ctx->node, &object, DEG_OB_COMP_GEOMETRY, "Nodes Modifier"); + /* We don't know exactly what attributes from the other object we will need. */ + CustomData_MeshMasks mask; + mask.vmask = CD_MASK_PROP_ALL | CD_MASK_MDEFORMVERT; + mask.pmask = CD_MASK_PROP_ALL; + mask.lmask = CD_MASK_PROP_ALL; + mask.fmask = CD_MASK_PROP_ALL; + mask.emask = CD_MASK_PROP_ALL; + DEG_add_customdata_mask(ctx->node, &object, &mask); } } } -- cgit v1.2.3 From a2e4d81849d038fcfda9552479c9ce02b9aaf644 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Apr 2021 11:28:23 +0200 Subject: Fix T87441: don't remove custom attributes automatically In the past, custom attributes were rarely used in practice, because the only way to use them was from Python. Since geometry nodes, more users started to add their own attributes. Those attributes should not be removed automatically. It is still possible to remove them in geometry nodes explictly to improve performance. --- source/blender/blenkernel/intern/object_update.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source') diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index b1ae4abd9bb..e6909127503 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -176,6 +176,13 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o CustomData_MeshMasks cddata_masks = scene->customdata_mask; CustomData_MeshMasks_update(&cddata_masks, &CD_MASK_BAREMESH); + /* Custom attributes should not be removed automatically. They might be used by the render + * engine or scripts. They can still be removed explicitly using geometry nodes. */ + cddata_masks.vmask |= CD_MASK_PROP_ALL; + cddata_masks.emask |= CD_MASK_PROP_ALL; + cddata_masks.fmask |= CD_MASK_PROP_ALL; + cddata_masks.pmask |= CD_MASK_PROP_ALL; + cddata_masks.lmask |= CD_MASK_PROP_ALL; /* Make sure Freestyle edge/face marks appear in DM for render (see T40315). * Due to Line Art implementation, edge marks should also be shown in viewport. */ #ifdef WITH_FREESTYLE -- cgit v1.2.3 From 58818cba40794905f9323080e60884e090f2d388 Mon Sep 17 00:00:00 2001 From: Wannes Malfait Date: Fri, 16 Apr 2021 11:37:49 +0200 Subject: Fix T87359: set group output in geometry node tree update callback This also fixes T85511. Differential Revision: https://developer.blender.org/D10970 --- source/blender/nodes/geometry/node_geometry_tree.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source') diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc index 2c4c7da64cc..6d3b1d55005 100644 --- a/source/blender/nodes/geometry/node_geometry_tree.cc +++ b/source/blender/nodes/geometry/node_geometry_tree.cc @@ -67,6 +67,8 @@ static void geometry_node_tree_get_from_context(const bContext *C, static void geometry_node_tree_update(bNodeTree *ntree) { + ntreeSetOutput(ntree); + /* Needed to give correct types to reroutes. */ ntree_update_reroute_nodes(ntree); } -- cgit v1.2.3 From ca37d8485c73ebc050e49c6bce2f73756c7578e3 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Apr 2021 11:43:16 +0200 Subject: Fix T87217: improve impact of seed in point distribute node Incrementing the seed just by one did not mix things up enough. --- source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc index 026455cbc95..74cca8a2f3c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc @@ -622,7 +622,7 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params) const GeometryNodePointDistributeMode distribute_method = static_cast(params.node().custom1); - const int seed = params.get_input("Seed"); + const int seed = params.get_input("Seed") * 5383843; const float density = params.extract_input("Density Max"); const std::string density_attribute_name = params.extract_input( "Density Attribute"); -- cgit v1.2.3 From 4bef49e32b6d4d9df496b2b54a78b66b11df7334 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Apr 2021 11:56:04 +0200 Subject: Fix T87169: support attribute search on group nodes --- source/blender/modifiers/intern/MOD_nodes.cc | 71 +++++++++++++--------------- 1 file changed, 32 insertions(+), 39 deletions(-) (limited to 'source') diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 02a1dc07c93..3481b1c75d9 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -462,10 +462,6 @@ class GeometryNodesEvaluator { { const bNode &bnode = params.node(); - if (DEG_is_active(depsgraph_)) { - this->store_ui_hints(node, params); - } - /* Use the geometry-node-execute callback if it exists. */ if (bnode.typeinfo->geometry_node_execute != nullptr) { bnode.typeinfo->geometry_node_execute(params); @@ -483,41 +479,6 @@ class GeometryNodesEvaluator { this->execute_unknown_node(node, params); } - void store_ui_hints(const DNode node, GeoNodeExecParams params) const - { - for (const InputSocketRef *socket_ref : node->inputs()) { - if (!socket_ref->is_available()) { - continue; - } - if (socket_ref->bsocket()->type != SOCK_GEOMETRY) { - continue; - } - if (socket_ref->is_multi_input_socket()) { - /* Not needed currently. */ - continue; - } - - bNodeTree *btree_cow = node->btree(); - bNodeTree *btree_original = (bNodeTree *)DEG_get_original_id((ID *)btree_cow); - const NodeTreeEvaluationContext context(*self_object_, *modifier_); - - const GeometrySet &geometry_set = params.get_input(socket_ref->identifier()); - - blender::bke::geometry_set_instances_attribute_foreach( - geometry_set, - [&](StringRefNull attribute_name, const AttributeMetaData &meta_data) { - BKE_nodetree_attribute_hint_add(*btree_original, - context, - *node->bnode(), - attribute_name, - meta_data.domain, - meta_data.data_type); - return true; - }, - 8); - } - } - void execute_multi_function_node(const DNode node, GeoNodeExecParams params, const MultiFunction &fn) @@ -1239,6 +1200,37 @@ static void log_preview_socket_value(const Span values, } } +static void log_ui_hints(const DSocket socket, + const Span values, + Object *self_object, + NodesModifierData *nmd) +{ + const DNode node = socket.node(); + if (node->is_reroute_node() || socket->typeinfo()->type != SOCK_GEOMETRY) { + return; + } + bNodeTree *btree_cow = node->btree(); + bNodeTree *btree_original = (bNodeTree *)DEG_get_original_id((ID *)btree_cow); + const NodeTreeEvaluationContext context{*self_object, nmd->modifier}; + for (const GPointer data : values) { + if (data.type() == &CPPType::get()) { + const GeometrySet &geometry_set = *(const GeometrySet *)data.get(); + blender::bke::geometry_set_instances_attribute_foreach( + geometry_set, + [&](StringRefNull attribute_name, const AttributeMetaData &meta_data) { + BKE_nodetree_attribute_hint_add(*btree_original, + context, + *node->bnode(), + attribute_name, + meta_data.domain, + meta_data.data_type); + return true; + }, + 8); + } + } +} + /** * Evaluate a node group to compute the output geometry. * Currently, this uses a fairly basic and inefficient algorithm that might compute things more @@ -1305,6 +1297,7 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree, if (!keys.is_empty()) { log_preview_socket_value(values, ctx->object, keys); } + log_ui_hints(socket, values, ctx->object, nmd); }; GeometryNodesEvaluator evaluator{group_inputs, -- cgit v1.2.3 From 1266df87c86067d7c2d18ef71dd0e5520de1a382 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Apr 2021 13:05:32 +0200 Subject: Fix unreported: instances disappear when instanced mesh is in edit mode The issue is that for historic reasons, `geometry_set_eval` does not contain the mesh component when the object is in edit mode. --- .../blenkernel/intern/geometry_set_instances.cc | 40 ++++++++++++++-------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc index baeed4fc3bc..07d0e520c93 100644 --- a/source/blender/blenkernel/intern/geometry_set_instances.cc +++ b/source/blender/blenkernel/intern/geometry_set_instances.cc @@ -36,30 +36,42 @@ static void geometry_set_collect_recursive_collection(const Collection &collecti const float4x4 &transform, Vector &r_sets); +static void add_final_mesh_as_geometry_component(const Object &object, GeometrySet &geometry_set) +{ + Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(&const_cast(object), + false); + + if (mesh != nullptr) { + BKE_mesh_wrapper_ensure_mdata(mesh); + + MeshComponent &mesh_component = geometry_set.get_component_for_write(); + mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly); + mesh_component.copy_vertex_group_names_from_object(object); + } +} + /** * \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances. */ static GeometrySet object_get_geometry_set_for_read(const Object &object) { - /* Objects evaluated with a nodes modifier will have a geometry set already. */ + if (object.type == OB_MESH && object.mode == OB_MODE_EDIT) { + GeometrySet geometry_set; + if (object.runtime.geometry_set_eval != nullptr) { + /* `geometry_set_eval` only contains non-mesh components, see `editbmesh_build_data`. */ + geometry_set = *object.runtime.geometry_set_eval; + } + add_final_mesh_as_geometry_component(object, geometry_set); + return geometry_set; + } if (object.runtime.geometry_set_eval != nullptr) { return *object.runtime.geometry_set_eval; } /* Otherwise, construct a new geometry set with the component based on the object type. */ - GeometrySet new_geometry_set; - + GeometrySet geometry_set; if (object.type == OB_MESH) { - Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object( - &const_cast(object), false); - - if (mesh != nullptr) { - BKE_mesh_wrapper_ensure_mdata(mesh); - - MeshComponent &mesh_component = new_geometry_set.get_component_for_write(); - mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly); - mesh_component.copy_vertex_group_names_from_object(object); - } + add_final_mesh_as_geometry_component(object, geometry_set); } /* TODO: Cover the case of point-clouds without modifiers-- they may not be covered by the @@ -68,7 +80,7 @@ static GeometrySet object_get_geometry_set_for_read(const Object &object) /* TODO: Add volume support. */ /* Return by value since there is not always an existing geometry set owned elsewhere to use. */ - return new_geometry_set; + return geometry_set; } static void geometry_set_collect_recursive_collection_instance( -- cgit v1.2.3 From 68c4ba348213b66543cdcd21da755fefaf286ef2 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Apr 2021 13:43:29 +0200 Subject: Fix T87522: frame selected does not take instances into account `ob->runtime.geometry_set_eval` can contain instances as well. This only affected instances generated by geometry nodes. We should probably have a separate function that tells us if an object has instances or not.. --- source/blender/blenkernel/intern/object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 5eb935f4651..160fb93b835 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -4135,7 +4135,7 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph, const bool use_hidden) { bool ok = false; - if ((ob->transflag & OB_DUPLI) == 0) { + if ((ob->transflag & OB_DUPLI) == 0 && ob->runtime.geometry_set_eval == NULL) { return ok; } -- cgit v1.2.3