Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_nodes.cc
| Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "BKE_customdata.h" | #include "BKE_customdata.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_idprop.h" | #include "BKE_idprop.h" | ||||
| #include "BKE_lib_query.h" | #include "BKE_lib_query.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_node_ui_storage.hh" | |||||
| #include "BKE_pointcloud.h" | #include "BKE_pointcloud.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_simulation.h" | #include "BKE_simulation.h" | ||||
| #include "BLO_read_write.h" | #include "BLO_read_write.h" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| ▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | if (nmd->node_group == nullptr) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| class GeometryNodesEvaluator { | class GeometryNodesEvaluator { | ||||
| private: | private: | ||||
| blender::LinearAllocator<> allocator_; | blender::LinearAllocator<> allocator_; | ||||
JacquesLucke: Should be `btree_orig_` or `btree_cow_`. | |||||
| Map<std::pair<const DInputSocket *, const DOutputSocket *>, GMutablePointer> value_by_input_; | Map<std::pair<const DInputSocket *, const DOutputSocket *>, GMutablePointer> value_by_input_; | ||||
| Vector<const DInputSocket *> group_outputs_; | Vector<const DInputSocket *> group_outputs_; | ||||
| blender::nodes::MultiFunctionByNode &mf_by_node_; | blender::nodes::MultiFunctionByNode &mf_by_node_; | ||||
| const blender::nodes::DataTypeConversions &conversions_; | const blender::nodes::DataTypeConversions &conversions_; | ||||
| const PersistentDataHandleMap &handle_map_; | const PersistentDataHandleMap &handle_map_; | ||||
| const Object *self_object_; | const Object *self_object_; | ||||
| const ModifierData *modifier_; | |||||
| Depsgraph *depsgraph_; | Depsgraph *depsgraph_; | ||||
| public: | public: | ||||
| GeometryNodesEvaluator(const Map<const DOutputSocket *, GMutablePointer> &group_input_data, | GeometryNodesEvaluator(const Map<const DOutputSocket *, GMutablePointer> &group_input_data, | ||||
| Vector<const DInputSocket *> group_outputs, | Vector<const DInputSocket *> group_outputs, | ||||
| blender::nodes::MultiFunctionByNode &mf_by_node, | blender::nodes::MultiFunctionByNode &mf_by_node, | ||||
| const PersistentDataHandleMap &handle_map, | const PersistentDataHandleMap &handle_map, | ||||
| const Object *self_object, | const Object *self_object, | ||||
| const ModifierData *modifier, | |||||
| Depsgraph *depsgraph) | Depsgraph *depsgraph) | ||||
| : group_outputs_(std::move(group_outputs)), | : group_outputs_(std::move(group_outputs)), | ||||
| mf_by_node_(mf_by_node), | mf_by_node_(mf_by_node), | ||||
| conversions_(blender::nodes::get_implicit_type_conversions()), | conversions_(blender::nodes::get_implicit_type_conversions()), | ||||
| handle_map_(handle_map), | handle_map_(handle_map), | ||||
| self_object_(self_object), | self_object_(self_object), | ||||
| modifier_(modifier), | |||||
| depsgraph_(depsgraph) | depsgraph_(depsgraph) | ||||
| { | { | ||||
| for (auto item : group_input_data.items()) { | for (auto item : group_input_data.items()) { | ||||
| this->forward_to_inputs(*item.key, item.value); | this->forward_to_inputs(*item.key, item.value); | ||||
| } | } | ||||
| } | } | ||||
| Vector<GMutablePointer> execute() | Vector<GMutablePointer> execute() | ||||
| ▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | for (const DInputSocket *input_socket : node.inputs()) { | ||||
| node_inputs_map.add_new_direct(key, std::move(values[i])); | node_inputs_map.add_new_direct(key, std::move(values[i])); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Execute the node. */ | /* Execute the node. */ | ||||
| GValueMap<StringRef> node_outputs_map{allocator_}; | GValueMap<StringRef> node_outputs_map{allocator_}; | ||||
| GeoNodeExecParams params{ | GeoNodeExecParams params{ | ||||
| node, node_inputs_map, node_outputs_map, handle_map_, self_object_, depsgraph_}; | node, node_inputs_map, node_outputs_map, handle_map_, self_object_, modifier_, depsgraph_}; | ||||
| this->execute_node(node, params); | this->execute_node(node, params); | ||||
| /* Forward computed outputs to linked input sockets. */ | /* Forward computed outputs to linked input sockets. */ | ||||
| for (const DOutputSocket *output_socket : node.outputs()) { | for (const DOutputSocket *output_socket : node.outputs()) { | ||||
| if (output_socket->is_available()) { | if (output_socket->is_available()) { | ||||
| GMutablePointer value = node_outputs_map.extract(output_socket->identifier()); | GMutablePointer value = node_outputs_map.extract(output_socket->identifier()); | ||||
| this->forward_to_inputs(*output_socket, value); | this->forward_to_inputs(*output_socket, value); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 570 Lines • ▼ Show 20 Lines | static void fill_data_handle_map(const NodesModifierSettings &settings, | ||||
| int current_handle = 0; | int current_handle = 0; | ||||
| for (ID *id : used_ids) { | for (ID *id : used_ids) { | ||||
| handle_map.add(current_handle, *id); | handle_map.add(current_handle, *id); | ||||
| current_handle++; | current_handle++; | ||||
| } | } | ||||
| } | } | ||||
| static void reset_tree_ui_storage(Span<const blender::nodes::NodeTreeRef *> trees, | |||||
| const Object &object, | |||||
| const ModifierData &modifier) | |||||
| { | |||||
| const NodeTreeEvaluationContext context = {object, modifier}; | |||||
| for (const blender::nodes::NodeTreeRef *tree : trees) { | |||||
| bNodeTree *btree_cow = tree->btree(); | |||||
| bNodeTree *btree_original = (bNodeTree *)DEG_get_original_id((ID *)btree_cow); | |||||
| BKE_nodetree_ui_storage_free_for_context(*btree_original, context); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Evaluate a node group to compute the output geometry. | * Evaluate a node group to compute the output geometry. | ||||
| * Currently, this uses a fairly basic and inefficient algorithm that might compute things more | * Currently, this uses a fairly basic and inefficient algorithm that might compute things more | ||||
| * often than necessary. It's going to be replaced soon. | * often than necessary. It's going to be replaced soon. | ||||
| */ | */ | ||||
| static GeometrySet compute_geometry(const DerivedNodeTree &tree, | static GeometrySet compute_geometry(const DerivedNodeTree &tree, | ||||
| Span<const DOutputSocket *> group_input_sockets, | Span<const DOutputSocket *> group_input_sockets, | ||||
| const DInputSocket &socket_to_compute, | const DInputSocket &socket_to_compute, | ||||
| Show All 30 Lines | for (const DOutputSocket *socket : remaining_input_sockets) { | ||||
| initialize_group_input(*nmd, handle_map, *socket->bsocket(), cpp_type, value_in); | initialize_group_input(*nmd, handle_map, *socket->bsocket(), cpp_type, value_in); | ||||
| group_inputs.add_new(socket, {cpp_type, value_in}); | group_inputs.add_new(socket, {cpp_type, value_in}); | ||||
| } | } | ||||
| } | } | ||||
| Vector<const DInputSocket *> group_outputs; | Vector<const DInputSocket *> group_outputs; | ||||
| group_outputs.append(&socket_to_compute); | group_outputs.append(&socket_to_compute); | ||||
| GeometryNodesEvaluator evaluator{ | GeometryNodesEvaluator evaluator{group_inputs, | ||||
| group_inputs, group_outputs, mf_by_node, handle_map, ctx->object, ctx->depsgraph}; | group_outputs, | ||||
| mf_by_node, | |||||
| handle_map, | |||||
| ctx->object, | |||||
| (ModifierData *)nmd, | |||||
| ctx->depsgraph}; | |||||
| Vector<GMutablePointer> results = evaluator.execute(); | Vector<GMutablePointer> results = evaluator.execute(); | ||||
| BLI_assert(results.size() == 1); | BLI_assert(results.size() == 1); | ||||
| GMutablePointer result = results[0]; | GMutablePointer result = results[0]; | ||||
| GeometrySet output_geometry = std::move(*(GeometrySet *)result.get()); | GeometrySet output_geometry = std::move(*(GeometrySet *)result.get()); | ||||
| return output_geometry; | return output_geometry; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | if (group_outputs.size() == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| const DInputSocket *group_output = group_outputs[0]; | const DInputSocket *group_output = group_outputs[0]; | ||||
| if (group_output->idname() != "NodeSocketGeometry") { | if (group_output->idname() != "NodeSocketGeometry") { | ||||
| return; | return; | ||||
| } | } | ||||
| reset_tree_ui_storage(tree.used_node_tree_refs(), *ctx->object, *md); | |||||
| geometry_set = compute_geometry( | geometry_set = compute_geometry( | ||||
| tree, group_inputs, *group_outputs[0], std::move(geometry_set), nmd, ctx); | tree, group_inputs, *group_outputs[0], std::move(geometry_set), nmd, ctx); | ||||
| } | } | ||||
| static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) | static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) | ||||
| { | { | ||||
| GeometrySet geometry_set = GeometrySet::create_with_mesh(mesh, GeometryOwnershipType::Editable); | GeometrySet geometry_set = GeometrySet::create_with_mesh(mesh, GeometryOwnershipType::Editable); | ||||
| geometry_set.get_component_for_write<MeshComponent>().copy_vertex_group_names_from_object( | geometry_set.get_component_for_write<MeshComponent>().copy_vertex_group_names_from_object( | ||||
| ▲ Show 20 Lines • Show All 191 Lines • Show Last 20 Lines | |||||
Should be btree_orig_ or btree_cow_.