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/blenkernel/BKE_attribute_access.hh5
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc20
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc19
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc20
4 files changed, 64 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index cf19eb29a0e..6a87375e5e2 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -372,6 +372,11 @@ class CustomDataAttributes {
void *buffer);
bool remove(const AttributeIDRef &attribute_id);
+ /**
+ * Change the order of the attributes to match the order of IDs in the argument.
+ */
+ void reorder(Span<AttributeIDRef> new_order);
+
bool foreach_attribute(const AttributeForeachCallback callback,
const AttributeDomain domain) const;
};
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index aeb66dc5a33..cd394a4ca42 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -835,6 +835,26 @@ bool CustomDataAttributes::foreach_attribute(const AttributeForeachCallback call
return true;
}
+void CustomDataAttributes::reorder(Span<AttributeIDRef> new_order)
+{
+ BLI_assert(new_order.size() == data.totlayer);
+
+ Map<AttributeIDRef, int> old_order;
+ old_order.reserve(data.totlayer);
+ Array<CustomDataLayer> old_layers(Span(data.layers, data.totlayer));
+ for (const int i : old_layers.index_range()) {
+ old_order.add_new(attribute_id_from_custom_data_layer(old_layers[i]), i);
+ }
+
+ MutableSpan layers(data.layers, data.totlayer);
+ for (const int i : layers.index_range()) {
+ const int old_index = old_order.lookup(new_order[i]);
+ layers[i] = old_layers[old_index];
+ }
+
+ CustomData_update_typemap(&data);
+}
+
} // namespace blender::bke
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 35c6a7df2c7..82fc14e7772 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -530,6 +530,24 @@ static void join_instance_groups_volume(Span<GeometryInstanceGroup> set_groups,
}
}
+/**
+ * Curve point domain attributes must be in the same order on every spline. The order might have
+ * been different on separate instances, so ensure that all splines have the same order. Note that
+ * because #Map is used, the order is not necessarily consistent every time, but it is the same for
+ * every spline, and that's what matters.
+ */
+static void sort_curve_point_attributes(const Map<AttributeIDRef, AttributeKind> &info,
+ MutableSpan<SplinePtr> splines)
+{
+ Vector<AttributeIDRef> new_order;
+ for (const AttributeIDRef attribute_id : info.keys()) {
+ new_order.append(attribute_id);
+ }
+ for (SplinePtr &spline : splines) {
+ spline->attributes.reorder(new_order);
+ }
+}
+
static void join_instance_groups_curve(Span<GeometryInstanceGroup> set_groups, GeometrySet &result)
{
CurveEval *curve = join_curve_splines_and_builtin_attributes(set_groups);
@@ -550,6 +568,7 @@ static void join_instance_groups_curve(Span<GeometryInstanceGroup> set_groups, G
{GEO_COMPONENT_TYPE_CURVE},
attributes,
static_cast<GeometryComponent &>(dst_component));
+ sort_curve_point_attributes(attributes, curve->splines());
}
GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index cd385f364e9..1422bf2e475 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -357,6 +357,24 @@ static void ensure_control_point_attribute(const AttributeIDRef &attribute_id,
}
/**
+ * Curve point domain attributes must be in the same order on every spline. The order might have
+ * been different on separate instances, so ensure that all splines have the same order. Note that
+ * because #Map is used, the order is not necessarily consistent every time, but it is the same for
+ * every spline, and that's what matters.
+ */
+static void sort_curve_point_attributes(const Map<AttributeIDRef, AttributeMetaData> &info,
+ MutableSpan<SplinePtr> splines)
+{
+ Vector<AttributeIDRef> new_order;
+ for (const AttributeIDRef attribute_id : info.keys()) {
+ new_order.append(attribute_id);
+ }
+ for (SplinePtr &spline : splines) {
+ spline->attributes.reorder(new_order);
+ }
+}
+
+/**
* Fill data for an attribute on the new curve based on all source curves.
*/
static void ensure_spline_attribute(const AttributeIDRef &attribute_id,
@@ -409,6 +427,8 @@ static void join_curve_attributes(const Map<AttributeIDRef, AttributeMetaData> &
ensure_control_point_attribute(attribute_id, meta_data.data_type, src_components, result);
}
}
+
+ sort_curve_point_attributes(info, result.splines());
}
static void join_curve_components(MutableSpan<GeometrySet> src_geometry_sets, GeometrySet &result)