[Bf-blender-cvs] [6e4b10d1b25] temp-attribute-transfer-node: progress

Jacques Lucke noreply at git.blender.org
Tue Apr 20 13:22:49 CEST 2021


Commit: 6e4b10d1b252c1c39ae6380cdff56d8eb9d1eda1
Author: Jacques Lucke
Date:   Tue Apr 20 13:20:57 2021 +0200
Branches: temp-attribute-transfer-node
https://developer.blender.org/rB6e4b10d1b252c1c39ae6380cdff56d8eb9d1eda1

progress

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

M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 25d4f8bec8f..578750135d0 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -158,7 +158,7 @@ class GeometryComponent {
   std::unique_ptr<blender::fn::GVArray> attribute_try_get_for_read(
       const blender::StringRef attribute_name, const AttributeDomain domain) const;
 
-  std::unique_ptr<blender::fn::GVArray> attribute_try_get_for_read(
+  blender::bke::ReadAttributeLookup attribute_try_get_for_read(
       const blender::StringRef attribute_name, const CustomDataType data_type) const;
 
   /* Get a virtual array to read the data of an attribute. If that is not possible, the returned
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 1fda0ada05b..3b2ee126d91 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -786,7 +786,7 @@ std::unique_ptr<blender::bke::GVArray> GeometryComponent::attribute_try_get_for_
   return std::move(attribute.varray);
 }
 
-std::unique_ptr<blender::fn::GVArray> GeometryComponent::attribute_try_get_for_read(
+blender::bke::ReadAttributeLookup GeometryComponent::attribute_try_get_for_read(
     const blender::StringRef attribute_name, const CustomDataType data_type) const
 {
   blender::bke::ReadAttributeLookup attribute = this->attribute_try_get_for_read(attribute_name);
@@ -796,11 +796,11 @@ std::unique_ptr<blender::fn::GVArray> GeometryComponent::attribute_try_get_for_r
   const blender::fn::CPPType *type = blender::bke::custom_data_type_to_cpp_type(data_type);
   BLI_assert(type != nullptr);
   if (attribute.varray->type() == *type) {
-    return std::move(attribute.varray);
+    return attribute;
   }
   const blender::nodes::DataTypeConversions &conversions =
       blender::nodes::get_implicit_type_conversions();
-  return conversions.try_convert(std::move(attribute.varray), *type);
+  return {conversions.try_convert(std::move(attribute.varray), *type), attribute.domain};
 }
 
 std::unique_ptr<blender::bke::GVArray> GeometryComponent::attribute_get_for_read(
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc
index 958040d6af8..5c5d7891387 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc
@@ -166,20 +166,68 @@ static void transfer_attribute(const GeometrySet &src_geometry,
 {
   const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
 
-  if (!src_geometry.has<PointCloudComponent>()) {
-    return;
+  GVArray_Typed<float3> dst_positions = dst_component.attribute_get_for_read<float3>(
+      "position", result_domain, {0, 0, 0});
+  const int64_t tot_dst_positions = dst_positions.size();
+
+  bool use_pointcloud = false;
+  Array<int> pointcloud_point_indices;
+  Array<float> pointcloud_point_distances_sq;
+
+  bool use_mesh = false;
+  Array<int> mesh_looptri_indices;
+  Array<float3> mesh_point_positions;
+  Array<float> mesh_point_distances_sq;
+
+  if (src_geometry.has<PointCloudComponent>()) {
+    const PointCloudComponent &component =
+        *src_geometry.get_component_for_read<PointCloudComponent>();
+    const PointCloud *pointcloud = component.get_for_read();
+    if (pointcloud != nullptr && pointcloud->totpoint > 0) {
+      pointcloud_point_indices.reinitialize(tot_dst_positions);
+      pointcloud_point_distances_sq.reinitialize(tot_dst_positions);
+      get_closest_pointcloud_point_indices(
+          *pointcloud, dst_positions, pointcloud_point_indices, pointcloud_point_distances_sq);
+      use_pointcloud = true;
+    }
   }
-  const PointCloudComponent &src_component =
-      *src_geometry.get_component_for_read<PointCloudComponent>();
-  const PointCloud *pointcloud = src_component.get_for_read();
-  if (pointcloud == nullptr) {
-    return;
+  if (src_geometry.has<MeshComponent>()) {
+    const MeshComponent &component = *src_geometry.get_component_for_read<MeshComponent>();
+    const Mesh *mesh = component.get_for_read();
+    if (mesh != nullptr && mesh->totpoly > 0) {
+      mesh_looptri_indices.reinitialize(tot_dst_positions);
+      mesh_point_positions.reinitialize(tot_dst_positions);
+      mesh_point_distances_sq.reinitialize(tot_dst_positions);
+      get_closest_mesh_surface_samples(*mesh,
+                                       dst_positions,
+                                       mesh_looptri_indices,
+                                       mesh_point_positions,
+                                       mesh_point_distances_sq);
+      use_mesh = true;
+    }
   }
-  if (pointcloud->totpoint == 0) {
-    return;
+
+  Vector<int> pointcloud_sample_indices;
+  Vector<int> mesh_sample_indices;
+
+  if (use_mesh && use_pointcloud) {
+    for (const int i : IndexRange(tot_dst_positions)) {
+      if (pointcloud_point_distances_sq[i] < mesh_point_distances_sq[i]) {
+        pointcloud_sample_indices.append(i);
+      }
+      else {
+        mesh_sample_indices.append(i);
+      }
+    }
+  }
+  else if (use_mesh) {
+    /* TODO: Optimize. */
+    mesh_sample_indices = IndexRange(tot_dst_positions).as_span();
+  }
+  else if (use_pointcloud) {
+    pointcloud_sample_indices = IndexRange(tot_dst_positions).as_span();
   }
-  GVArrayPtr src_attribute = src_component.attribute_try_get_for_read(src_name, data_type);
-  if (!src_attribute) {
+  else {
     return;
   }
 
@@ -189,20 +237,54 @@ static void transfer_attribute(const GeometrySet &src_geometry,
     return;
   }
 
-  GVArray_Typed<float3> dst_positions = dst_component.attribute_get_for_read<float3>(
-      "position", result_domain, {0, 0, 0});
-
-  Array<int> nearest_point_indices(dst_positions.size());
-  Array<float> nearest_point_distances_sq(dst_positions.size());
-  get_closest_pointcloud_point_indices(
-      *pointcloud, dst_positions, nearest_point_indices, nearest_point_distances_sq);
-
   BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
 
-  for (const int i : dst_positions.index_range()) {
-    const int point_index = nearest_point_indices[i];
-    src_attribute->get(point_index, buffer);
-    dst_attribute->set_by_relocate(i, buffer);
+  if (!pointcloud_sample_indices.is_empty()) {
+    const PointCloudComponent &component =
+        *src_geometry.get_component_for_read<PointCloudComponent>();
+    ReadAttributeLookup src_attribute = component.attribute_try_get_for_read(src_name, data_type);
+    if (src_attribute) {
+      BLI_assert(src_attribute.domain == ATTR_DOMAIN_POINT);
+      for (const int i : pointcloud_sample_indices) {
+        const int point_index = pointcloud_point_indices[i];
+        src_attribute.varray->get(point_index, buffer);
+        dst_attribute->set_by_relocate(i, buffer);
+      }
+    }
+    else {
+      const void *default_value = type.default_value();
+      for (const int i : pointcloud_point_indices) {
+        dst_attribute->set_by_copy(i, default_value);
+      }
+    }
+  }
+
+  if (!mesh_sample_indices.is_empty()) {
+    const MeshComponent &component = *src_geometry.get_component_for_read<MeshComponent>();
+    ReadAttributeLookup src_attribute = component.attribute_try_get_for_read(src_name, data_type);
+    if (src_attribute) {
+      GVArray_GSpan src_span{*src_attribute.varray};
+      switch (src_attribute.domain) {
+        case ATTR_DOMAIN_POINT: {
+          break;
+        }
+        case ATTR_DOMAIN_FACE: {
+          break;
+        }
+        case ATTR_DOMAIN_CORNER: {
+          break;
+        }
+        case ATTR_DOMAIN_EDGE: {
+          break;
+        }
+      }
+    }
+    else {
+      const void *default_value = type.default_value();
+      for (const int i : mesh_sample_indices) {
+        dst_attribute->set_by_copy(i, default_value);
+      }
+    }
   }
 
   dst_attribute.save();



More information about the Bf-blender-cvs mailing list