Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/intern/geometry_nodes_lazy_function.cc
| Show First 20 Lines • Show All 537 Lines • ▼ Show 20 Lines | void execute_impl(lf::Params ¶ms, const lf::Context &context) const override | ||||
| if (user_data->modifier_data == nullptr) { | if (user_data->modifier_data == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (user_data->modifier_data->eval_log == nullptr) { | if (user_data->modifier_data->eval_log == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| GeometrySet geometry = params.extract_input<GeometrySet>(0); | GeometrySet geometry = params.extract_input<GeometrySet>(0); | ||||
| const NodeGeometryViewer *storage = static_cast<NodeGeometryViewer *>(bnode_.storage); | |||||
| GField field; | |||||
| if (use_field_input_) { | if (use_field_input_) { | ||||
| const void *value_or_field = params.try_get_input_data_ptr(1); | const void *value_or_field = params.try_get_input_data_ptr(1); | ||||
| BLI_assert(value_or_field != nullptr); | BLI_assert(value_or_field != nullptr); | ||||
| const ValueOrFieldCPPType &value_or_field_type = static_cast<const ValueOrFieldCPPType &>( | const ValueOrFieldCPPType &value_or_field_type = static_cast<const ValueOrFieldCPPType &>( | ||||
| *inputs_[1].type); | *inputs_[1].type); | ||||
| field = value_or_field_type.as_field(value_or_field); | GField field = value_or_field_type.as_field(value_or_field); | ||||
| const eAttrDomain domain = eAttrDomain(storage->domain); | |||||
| const StringRefNull viewer_attribute_name = ".viewer"; | |||||
| if (domain == ATTR_DOMAIN_INSTANCE) { | |||||
| if (geometry.has_instances()) { | |||||
| GeometryComponent &component = geometry.get_component_for_write( | |||||
| GEO_COMPONENT_TYPE_INSTANCES); | |||||
| bke::try_capture_field_on_geometry( | |||||
| component, viewer_attribute_name, ATTR_DOMAIN_INSTANCE, field); | |||||
| } | |||||
| } | |||||
| else { | |||||
| geometry.modify_geometry_sets([&](GeometrySet &geometry) { | |||||
| for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH, | |||||
| GEO_COMPONENT_TYPE_POINT_CLOUD, | |||||
| GEO_COMPONENT_TYPE_CURVE}) { | |||||
| if (geometry.has(type)) { | |||||
| GeometryComponent &component = geometry.get_component_for_write(type); | |||||
| eAttrDomain used_domain = domain; | |||||
| if (used_domain == ATTR_DOMAIN_AUTO) { | |||||
| if (const std::optional<eAttrDomain> detected_domain = | |||||
| bke::try_detect_field_domain(component, field)) { | |||||
| used_domain = *detected_domain; | |||||
| } | |||||
| else { | |||||
| used_domain = type == GEO_COMPONENT_TYPE_MESH ? ATTR_DOMAIN_CORNER : | |||||
| ATTR_DOMAIN_POINT; | |||||
| } | |||||
| } | |||||
| bke::try_capture_field_on_geometry( | |||||
| component, viewer_attribute_name, used_domain, field); | |||||
| } | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | } | ||||
| geo_eval_log::GeoTreeLogger &tree_logger = | geo_eval_log::GeoTreeLogger &tree_logger = | ||||
| user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context); | user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context); | ||||
| tree_logger.log_viewer_node(bnode_, geometry, field); | tree_logger.log_viewer_node(bnode_, std::move(geometry)); | ||||
| } | } | ||||
| }; | }; | ||||
| /** | /** | ||||
| * This lazy-function wraps a group node. Internally it just executes the lazy-function graph of | * This lazy-function wraps a group node. Internally it just executes the lazy-function graph of | ||||
| * the referenced group. | * the referenced group. | ||||
| */ | */ | ||||
| class LazyFunctionForGroupNode : public LazyFunction { | class LazyFunctionForGroupNode : public LazyFunction { | ||||
| ▲ Show 20 Lines • Show All 465 Lines • ▼ Show 20 Lines | private: | ||||
| { | { | ||||
| for (const auto item : output_socket_map_.items()) { | for (const auto item : output_socket_map_.items()) { | ||||
| this->insert_links_from_socket(*item.key, *item.value); | this->insert_links_from_socket(*item.key, *item.value); | ||||
| } | } | ||||
| } | } | ||||
| void insert_links_from_socket(const bNodeSocket &from_bsocket, lf::OutputSocket &from_lf_socket) | void insert_links_from_socket(const bNodeSocket &from_bsocket, lf::OutputSocket &from_lf_socket) | ||||
| { | { | ||||
| const bNode &from_bnode = from_bsocket.owner_node(); | |||||
| if (this->is_dangling_reroute_input(from_bnode)) { | |||||
| /* Dangling reroutes should not be used as source of values. */ | |||||
| return; | |||||
| } | |||||
| const Span<const bNodeLink *> links_from_bsocket = from_bsocket.directly_linked_links(); | const Span<const bNodeLink *> links_from_bsocket = from_bsocket.directly_linked_links(); | ||||
| struct TypeWithLinks { | struct TypeWithLinks { | ||||
| const CPPType *type; | const CPPType *type; | ||||
| Vector<const bNodeLink *> links; | Vector<const bNodeLink *> links; | ||||
| }; | }; | ||||
| /* Group available target sockets by type so that they can be handled together. */ | /* Group available target sockets by type so that they can be handled together. */ | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | for (const TypeWithLinks &type_with_links : types_with_links) { | ||||
| for (lf::InputSocket *to_lf_socket : input_socket_map_.lookup(&to_bsocket)) { | for (lf::InputSocket *to_lf_socket : input_socket_map_.lookup(&to_bsocket)) { | ||||
| make_input_link_or_set_default(*to_lf_socket); | make_input_link_or_set_default(*to_lf_socket); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| bool is_dangling_reroute_input(const bNode &node) | |||||
| { | |||||
| if (!node.is_reroute()) { | |||||
| return false; | |||||
| } | |||||
| const bNode *iter_node = &node; | |||||
| /* It is guaranteed at a higher level that there are no link cycles. */ | |||||
| while (true) { | |||||
| const Span<const bNodeLink *> links = iter_node->input_socket(0).directly_linked_links(); | |||||
| BLI_assert(links.size() <= 1); | |||||
| if (links.is_empty()) { | |||||
| return true; | |||||
| } | |||||
| const bNodeLink &link = *links[0]; | |||||
| if (!link.is_available()) { | |||||
| return false; | |||||
| } | |||||
| if (link.is_muted()) { | |||||
| return false; | |||||
| } | |||||
| iter_node = link.fromnode; | |||||
| if (!iter_node->is_reroute()) { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| } | |||||
| lf::OutputSocket *insert_type_conversion_if_necessary( | lf::OutputSocket *insert_type_conversion_if_necessary( | ||||
| lf::OutputSocket &from_socket, | lf::OutputSocket &from_socket, | ||||
| const CPPType &to_type, | const CPPType &to_type, | ||||
| Vector<const bNodeSocket *> &&target_sockets) | Vector<const bNodeSocket *> &&target_sockets) | ||||
| { | { | ||||
| const CPPType &from_type = from_socket.type(); | const CPPType &from_type = from_socket.type(); | ||||
| if (from_type == to_type) { | if (from_type == to_type) { | ||||
| return &from_socket; | return &from_socket; | ||||
| ▲ Show 20 Lines • Show All 244 Lines • Show Last 20 Lines | |||||