Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2021-06-22 20:19:34 +0300
committerHans Goudey <h.goudey@me.com>2021-06-22 20:19:34 +0300
commitebfad93039afc67adaf23ebb00443d324a325350 (patch)
tree3ba7fdf49dc841b49869f29377680399ba5cd705 /source/blender/blenkernel
parent3a48147b8ab92e4828157ec7a3a1a75dd1a6b964 (diff)
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.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc56
1 files changed, 44 insertions, 12 deletions
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);