diff options
Diffstat (limited to 'source/blender')
6 files changed, 77 insertions, 55 deletions
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<GeometryInstanceGroup> &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 &>(object), + false); + + if (mesh != nullptr) { + BKE_mesh_wrapper_ensure_mdata(mesh); + + MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); + 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 &>(object), false); - - if (mesh != nullptr) { - BKE_mesh_wrapper_ensure_mdata(mesh); - - MeshComponent &mesh_component = new_geometry_set.get_component_for_write<MeshComponent>(); - 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( 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; } 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 diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 4a384063571..3481b1c75d9 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); } } } @@ -454,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); @@ -475,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<GeometrySet>(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) @@ -1231,6 +1200,37 @@ static void log_preview_socket_value(const Span<GPointer> values, } } +static void log_ui_hints(const DSocket socket, + const Span<GPointer> 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<GeometrySet>()) { + 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 @@ -1297,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, 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); } 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<GeometryNodePointDistributeMode>(params.node().custom1); - const int seed = params.get_input<int>("Seed"); + const int seed = params.get_input<int>("Seed") * 5383843; const float density = params.extract_input<float>("Density Max"); const std::string density_attribute_name = params.extract_input<std::string>( "Density Attribute"); |