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:
authorJacques Lucke <jacques@blender.org>2022-06-18 14:01:41 +0300
committerJacques Lucke <jacques@blender.org>2022-06-18 14:01:41 +0300
commit30f244d96f16142d449cc1d050dc88218201fa4a (patch)
tree10e7436d04c9f817e25880efd7ff6a23528b3a9f
parent3c2a2a6c9659dd66f1a1d3a5e4153d1d2f8243eb (diff)
Fix: curves have incorrect resolution attribute after realizing instances
If the resolution attribute existed on some curves, but not on others, it was initialized to zero by default. However, zero is not a valid resolution.
-rw-r--r--source/blender/geometry/intern/realize_instances.cc43
1 files changed, 38 insertions, 5 deletions
diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc
index 4db4256ec8f..bd4099d37f9 100644
--- a/source/blender/geometry/intern/realize_instances.cc
+++ b/source/blender/geometry/intern/realize_instances.cc
@@ -134,6 +134,12 @@ struct RealizeCurveInfo {
* doesn't exist on some (but not all) of the input curves data-blocks.
*/
Span<float> radius;
+
+ /**
+ * The resolution attribute must be filled with the default value if it does not exist on some
+ * curves.
+ */
+ VArray<int> resolution;
};
/** Start indices in the final output curves data-block. */
@@ -185,6 +191,7 @@ struct AllCurvesInfo {
bool create_id_attribute = false;
bool create_handle_postion_attributes = false;
bool create_radius_attribute = false;
+ bool create_resolution_attribute = false;
};
/** Collects all tasks that need to be executed to realize all instances. */
@@ -1037,6 +1044,7 @@ static OrderedAttributes gather_generic_curve_attributes_to_propagate(
src_component_types, GEO_COMPONENT_TYPE_CURVE, true, attributes_to_propagate);
attributes_to_propagate.remove("position");
attributes_to_propagate.remove("radius");
+ attributes_to_propagate.remove("resolution");
attributes_to_propagate.remove("handle_right");
attributes_to_propagate.remove("handle_left");
r_create_id = attributes_to_propagate.pop_try("id").has_value();
@@ -1075,12 +1083,13 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set,
info.realize_info.reinitialize(info.order.size());
for (const int curve_index : info.realize_info.index_range()) {
RealizeCurveInfo &curve_info = info.realize_info[curve_index];
- const Curves *curves = info.order[curve_index];
- curve_info.curves = curves;
+ const Curves *curves_id = info.order[curve_index];
+ const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
+ curve_info.curves = curves_id;
/* Access attributes. */
CurveComponent component;
- component.replace(const_cast<Curves *>(curves), GeometryOwnershipType::ReadOnly);
+ component.replace(const_cast<Curves *>(curves_id), GeometryOwnershipType::ReadOnly);
curve_info.attributes.reinitialize(info.attributes.size());
for (const int attribute_index : info.attributes.index_range()) {
const eAttrDomain domain = info.attributes.kinds[attribute_index].domain;
@@ -1106,6 +1115,12 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set,
info.create_radius_attribute = true;
}
+ /* Retrieve the resolution attribute, if it exists. */
+ curve_info.resolution = curves.resolution();
+ if (component.attribute_exists("resolution")) {
+ info.create_resolution_attribute = true;
+ }
+
/* Retrieve handle position attributes, if they exist. */
if (component.attribute_exists("handle_right")) {
curve_info.handle_left = component
@@ -1131,7 +1146,8 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options,
MutableSpan<int> all_dst_ids,
MutableSpan<float3> all_handle_left,
MutableSpan<float3> all_handle_right,
- MutableSpan<float> all_radii)
+ MutableSpan<float> all_radii,
+ MutableSpan<int> all_resolutions)
{
const RealizeCurveInfo &curves_info = *task.curve_info;
const Curves &curves_id = *curves_info.curves;
@@ -1171,6 +1187,10 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options,
}
}
+ if (all_curves_info.create_resolution_attribute) {
+ curves_info.resolution.materialize(all_resolutions.slice(dst_curve_range));
+ }
+
/* Copy curve offsets. */
const Span<int> src_offsets = curves.offsets();
const MutableSpan<int> dst_offsets = dst_curves.offsets_for_write().slice(dst_curve_range);
@@ -1268,6 +1288,15 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
radius_span = radius.as_span();
}
+ /* Prepare resolution attribute if necessary. */
+ OutputAttribute_Typed<int> resolution;
+ MutableSpan<int> resolution_span;
+ if (all_curves_info.create_resolution_attribute) {
+ resolution = dst_component.attribute_try_get_for_output_only<int>("resolution",
+ ATTR_DOMAIN_CURVE);
+ resolution_span = resolution.as_span();
+ }
+
/* Actually execute all tasks. */
threading::parallel_for(tasks.index_range(), 100, [&](const IndexRange task_range) {
for (const int task_index : task_range) {
@@ -1281,7 +1310,8 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
point_ids_span,
handle_left_span,
handle_right_span,
- radius_span);
+ radius_span,
+ resolution_span);
}
});
@@ -1295,6 +1325,9 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
if (radius) {
radius.save();
}
+ if (resolution) {
+ resolution.save();
+ }
if (all_curves_info.create_handle_postion_attributes) {
handle_left.save();
handle_right.save();