[Bf-blender-cvs] [506d6725247] master: Geometry Nodes: deduplicate join geometry code

Jacques Lucke noreply at git.blender.org
Wed Dec 1 17:57:23 CET 2021


Commit: 506d67252473f7402a936ad74edbf97d363eae26
Author: Jacques Lucke
Date:   Wed Dec 1 17:52:52 2021 +0100
Branches: master
https://developer.blender.org/rB506d67252473f7402a936ad74edbf97d363eae26

Geometry Nodes: deduplicate join geometry code

The Realize Instances and Join Geometry node can share most of their code.
Until now, both nodes had their own implementations though. This patch
removes the implementation in the Join Geometry node in favor of the more
general Realize Instances implementation.

This removes an optimization for avoiding spline copies. This can be brought
back later. The realize instances code has to be rewritten to support attribute
instances anyway.

Differential Revision: https://developer.blender.org/D13417

===================================================================

M	source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc

===================================================================

diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index 53f7d968644..82dd6e294e9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -35,111 +35,6 @@ static void node_declare(NodeDeclarationBuilder &b)
   b.add_output<decl::Geometry>(N_("Geometry"));
 }
 
-static Mesh *join_mesh_topology_and_builtin_attributes(Span<const MeshComponent *> src_components)
-{
-  int totverts = 0;
-  int totloops = 0;
-  int totedges = 0;
-  int totpolys = 0;
-
-  int64_t cd_dirty_vert = 0;
-  int64_t cd_dirty_poly = 0;
-  int64_t cd_dirty_edge = 0;
-  int64_t cd_dirty_loop = 0;
-
-  VectorSet<Material *> materials;
-
-  for (const MeshComponent *mesh_component : src_components) {
-    const Mesh *mesh = mesh_component->get_for_read();
-    totverts += mesh->totvert;
-    totloops += mesh->totloop;
-    totedges += mesh->totedge;
-    totpolys += mesh->totpoly;
-    cd_dirty_vert |= mesh->runtime.cd_dirty_vert;
-    cd_dirty_poly |= mesh->runtime.cd_dirty_poly;
-    cd_dirty_edge |= mesh->runtime.cd_dirty_edge;
-    cd_dirty_loop |= mesh->runtime.cd_dirty_loop;
-
-    for (const int slot_index : IndexRange(mesh->totcol)) {
-      Material *material = mesh->mat[slot_index];
-      materials.add(material);
-    }
-  }
-
-  const Mesh *first_input_mesh = src_components[0]->get_for_read();
-  Mesh *new_mesh = BKE_mesh_new_nomain(totverts, totedges, 0, totloops, totpolys);
-  BKE_mesh_copy_parameters_for_eval(new_mesh, first_input_mesh);
-
-  for (const int i : IndexRange(materials.size())) {
-    Material *material = materials[i];
-    BKE_id_material_eval_assign(&new_mesh->id, i + 1, material);
-  }
-
-  new_mesh->runtime.cd_dirty_vert = cd_dirty_vert;
-  new_mesh->runtime.cd_dirty_poly = cd_dirty_poly;
-  new_mesh->runtime.cd_dirty_edge = cd_dirty_edge;
-  new_mesh->runtime.cd_dirty_loop = cd_dirty_loop;
-
-  int vert_offset = 0;
-  int loop_offset = 0;
-  int edge_offset = 0;
-  int poly_offset = 0;
-  for (const MeshComponent *mesh_component : src_components) {
-    const Mesh *mesh = mesh_component->get_for_read();
-    if (mesh == nullptr) {
-      continue;
-    }
-
-    Array<int> material_index_map(mesh->totcol);
-    for (const int i : IndexRange(mesh->totcol)) {
-      Material *material = mesh->mat[i];
-      const int new_material_index = materials.index_of(material);
-      material_index_map[i] = new_material_index;
-    }
-
-    for (const int i : IndexRange(mesh->totvert)) {
-      const MVert &old_vert = mesh->mvert[i];
-      MVert &new_vert = new_mesh->mvert[vert_offset + i];
-      new_vert = old_vert;
-    }
-
-    for (const int i : IndexRange(mesh->totedge)) {
-      const MEdge &old_edge = mesh->medge[i];
-      MEdge &new_edge = new_mesh->medge[edge_offset + i];
-      new_edge = old_edge;
-      new_edge.v1 += vert_offset;
-      new_edge.v2 += vert_offset;
-    }
-    for (const int i : IndexRange(mesh->totloop)) {
-      const MLoop &old_loop = mesh->mloop[i];
-      MLoop &new_loop = new_mesh->mloop[loop_offset + i];
-      new_loop = old_loop;
-      new_loop.v += vert_offset;
-      new_loop.e += edge_offset;
-    }
-    for (const int i : IndexRange(mesh->totpoly)) {
-      const MPoly &old_poly = mesh->mpoly[i];
-      MPoly &new_poly = new_mesh->mpoly[poly_offset + i];
-      new_poly = old_poly;
-      new_poly.loopstart += loop_offset;
-      if (old_poly.mat_nr >= 0 && old_poly.mat_nr < mesh->totcol) {
-        new_poly.mat_nr = material_index_map[new_poly.mat_nr];
-      }
-      else {
-        /* The material index was invalid before. */
-        new_poly.mat_nr = 0;
-      }
-    }
-
-    vert_offset += mesh->totvert;
-    loop_offset += mesh->totloop;
-    edge_offset += mesh->totedge;
-    poly_offset += mesh->totpoly;
-  }
-
-  return new_mesh;
-}
-
 template<typename Component>
 static Array<const GeometryComponent *> to_base_components(Span<const Component *> components)
 {
@@ -223,33 +118,6 @@ static void join_attributes(Span<const GeometryComponent *> src_components,
   }
 }
 
