Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| #include "GEO_realize_instances.hh" | #include "GEO_realize_instances.hh" | ||||
| #include "BKE_instances.hh" | #include "BKE_instances.hh" | ||||
| #include "node_geometry_util.hh" | #include "node_geometry_util.hh" | ||||
| namespace blender::nodes::node_geo_join_geometry_cc { | namespace blender::nodes::node_geo_join_geometry_cc { | ||||
| static void node_declare(NodeDeclarationBuilder &b) | static void node_declare(NodeDeclarationBuilder &b) | ||||
| { | { | ||||
| b.add_input<decl::Geometry>(N_("Geometry")).multi_input(); | b.add_input<decl::Geometry>(N_("Geometry")).multi_input(); | ||||
| b.add_output<decl::Geometry>(N_("Geometry")); | b.add_output<decl::Geometry>(N_("Geometry")).propagate_from_auto(); | ||||
| } | } | ||||
| template<typename Component> | template<typename Component> | ||||
| static Array<const GeometryComponent *> to_base_components(Span<const Component *> components) | static Array<const GeometryComponent *> to_base_components(Span<const Component *> components) | ||||
| { | { | ||||
| return components; | return components; | ||||
| } | } | ||||
| static Map<AttributeIDRef, AttributeMetaData> get_final_attribute_info( | static Map<AttributeIDRef, AttributeMetaData> get_final_attribute_info( | ||||
| Span<const GeometryComponent *> components, Span<StringRef> ignored_attributes) | Span<const GeometryComponent *> components, Span<StringRef> ignored_attributes) | ||||
| { | { | ||||
| Map<AttributeIDRef, AttributeMetaData> info; | Map<AttributeIDRef, AttributeMetaData> info; | ||||
| for (const GeometryComponent *component : components) { | for (const GeometryComponent *component : components) { | ||||
| component->attributes()->for_all( | component->attributes()->for_all( | ||||
| [&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) { | [&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) { | ||||
| if (attribute_id.is_named() && ignored_attributes.contains(attribute_id.name())) { | if (ignored_attributes.contains(attribute_id.name())) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (meta_data.data_type == CD_PROP_STRING) { | if (meta_data.data_type == CD_PROP_STRING) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| info.add_or_modify( | info.add_or_modify( | ||||
| attribute_id, | attribute_id, | ||||
| [&](AttributeMetaData *meta_data_final) { *meta_data_final = meta_data; }, | [&](AttributeMetaData *meta_data_final) { *meta_data_final = meta_data; }, | ||||
| ▲ Show 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | |||||
| static void join_components(Span<const VolumeComponent *> /*src_components*/, | static void join_components(Span<const VolumeComponent *> /*src_components*/, | ||||
| GeometrySet & /*result*/) | GeometrySet & /*result*/) | ||||
| { | { | ||||
| /* Not yet supported. Joining volume grids with the same name requires resampling of at least one | /* Not yet supported. Joining volume grids with the same name requires resampling of at least one | ||||
| * of the grids. The cell size of the resulting volume has to be determined somehow. */ | * of the grids. The cell size of the resulting volume has to be determined somehow. */ | ||||
| } | } | ||||
| template<typename Component> | template<typename Component> | ||||
| static void join_component_type(Span<GeometrySet> src_geometry_sets, GeometrySet &result) | static void join_component_type(Span<GeometrySet> src_geometry_sets, | ||||
| GeometrySet &result, | |||||
| const AnonymousAttributePropagationInfo &propagation_info) | |||||
| { | { | ||||
| Vector<const Component *> components; | Vector<const Component *> components; | ||||
| for (const GeometrySet &geometry_set : src_geometry_sets) { | for (const GeometrySet &geometry_set : src_geometry_sets) { | ||||
| const Component *component = geometry_set.get_component_for_read<Component>(); | const Component *component = geometry_set.get_component_for_read<Component>(); | ||||
| if (component != nullptr && !component->is_empty()) { | if (component != nullptr && !component->is_empty()) { | ||||
| components.append(component); | components.append(component); | ||||
| } | } | ||||
| } | } | ||||
| Show All 16 Lines | for (const Component *component : components) { | ||||
| tmp_geo.add(*component); | tmp_geo.add(*component); | ||||
| const int handle = instances->add_reference(bke::InstanceReference{tmp_geo}); | const int handle = instances->add_reference(bke::InstanceReference{tmp_geo}); | ||||
| instances->add_instance(handle, float4x4::identity()); | instances->add_instance(handle, float4x4::identity()); | ||||
| } | } | ||||
| geometry::RealizeInstancesOptions options; | geometry::RealizeInstancesOptions options; | ||||
| options.keep_original_ids = true; | options.keep_original_ids = true; | ||||
| options.realize_instance_attributes = false; | options.realize_instance_attributes = false; | ||||
| options.propagation_info = propagation_info; | |||||
| GeometrySet joined_components = geometry::realize_instances( | GeometrySet joined_components = geometry::realize_instances( | ||||
| GeometrySet::create_with_instances(instances.release()), options); | GeometrySet::create_with_instances(instances.release()), options); | ||||
| result.add(joined_components.get_component_for_write<Component>()); | result.add(joined_components.get_component_for_write<Component>()); | ||||
| } | } | ||||
| } | } | ||||
| static void node_geo_exec(GeoNodeExecParams params) | static void node_geo_exec(GeoNodeExecParams params) | ||||
| { | { | ||||
| Vector<GeometrySet> geometry_sets = params.extract_input<Vector<GeometrySet>>("Geometry"); | Vector<GeometrySet> geometry_sets = params.extract_input<Vector<GeometrySet>>("Geometry"); | ||||
| const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( | |||||
| "Geometry"); | |||||
| GeometrySet geometry_set_result; | GeometrySet geometry_set_result; | ||||
| join_component_type<MeshComponent>(geometry_sets, geometry_set_result); | join_component_type<MeshComponent>(geometry_sets, geometry_set_result, propagation_info); | ||||
| join_component_type<PointCloudComponent>(geometry_sets, geometry_set_result); | join_component_type<PointCloudComponent>(geometry_sets, geometry_set_result, propagation_info); | ||||
| join_component_type<InstancesComponent>(geometry_sets, geometry_set_result); | join_component_type<InstancesComponent>(geometry_sets, geometry_set_result, propagation_info); | ||||
| join_component_type<VolumeComponent>(geometry_sets, geometry_set_result); | join_component_type<VolumeComponent>(geometry_sets, geometry_set_result, propagation_info); | ||||
| join_component_type<CurveComponent>(geometry_sets, geometry_set_result); | join_component_type<CurveComponent>(geometry_sets, geometry_set_result, propagation_info); | ||||
| join_component_type<GeometryComponentEditData>(geometry_sets, geometry_set_result); | join_component_type<GeometryComponentEditData>( | ||||
| geometry_sets, geometry_set_result, propagation_info); | |||||
| params.set_output("Geometry", std::move(geometry_set_result)); | params.set_output("Geometry", std::move(geometry_set_result)); | ||||
| } | } | ||||
| } // namespace blender::nodes::node_geo_join_geometry_cc | } // namespace blender::nodes::node_geo_join_geometry_cc | ||||
| void register_node_type_geo_join_geometry() | void register_node_type_geo_join_geometry() | ||||
| { | { | ||||
| namespace file_ns = blender::nodes::node_geo_join_geometry_cc; | namespace file_ns = blender::nodes::node_geo_join_geometry_cc; | ||||
| static bNodeType ntype; | static bNodeType ntype; | ||||
| geo_node_type_base(&ntype, GEO_NODE_JOIN_GEOMETRY, "Join Geometry", NODE_CLASS_GEOMETRY); | geo_node_type_base(&ntype, GEO_NODE_JOIN_GEOMETRY, "Join Geometry", NODE_CLASS_GEOMETRY); | ||||
| ntype.geometry_node_execute = file_ns::node_geo_exec; | ntype.geometry_node_execute = file_ns::node_geo_exec; | ||||
| ntype.declare = file_ns::node_declare; | ntype.declare = file_ns::node_declare; | ||||
| nodeRegisterType(&ntype); | nodeRegisterType(&ntype); | ||||
| } | } | ||||