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:
-rw-r--r--source/blender/geometry/intern/realize_instances.cc323
1 files changed, 132 insertions, 191 deletions
diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc
index 94c75e8dbb1..100146bbf0c 100644
--- a/source/blender/geometry/intern/realize_instances.cc
+++ b/source/blender/geometry/intern/realize_instances.cc
@@ -265,6 +265,81 @@ static void copy_transformed_positions(const Span<float3> src,
});
}
+static void threaded_copy(const GSpan src, GMutableSpan dst)
+{
+ BLI_assert(src.size() == dst.size());
+ BLI_assert(src.type() == dst.type());
+ threading::parallel_for(IndexRange(src.size()), 1024, [&](const IndexRange range) {
+ src.type().copy_construct_n(src.slice(range).data(), dst.slice(range).data(), range.size());
+ });
+}
+
+static void threaded_fill(const fn::GPointer value, GMutableSpan dst)
+{
+ BLI_assert(*value.type() == dst.type());
+ threading::parallel_for(IndexRange(dst.size()), 1024, [&](const IndexRange range) {
+ value.type()->fill_construct_n(value.get(), dst.slice(range).data(), range.size());
+ });
+}
+
+static void copy_generic_attributes_to_result(
+ const Span<std::optional<GVArray_GSpan>> src_attributes,
+ const AttributeFallbacksArray &attribute_fallbacks,
+ const OrderedAttributes &ordered_attributes,
+ const FunctionRef<IndexRange(AttributeDomain)> &range_fn,
+ MutableSpan<GMutableSpan> dst_attributes)
+{
+ threading::parallel_for(dst_attributes.index_range(), 10, [&](const IndexRange attribute_range) {
+ for (const int attribute_index : attribute_range) {
+ const AttributeDomain domain = ordered_attributes.kinds[attribute_index].domain;
+ const IndexRange element_slice = range_fn(domain);
+
+ GMutableSpan dst_span = dst_attributes[attribute_index].slice(element_slice);
+ if (src_attributes[attribute_index].has_value()) {
+ threaded_copy(*src_attributes[attribute_index], dst_span);
+ }
+ else {
+ const CPPType &cpp_type = dst_span.type();
+ const void *fallback = attribute_fallbacks.array[attribute_index] == nullptr ?
+ cpp_type.default_value() :
+ attribute_fallbacks.array[attribute_index];
+ threaded_fill({cpp_type, fallback}, dst_span);
+ }
+ }
+ });
+}
+
+static void create_result_ids(const RealizeInstancesOptions &options,
+ Span<int> stored_ids,
+ const int task_id,
+ MutableSpan<int> dst_ids)
+{
+ if (options.keep_original_ids) {
+ if (stored_ids.is_empty()) {
+ dst_ids.fill(0);
+ }
+ else {
+ dst_ids.copy_from(stored_ids);
+ }
+ }
+ else {
+ if (stored_ids.is_empty()) {
+ threading::parallel_for(dst_ids.index_range(), 1024, [&](const IndexRange range) {
+ for (const int i : range) {
+ dst_ids[i] = noise::hash(task_id, i);
+ }
+ });
+ }
+ else {
+ threading::parallel_for(dst_ids.index_range(), 1024, [&](const IndexRange range) {
+ for (const int i : range) {
+ dst_ids[i] = noise::hash(task_id, stored_ids[i]);
+ }
+ });
+ }
+ }
+}
+
/* -------------------------------------------------------------------- */
/** \name Gather Realize Tasks
* \{ */
@@ -595,6 +670,7 @@ static AllPointCloudsInfo preprocess_pointclouds(const GeometrySet &geometry_set
static void execute_realize_pointcloud_task(const RealizeInstancesOptions &options,
const RealizePointCloudTask &task,
+ const OrderedAttributes &ordered_attributes,
PointCloud &dst_pointcloud,
MutableSpan<GMutableSpan> dst_attribute_spans,
MutableSpan<int> all_dst_ids)
@@ -605,64 +681,25 @@ static void execute_realize_pointcloud_task(const RealizeInstancesOptions &optio
const IndexRange point_slice{task.start_index, pointcloud.totpoint};
MutableSpan<float3> dst_positions{(float3 *)dst_pointcloud.co + task.start_index,
pointcloud.totpoint};
- MutableSpan<int> dst_ids = all_dst_ids.slice(task.start_index, pointcloud.totpoint);
copy_transformed_positions(src_positions, task.transform, dst_positions);
/* Create point ids. */
if (!all_dst_ids.is_empty()) {
- if (options.keep_original_ids) {
- if (pointcloud_info.stored_ids.is_empty()) {
- dst_ids.fill(0);
- }
- else {
- dst_ids.copy_from(pointcloud_info.stored_ids);
- }
- }
- else {
- threading::parallel_for(IndexRange(pointcloud.totpoint), 1024, [&](const IndexRange range) {
- if (pointcloud_info.stored_ids.is_empty()) {
- for (const int i : range) {
- dst_ids[i] = noise::hash(task.id, i);
- }
- }
- else {
- for (const int i : range) {
- dst_ids[i] = noise::hash(task.id, pointcloud_info.stored_ids[i]);
- }
- }
- });
- }
+ create_result_ids(
+ options, pointcloud_info.stored_ids, task.id, all_dst_ids.slice(point_slice));
}
- /* Copy generic attributes. */
- threading::parallel_for(
- dst_attribute_spans.index_range(), 10, [&](const IndexRange attribute_range) {
- for (const int attribute_index : attribute_range) {
- GMutableSpan dst_span = dst_attribute_spans[attribute_index].slice(point_slice);
- const CPPType &cpp_type = dst_span.type();
- const void *attribute_fallback = task.attribute_fallbacks.array[attribute_index];
- if (pointcloud_info.attributes[attribute_index].has_value()) {
- /* Copy attribute from the original point cloud. */
- const GSpan src_span = *pointcloud_info.attributes[attribute_index];
- threading::parallel_for(
- IndexRange(pointcloud.totpoint), 1024, [&](const IndexRange range) {
- cpp_type.copy_construct_n(
- src_span.slice(range).data(), dst_span.slice(range).data(), range.size());
- });
- }
- else {
- if (attribute_fallback == nullptr) {
- attribute_fallback = cpp_type.default_value();
- }
- /* As the fallback value for the attribute. */
- threading::parallel_for(
- IndexRange(pointcloud.totpoint), 1024, [&](const IndexRange range) {
- cpp_type.fill_construct_n(
- attribute_fallback, dst_span.slice(range).data(), range.size());
- });
- }
- }
- });
+
+ copy_generic_attributes_to_result(
+ pointcloud_info.attributes,
+ task.attribute_fallbacks,
+ ordered_attributes,
+ [&](const AttributeDomain domain) {
+ BLI_assert(domain == ATTR_DOMAIN_POINT);
+ UNUSED_VARS_NDEBUG(domain);
+ return point_slice;
+ },
+ dst_attribute_spans);
}
static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &options,
@@ -710,7 +747,7 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti
for (const int task_index : task_range) {
const RealizePointCloudTask &task = tasks[task_index];
execute_realize_pointcloud_task(
- options, task, *dst_pointcloud, dst_attribute_spans, point_ids_span);
+ options, task, ordered_attributes, *dst_pointcloud, dst_attribute_spans, point_ids_span);
}
});
@@ -842,9 +879,6 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options,
MutableSpan<MLoop> dst_loops{dst_mesh.mloop + task.start_indices.loop, mesh.totloop};
MutableSpan<MPoly> dst_polys{dst_mesh.mpoly + task.start_indices.poly, mesh.totpoly};
- MutableSpan<int> dst_vertex_ids = all_dst_vertex_ids.slice(task.start_indices.vertex,
- mesh.totvert);
-
const Span<int> material_index_map = mesh_info.material_index_map;
threading::parallel_for(IndexRange(mesh.totvert), 1024, [&](const IndexRange vert_range) {
@@ -888,79 +922,34 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options,
}
}
});
- /* Create id attribute. */
+
if (!all_dst_vertex_ids.is_empty()) {
- if (options.keep_original_ids) {
- if (mesh_info.stored_vertex_ids.is_empty()) {
- dst_vertex_ids.fill(0);
- }
- else {
- dst_vertex_ids.copy_from(mesh_info.stored_vertex_ids);
- }
- }
- else {
- threading::parallel_for(IndexRange(mesh.totvert), 1024, [&](const IndexRange vert_range) {
- if (mesh_info.stored_vertex_ids.is_empty()) {
- for (const int i : vert_range) {
- dst_vertex_ids[i] = noise::hash(task.id, i);
- }
- }
- else {
- for (const int i : vert_range) {
- const int original_id = mesh_info.stored_vertex_ids[i];
- dst_vertex_ids[i] = noise::hash(task.id, original_id);
- }
- }
- });
- }
+ create_result_ids(options,
+ mesh_info.stored_vertex_ids,
+ task.id,
+ all_dst_vertex_ids.slice(task.start_indices.vertex, mesh.totvert));
}
- /* Copy generic attributes. */
- threading::parallel_for(
- dst_attribute_spans.index_range(), 10, [&](const IndexRange attribute_range) {
- for (const int attribute_index : attribute_range) {
- const AttributeDomain domain = ordered_attributes.kinds[attribute_index].domain;
- IndexRange element_slice;
- switch (domain) {
- case ATTR_DOMAIN_POINT:
- element_slice = IndexRange(task.start_indices.vertex, mesh.totvert);
- break;
- case ATTR_DOMAIN_EDGE:
- element_slice = IndexRange(task.start_indices.edge, mesh.totedge);
- break;
- case ATTR_DOMAIN_CORNER:
- element_slice = IndexRange(task.start_indices.loop, mesh.totloop);
- break;
- case ATTR_DOMAIN_FACE:
- element_slice = IndexRange(task.start_indices.poly, mesh.totpoly);
- break;
- default:
- BLI_assert_unreachable();
- break;
- }
- GMutableSpan dst_span = dst_attribute_spans[attribute_index].slice(element_slice);
- const CPPType &cpp_type = dst_span.type();
- const void *attribute_fallback = task.attribute_fallbacks.array[attribute_index];
- if (mesh_info.attributes[attribute_index].has_value()) {
- const GSpan src_span = *mesh_info.attributes[attribute_index];
- threading::parallel_for(
- IndexRange(element_slice.size()), 1024, [&](const IndexRange sub_range) {
- cpp_type.copy_construct_n(src_span.slice(sub_range).data(),
- dst_span.slice(sub_range).data(),
- sub_range.size());
- });
- }
- else {
- if (attribute_fallback == nullptr) {
- attribute_fallback = cpp_type.default_value();
- }
- threading::parallel_for(
- IndexRange(element_slice.size()), 1024, [&](const IndexRange sub_range) {
- cpp_type.fill_construct_n(
- attribute_fallback, dst_span.slice(sub_range).data(), sub_range.size());
- });
- }
+
+ copy_generic_attributes_to_result(
+ mesh_info.attributes,
+ task.attribute_fallbacks,
+ ordered_attributes,
+ [&](const AttributeDomain domain) {
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ return IndexRange(task.start_indices.vertex, mesh.totvert);
+ case ATTR_DOMAIN_EDGE:
+ return IndexRange(task.start_indices.edge, mesh.totedge);
+ case ATTR_DOMAIN_CORNER:
+ return IndexRange(task.start_indices.loop, mesh.totloop);
+ case ATTR_DOMAIN_FACE:
+ return IndexRange(task.start_indices.poly, mesh.totpoly);
+ default:
+ BLI_assert_unreachable();
+ return IndexRange();
}
- });
+ },
+ dst_attribute_spans);
}
static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options,
@@ -1200,75 +1189,27 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options,
}
});
- /* Create id attribute. */
if (!all_dst_ids.is_empty()) {
- MutableSpan<int> dst_ids = all_dst_ids.slice(task.start_indices.point, curves.points_size());
- if (options.keep_original_ids) {
- if (curves_info.stored_ids.is_empty()) {
- dst_ids.fill(0);
- }
- else {
- dst_ids.copy_from(curves_info.stored_ids);
- }
- }
- else {
- threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange vert_range) {
- if (curves_info.stored_ids.is_empty()) {
- for (const int i : vert_range) {
- dst_ids[i] = noise::hash(task.id, i);
- }
- }
- else {
- for (const int i : vert_range) {
- const int original_id = curves_info.stored_ids[i];
- dst_ids[i] = noise::hash(task.id, original_id);
- }
- }
- });
- }
+ create_result_ids(
+ options, curves_info.stored_ids, task.id, all_dst_ids.slice(dst_point_range));
}
- /* Copy generic attributes. */
- threading::parallel_for(
- dst_attribute_spans.index_range(), 10, [&](const IndexRange attribute_range) {
- for (const int attribute_index : attribute_range) {
- const AttributeDomain domain = ordered_attributes.kinds[attribute_index].domain;
- IndexRange element_slice;
- switch (domain) {
- case ATTR_DOMAIN_POINT:
- element_slice = IndexRange(task.start_indices.point, curves.points_size());
- break;
- case ATTR_DOMAIN_CURVE:
- element_slice = IndexRange(task.start_indices.curve, curves.curves_size());
- break;
- default:
- BLI_assert_unreachable();
- break;
- }
- GMutableSpan dst_span = dst_attribute_spans[attribute_index].slice(element_slice);
- const CPPType &cpp_type = dst_span.type();
- const void *attribute_fallback = task.attribute_fallbacks.array[attribute_index];
- if (curves_info.attributes[attribute_index].has_value()) {
- const GSpan src_span = *curves_info.attributes[attribute_index];
- threading::parallel_for(
- IndexRange(element_slice.size()), 1024, [&](const IndexRange sub_range) {
- cpp_type.copy_construct_n(src_span.slice(sub_range).data(),
- dst_span.slice(sub_range).data(),
- sub_range.size());
- });
- }
- else {
- if (attribute_fallback == nullptr) {
- attribute_fallback = cpp_type.default_value();
- }
- threading::parallel_for(
- IndexRange(element_slice.size()), 1024, [&](const IndexRange sub_range) {
- cpp_type.fill_construct_n(
- attribute_fallback, dst_span.slice(sub_range).data(), sub_range.size());
- });
- }
+ copy_generic_attributes_to_result(
+ curves_info.attributes,
+ task.attribute_fallbacks,
+ ordered_attributes,
+ [&](const AttributeDomain domain) {
+ switch (domain) {
+ case ATTR_DOMAIN_POINT:
+ return IndexRange(task.start_indices.point, curves.points_size());
+ case ATTR_DOMAIN_CURVE:
+ return IndexRange(task.start_indices.curve, curves.curves_size());
+ default:
+ BLI_assert_unreachable();
+ return IndexRange();
}
- });
+ },
+ dst_attribute_spans);
}
static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,