[Bf-blender-cvs] [ebfad93039a] master: Fix T89343: Point cloud instances not transformed when realized

Hans Goudey noreply at git.blender.org
Tue Jun 22 19:19:42 CEST 2021


Commit: ebfad93039afc67adaf23ebb00443d324a325350
Author: Hans Goudey
Date:   Tue Jun 22 12:19:34 2021 -0500
Branches: master
https://developer.blender.org/rBebfad93039afc67adaf23ebb00443d324a325350

Fix T89343: Point cloud instances not transformed when realized

This problem has surprisingly been there for quite a few months.
For point clouds all attributes were handled the same, even "position",
which should be transformed when combining source points into the
destination.

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

M	source/blender/blenkernel/intern/geometry_set_instances.cc

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

diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 0aea57d1a45..8cf08d05d9d 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -550,6 +550,44 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
   }
 }
 
+static PointCloud *join_pointcloud_position_attribute(Span<GeometryInstanceGroup> set_groups)
+{
+  /* Count the total number of points. */
+  int totpoint = 0;
+  for (const GeometryInstanceGroup &set_group : set_groups) {
+    const GeometrySet &set = set_group.geometry_set;
+    if (set.has<PointCloudComponent>()) {
+      const PointCloudComponent &component = *set.get_component_for_read<PointCloudComponent>();
+      totpoint += component.attribute_domain_size(ATTR_DOMAIN_POINT);
+    }
+  }
+  if (totpoint == 0) {
+    return nullptr;
+  }
+
+  PointCloud *new_pointcloud = BKE_pointcloud_new_nomain(totpoint);
+
+  /* Transform each instance's point locations into the new point cloud. */
+  int offset = 0;
+  for (const GeometryInstanceGroup &set_group : set_groups) {
+    const GeometrySet &set = set_group.geometry_set;
+    const PointCloud *pointcloud = set.get_pointcloud_for_read();
+    if (pointcloud == nullptr) {
+      continue;
+    }
+    for (const float4x4 &transform : set_group.transforms) {
+      for (const int i : IndexRange(pointcloud->totpoint)) {
+        const float3 old_position = pointcloud->co[i];
+        const float3 new_position = transform * old_position;
+        copy_v3_v3(new_pointcloud->co[offset + i], new_position);
+      }
+      offset += pointcloud->totpoint;
+    }
+  }
+
+  return new_pointcloud;
+}
+
 static CurveEval *join_curve_splines_and_builtin_attributes(Span<GeometryInstanceGroup> set_groups)
 {
   Vector<SplinePtr> new_splines;
@@ -614,24 +652,17 @@ static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups,
 static void join_instance_groups_pointcloud(Span<GeometryInstanceGroup> set_groups,
                                             GeometrySet &result)
 {
-  int totpoint = 0;
-  for (const GeometryInstanceGroup &set_group : set_groups) {
-    const GeometrySet &set = set_group.geometry_set;
-    if (set.has<PointCloudComponent>()) {
-      const PointCloudComponent &component = *set.get_component_for_read<PointCloudComponent>();
-      totpoint += component.attribute_domain_size(ATTR_DOMAIN_POINT);
-    }
-  }
-  if (totpoint == 0) {
+  PointCloud *new_pointcloud = join_pointcloud_position_attribute(set_groups);
+  if (new_pointcloud == nullptr) {
     return;
   }
 
   PointCloudComponent &dst_component = result.get_component_for_write<PointCloudComponent>();
-  PointCloud *pointcloud = BKE_pointcloud_new_nomain(totpoint);
-  dst_component.replace(pointcloud);
+  dst_component.replace(new_pointcloud);
+
   Map<std::string, AttributeKind> attributes;
   geometry_set_gather_instances_attribute_info(
-      set_groups, {GEO_COMPONENT_TYPE_POINT_CLOUD}, {}, attributes);
+      set_groups, {GEO_COMPONENT_TYPE_POINT_CLOUD}, {"position"}, attributes);
   join_attributes(set_groups,
                   {GEO_COMPONENT_TYPE_POINT_CLOUD},
                   attributes,
@@ -659,6 +690,7 @@ static void join_instance_groups_curve(Span<GeometryInstanceGroup> set_groups, G
   if (curve == nullptr) {
     return;
   }
+
   CurveComponent &dst_component = result.get_component_for_write<CurveComponent>();
   dst_component.replace(curve);



More information about the Bf-blender-cvs mailing list