Merge branch 'blender-v3.0-release'
This commit is contained in:
commit
8c58838f6a
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -348,6 +348,7 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
|
|||
* because attributes are stored on splines rather than in a flat array on the curve:
|
||||
* - The same set of attributes exists on every spline.
|
||||
* - Attributes with the same name have the same type on every spline.
|
||||
* - Attributes are in the same order on every spline.
|
||||
*/
|
||||
void CurveEval::assert_valid_point_attributes() const
|
||||
{
|
||||
|
@ -356,25 +357,40 @@ void CurveEval::assert_valid_point_attributes() const
|
|||
return;
|
||||
}
|
||||
const int layer_len = splines_.first()->attributes.data.totlayer;
|
||||
Map<AttributeIDRef, AttributeMetaData> map;
|
||||
for (const SplinePtr &spline : splines_) {
|
||||
BLI_assert(spline->attributes.data.totlayer == layer_len);
|
||||
spline->attributes.foreach_attribute(
|
||||
|
||||
Array<AttributeIDRef> ids_in_order(layer_len);
|
||||
Array<AttributeMetaData> meta_data_in_order(layer_len);
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
splines_.first()->attributes.foreach_attribute(
|
||||
[&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
|
||||
map.add_or_modify(
|
||||
attribute_id,
|
||||
[&](AttributeMetaData *map_data) {
|
||||
/* All unique attribute names should be added on the first spline. */
|
||||
BLI_assert(spline == splines_.first());
|
||||
*map_data = meta_data;
|
||||
},
|
||||
[&](AttributeMetaData *map_data) {
|
||||
/* Attributes on different splines should all have the same type. */
|
||||
BLI_assert(meta_data == *map_data);
|
||||
});
|
||||
ids_in_order[i] = attribute_id;
|
||||
meta_data_in_order[i] = meta_data;
|
||||
i++;
|
||||
return true;
|
||||
},
|
||||
ATTR_DOMAIN_POINT);
|
||||
}
|
||||
|
||||
for (const SplinePtr &spline : splines_) {
|
||||
/* All splines should have the same number of attributes. */
|
||||
BLI_assert(spline->attributes.data.totlayer == layer_len);
|
||||
|
||||
int i = 0;
|
||||
spline->attributes.foreach_attribute(
|
||||
[&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
|
||||
/* Attribute names and IDs should have the same order and exist on all splines. */
|
||||
BLI_assert(attribute_id == ids_in_order[i]);
|
||||
|
||||
/* Attributes with the same ID different splines should all have the same type. */
|
||||
BLI_assert(meta_data == meta_data_in_order[i]);
|
||||
|
||||
i++;
|
||||
return true;
|
||||
},
|
||||
ATTR_DOMAIN_POINT);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -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,8 @@ 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());
|
||||
curve->assert_valid_point_attributes();
|
||||
}
|
||||
|
||||
GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set)
|
||||
|
|
|
@ -356,6 +356,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.
|
||||
*/
|
||||
|
@ -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)
|
||||
|
@ -449,6 +469,7 @@ static void join_curve_components(MutableSpan<GeometrySet> src_geometry_sets, Ge
|
|||
dst_curve->attributes.reallocate(dst_curve->splines().size());
|
||||
|
||||
join_curve_attributes(info, src_components, *dst_curve);
|
||||
dst_curve->assert_valid_point_attributes();
|
||||
|
||||
dst_component.replace(dst_curve);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue