[Bf-blender-cvs] [ed04957d762] temp-attribute-transfer-node: initial transfer from pointcloud
Jacques Lucke
noreply at git.blender.org
Tue Apr 20 13:22:49 CEST 2021
Commit: ed04957d7621cbce47cda9f5463bea5f98f004b7
Author: Jacques Lucke
Date: Tue Apr 20 12:14:14 2021 +0200
Branches: temp-attribute-transfer-node
https://developer.blender.org/rBed04957d7621cbce47cda9f5463bea5f98f004b7
initial transfer from pointcloud
===================================================================
M source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc
===================================================================
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 37d9b8443a3..7e5d5d6c62f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc
@@ -17,6 +17,10 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "BLI_kdopbvh.h"
+
+#include "BKE_bvhutils.h"
+
#include "node_geometry_util.hh"
static bNodeSocketTemplate geo_node_attribute_transfer_in[] = {
@@ -51,15 +55,97 @@ static void geo_node_attribute_transfer_init(bNodeTree *UNUSED(tree), bNode *nod
node->storage = data;
}
+static CustomDataType get_result_data_type(const GeometrySet &geometry,
+ const StringRef attribute_name)
+{
+ Vector<CustomDataType> data_types;
+
+ const PointCloudComponent *pointcloud_component =
+ geometry.get_component_for_read<PointCloudComponent>();
+ if (pointcloud_component != nullptr) {
+ ReadAttributeLookup attribute = pointcloud_component->attribute_try_get_for_read(
+ attribute_name);
+ if (attribute) {
+ data_types.append(bke::cpp_type_to_custom_data_type(attribute.varray->type()));
+ }
+ }
+
+ const MeshComponent *mesh_component = geometry.get_component_for_read<MeshComponent>();
+ if (mesh_component != nullptr) {
+ ReadAttributeLookup attribute = mesh_component->attribute_try_get_for_read(attribute_name);
+ if (attribute) {
+ data_types.append(bke::cpp_type_to_custom_data_type(attribute.varray->type()));
+ }
+ }
+ return bke::attribute_data_type_highest_complexity(data_types);
+}
+
+static void transfer_attribute(const GeometrySet &src_geometry,
+ GeometryComponent &dst_component,
+ const AttributeDomain result_domain,
+ const CustomDataType data_type,
+ const StringRef src_name,
+ const StringRef dst_name)
+{
+ const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
+
+ if (!src_geometry.has<PointCloudComponent>()) {
+ return;
+ }
+ const PointCloudComponent &src_component =
+ *src_geometry.get_component_for_read<PointCloudComponent>();
+ ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(src_name);
+ if (!src_attribute) {
+ return;
+ }
+ /* TODO: Possibly convert data type. */
+ BLI_assert(src_attribute.varray->type() == type);
+
+ OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
+ dst_name, result_domain, data_type);
+ if (!dst_attribute) {
+ return;
+ }
+
+ GVArray_Typed<float3> dst_positions = dst_component.attribute_get_for_read<float3>(
+ "position", result_domain, {0, 0, 0});
+
+ BVHTreeFromPointCloud tree_data_pointcloud;
+ BKE_bvhtree_from_pointcloud_get(&tree_data_pointcloud, src_component.get_for_read(), 2);
+ if (tree_data_pointcloud.tree == nullptr) {
+ return;
+ }
+
+ BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
+
+ for (const int i : dst_positions.index_range()) {
+ BVHTreeNearest nearest;
+ nearest.dist_sq = FLT_MAX;
+ const float3 position = dst_positions[i];
+ BLI_bvhtree_find_nearest(tree_data_pointcloud.tree,
+ position,
+ &nearest,
+ tree_data_pointcloud.nearest_callback,
+ &tree_data_pointcloud);
+
+ src_attribute.varray->get(nearest.index, buffer);
+ dst_attribute->set_by_relocate(i, buffer);
+ }
+
+ free_bvhtree_from_pointcloud(&tree_data_pointcloud);
+
+ dst_attribute.save();
+}
+
static void geo_node_attribute_transfer_exec(GeoNodeExecParams params)
{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- GeometrySet target_geometry_set = params.extract_input<GeometrySet>("Target");
+ GeometrySet dst_geometry_set = params.extract_input<GeometrySet>("Geometry");
+ GeometrySet src_geometry_set = params.extract_input<GeometrySet>("Target");
const std::string src_attribute_name = params.extract_input<std::string>("Source");
const std::string dst_attribute_name = params.extract_input<std::string>("Destination");
if (src_attribute_name.empty() || dst_attribute_name.empty()) {
- params.set_output("Geometry", geometry_set);
+ params.set_output("Geometry", dst_geometry_set);
return;
}
@@ -69,10 +155,30 @@ static void geo_node_attribute_transfer_exec(GeoNodeExecParams params)
const GeometryNodeAttributeTransferMappingMode mapping =
(GeometryNodeAttributeTransferMappingMode)storage.mapping;
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
- target_geometry_set = bke::geometry_set_realize_instances(target_geometry_set);
+ dst_geometry_set = bke::geometry_set_realize_instances(dst_geometry_set);
+ src_geometry_set = bke::geometry_set_realize_instances(src_geometry_set);
+
+ const CustomDataType result_data_type = get_result_data_type(src_geometry_set,
+ src_attribute_name);
+
+ if (dst_geometry_set.has<MeshComponent>()) {
+ transfer_attribute(src_geometry_set,
+ dst_geometry_set.get_component_for_write<MeshComponent>(),
+ dst_domain,
+ result_data_type,
+ src_attribute_name,
+ dst_attribute_name);
+ }
+ if (dst_geometry_set.has<PointCloudComponent>()) {
+ transfer_attribute(src_geometry_set,
+ dst_geometry_set.get_component_for_write<PointCloudComponent>(),
+ dst_domain,
+ result_data_type,
+ src_attribute_name,
+ dst_attribute_name);
+ }
- params.set_output("Geometry", geometry_set);
+ params.set_output("Geometry", dst_geometry_set);
}
} // namespace blender::nodes
More information about the Bf-blender-cvs
mailing list