-static void join_components(Span<const MeshComponent *> src_components, GeometrySet &result)
-{
-  Mesh *new_mesh = join_mesh_topology_and_builtin_attributes(src_components);
-
-  MeshComponent &dst_component = result.get_component_for_write<MeshComponent>();
-  dst_component.replace(new_mesh);
-
-  /* Don't copy attributes that are stored directly in the mesh data structs. */
-  join_attributes(to_base_components(src_components),
-                  dst_component,
-                  {"position", "material_index", "normal", "shade_smooth", "crease"});
-}
-
-static void join_components(Span<const PointCloudComponent *> src_components, GeometrySet &result)
-{
-  int totpoints = 0;
-  for (const PointCloudComponent *pointcloud_component : src_components) {
-    totpoints += pointcloud_component->attribute_domain_size(ATTR_DOMAIN_POINT);
-  }
-
-  PointCloudComponent &dst_component = result.get_component_for_write<PointCloudComponent>();
-  PointCloud *pointcloud = BKE_pointcloud_new_nomain(totpoints);
-  dst_component.replace(pointcloud);
-
-  join_attributes(to_base_components(src_components), dst_component);
-}
-
 static void join_components(Span<const InstancesComponent *> src_components, GeometrySet &result)
 {
   InstancesComponent &dst_component = result.get_component_for_write<InstancesComponent>();
@@ -288,192 +156,6 @@ static void join_components(Span<const VolumeComponent *> src_components, Geomet
   UNUSED_VARS(src_components, dst_component);
 }
 
-/**
- * \note This takes advantage of the fact that creating attributes on joined curves never
- * changes a point attribute into a spline attribute; it is always the other way around.
- */
-static void ensure_control_point_attribute(const AttributeIDRef &attribute_id,
-                                           const CustomDataType data_type,
-                                           Span<CurveComponent *> src_components,
-                                           CurveEval &result)
-{
-  MutableSpan<SplinePtr> splines = result.splines();
-  const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
-  /* In order to fill point attributes with spline domain attribute values where necessary, keep
-   * track of the curve each spline came from while iterating over the splines in the result. */
-  int src_component_index = 0;
-  int spline_index_in_component = 0;
-  const CurveEval *current_curve = src_components[src_component_index]->get_for_read();
-
-  for (SplinePtr &spline : splines) {
-    std::optional<GSpan> attribute = spline->attributes.get_for_read(attribute_id);
-
-    if (attribute) {
-      if (attribute->type() != type) {
-        /* In this case, the attribute exists, but it has the wrong type. So create a buffer
-         * for the converted values, do the conversion, and then replace the attribute. */
-        void *converted_buffer = MEM_mallocN_aligned(
-            spline->size() * type.size(), type.alignment(), __func__);
-
-        const DataTypeConversions &conversions = blender::nodes::get_implicit_type_conversions();
-        conversions.try_convert(GVArray::ForSpan(*attribute), type).materialize(converted_buffer);
-
-        spline->attributes.remove(attribute_id);
-        spline->attributes.create_by_move(attribute_id, data_type, converted_buffer);
-      }
-    }
-    else {
-      spline->attributes.create(attribute_id, data_type);
-
-      if (current_curve->attributes.get_for_read(attribute_id)) {
-        /* In this case the attribute did not exist, but there is a spline domain attribute
-         * we can retrieve a value from, as a spline to point domain conversion. So fill the
-         * new attribute with the value for this spline. */
-        GVArray current_curve_attribute = current_curve->attributes.get_for_read(
-            attribute_id, data_type, nullptr);
-
-        BLI_assert(spline->attributes.get_for_read(attribute_id));
-        std::optional<GMutableSpan> new_attribute = spline->attributes.get_for_write(attribute_id);
-
-        BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
-        current_curve_attribute.get(spline_index_in_component, buffer);
-        type.fill_assign_n(buffer, new_attribute->data(), new_attribute->size());
-      }
-    }
-
-    /* Move to the next spline and maybe the next input component. */
-    spline_index_in_component++;
-    if (spline != splines.last() && spline_index_in_component >= current_curve->splines().size()) {
-      src_component_index++;
-      spline_index_in_component = 0;
-
-      current_curve = src_components[src_component_index]->get_for_read();
-    }
-  }
-}
-
-/**
- * Curve point domain attributes must be in the same order on every spline. The order might have
- * been different on separate instances, so ensure that all splines have the same order. Note that
- * because #Map is used, the order is not necessarily consistent every time, but it is the same for
- * every spline, and that's what matters.
- */
-static void sort_curve_point_attributes(const Map<AttributeIDRef, AttributeMetaData> &info,
-                                        MutableSpan<SplinePtr> splines)
-{
-  Vector<AttributeIDRef> new_order;
-  for (Map<AttributeIDRef, AttributeMetaData>::Item item : info.items()) {
-    if (item.value.domain == ATTR_DOMAIN_POINT) {
-      /* Only sort attributes stored on splines. */
-      new_order.append(item.key);
-    }
-  }
-  for (SplinePtr &spline : splines) {
-    spline->attributes.reorder(new_order);
-  }
-}
-
-/**
- * Fill data for an attribute on the new curve based on all source curves.
- */
-static void ensure_spline_attribute(const AttributeIDRef &attribute_id,
-                                    const CustomDataType data_type,
-                                    Span<CurveComponent *> src_components,
-                                    CurveEval &result)
-{
-  const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
-  result.attributes.create(attribute_id, data_type);
-  GMutableSpan result_attribute = *result.attributes.get_for_write(attribute_id);
-
-  int offset = 0;
-  for 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list