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:
Diffstat (limited to 'source/blender/blenkernel/intern/curves_geometry.cc')
-rw-r--r--source/blender/blenkernel/intern/curves_geometry.cc124
1 files changed, 61 insertions, 63 deletions
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index 6fdcb56fc91..06789e34ad4 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -58,7 +58,7 @@ CurvesGeometry::CurvesGeometry(const int point_num, const int curve_num)
CustomData_add_layer_named(&this->point_data,
CD_PROP_FLOAT3,
- CD_DEFAULT,
+ CD_CONSTRUCT,
nullptr,
this->point_num,
ATTR_POSITION.c_str());
@@ -222,7 +222,7 @@ static MutableSpan<T> get_mutable_attribute(CurvesGeometry &curves,
return {data, num};
}
data = (T *)CustomData_add_layer_named(
- &custom_data, type, CD_CALLOC, nullptr, num, name.c_str());
+ &custom_data, type, CD_SET_DEFAULT, nullptr, num, name.c_str());
MutableSpan<T> span = {data, num};
if (num > 0 && span.first() != default_value) {
span.fill(default_value);
@@ -255,6 +255,12 @@ void CurvesGeometry::fill_curve_types(const IndexMask selection, const CurveType
this->fill_curve_types(type);
return;
}
+ if (std::optional<int8_t> single_type = this->curve_types().get_if_single()) {
+ if (single_type == type) {
+ /* No need for an array if the types are already a single with the correct type. */
+ return;
+ }
+ }
/* A potential performance optimization is only counting the changed indices. */
this->curve_types_for_write().fill_indices(selection, type);
this->update_curve_types();
@@ -734,11 +740,14 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
const IndexRange points = this->points_for_curve(curve_index);
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
- if (handles_right[points.first()] != positions[points.first()]) {
+ const float epsilon = 1e-6f;
+ if (!math::almost_equal_relative(
+ handles_right[points.first()], positions[points.first()], epsilon)) {
tangents[evaluated_points.first()] = math::normalize(handles_right[points.first()] -
positions[points.first()]);
}
- if (handles_left[points.last()] != positions[points.last()]) {
+ if (!math::almost_equal_relative(
+ handles_left[points.last()], positions[points.last()], epsilon)) {
tangents[evaluated_points.last()] = math::normalize(positions[points.last()] -
handles_left[points.last()]);
}
@@ -939,6 +948,12 @@ void CurvesGeometry::ensure_evaluated_lengths() const
this->runtime->length_cache_dirty = false;
}
+void CurvesGeometry::ensure_can_interpolate_to_evaluated() const
+{
+ this->ensure_evaluated_offsets();
+ this->ensure_nurbs_basis_cache();
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -948,11 +963,11 @@ void CurvesGeometry::ensure_evaluated_lengths() const
void CurvesGeometry::resize(const int points_num, const int curves_num)
{
if (points_num != this->point_num) {
- CustomData_realloc(&this->point_data, points_num);
+ CustomData_realloc(&this->point_data, this->points_num(), points_num);
this->point_num = points_num;
}
if (curves_num != this->curve_num) {
- CustomData_realloc(&this->curve_data, curves_num);
+ CustomData_realloc(&this->curve_data, this->curves_num(), curves_num);
this->curve_num = curves_num;
this->curve_offsets = (int *)MEM_reallocN(this->curve_offsets, sizeof(int) * (curves_num + 1));
}
@@ -1357,73 +1372,57 @@ static void reverse_swap_curve_point_data(const CurvesGeometry &curves,
std::swap(a[end_index], b[i]);
std::swap(b[end_index], a[i]);
}
+ if (points.size() % 2) {
+ const int64_t middle_index = points.size() / 2;
+ std::swap(a[middle_index], b[middle_index]);
+ }
}
});
}
-static bool layer_matches_name_and_type(const CustomDataLayer &layer,
- const StringRef name,
- const eCustomDataType type)
-{
- if (layer.type != type) {
- return false;
- }
- return layer.name == name;
-}
-
void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse)
{
- CustomData_duplicate_referenced_layers(&this->point_data, this->points_num());
-
- /* Collect the Bezier handle attributes while iterating through the point custom data layers;
- * they need special treatment later. */
- MutableSpan<float3> positions_left;
- MutableSpan<float3> positions_right;
- MutableSpan<int8_t> types_left;
- MutableSpan<int8_t> types_right;
+ Set<StringRef> bezier_handle_names{{ATTR_HANDLE_POSITION_LEFT,
+ ATTR_HANDLE_POSITION_RIGHT,
+ ATTR_HANDLE_TYPE_LEFT,
+ ATTR_HANDLE_TYPE_RIGHT}};
- for (const int layer_i : IndexRange(this->point_data.totlayer)) {
- CustomDataLayer &layer = this->point_data.layers[layer_i];
+ MutableAttributeAccessor attributes = this->attributes_for_write();
- if (positions_left.is_empty() &&
- layer_matches_name_and_type(layer, ATTR_HANDLE_POSITION_LEFT, CD_PROP_FLOAT3)) {
- positions_left = {static_cast<float3 *>(layer.data), this->points_num()};
- continue;
+ attributes.for_all([&](const AttributeIDRef &id, AttributeMetaData meta_data) {
+ if (meta_data.domain != ATTR_DOMAIN_POINT) {
+ return true;
}
- if (positions_right.is_empty() &&
- layer_matches_name_and_type(layer, ATTR_HANDLE_POSITION_RIGHT, CD_PROP_FLOAT3)) {
- positions_right = {static_cast<float3 *>(layer.data), this->points_num()};
- continue;
- }
- if (types_left.is_empty() &&
- layer_matches_name_and_type(layer, ATTR_HANDLE_TYPE_LEFT, CD_PROP_INT8)) {
- types_left = {static_cast<int8_t *>(layer.data), this->points_num()};
- continue;
- }
- if (types_right.is_empty() &&
- layer_matches_name_and_type(layer, ATTR_HANDLE_TYPE_RIGHT, CD_PROP_INT8)) {
- types_right = {static_cast<int8_t *>(layer.data), this->points_num()};
- continue;
+ if (id.is_named() && bezier_handle_names.contains(id.name())) {
+ return true;
}
- const eCustomDataType data_type = static_cast<eCustomDataType>(layer.type);
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id);
+ attribute_math::convert_to_static_type(attribute.span.type(), [&](auto dummy) {
using T = decltype(dummy);
- reverse_curve_point_data<T>(
- *this, curves_to_reverse, {static_cast<T *>(layer.data), this->points_num()});
+ reverse_curve_point_data<T>(*this, curves_to_reverse, attribute.span.typed<T>());
});
- }
+ attribute.finish();
+ return true;
+ });
/* In order to maintain the shape of Bezier curves, handle attributes must reverse, but also the
* values for the left and right must swap. Use a utility to swap and reverse at the same time,
* to avoid loading the attribute twice. Generally we can expect the right layer to exist when
* the left does, but there's no need to count on it, so check for both attributes. */
- if (!positions_left.is_empty() && !positions_right.is_empty()) {
- reverse_swap_curve_point_data(*this, curves_to_reverse, positions_left, positions_right);
+ if (attributes.contains(ATTR_HANDLE_POSITION_LEFT) &&
+ attributes.contains(ATTR_HANDLE_POSITION_RIGHT)) {
+ reverse_swap_curve_point_data(*this,
+ curves_to_reverse,
+ this->handle_positions_left_for_write(),
+ this->handle_positions_right_for_write());
}
- if (!types_left.is_empty() && !types_right.is_empty()) {
- reverse_swap_curve_point_data(*this, curves_to_reverse, types_left, types_right);
+ if (attributes.contains(ATTR_HANDLE_TYPE_LEFT) && attributes.contains(ATTR_HANDLE_TYPE_RIGHT)) {
+ reverse_swap_curve_point_data(*this,
+ curves_to_reverse,
+ this->handle_types_left_for_write(),
+ this->handle_types_right_for_write());
}
this->tag_topology_changed();
@@ -1431,21 +1430,20 @@ void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse)
void CurvesGeometry::remove_attributes_based_on_types()
{
- const int points_num = this->points_num();
- const int curves_num = this->curves_num();
+ MutableAttributeAccessor attributes = this->attributes_for_write();
if (!this->has_curve_with_type(CURVE_TYPE_BEZIER)) {
- CustomData_free_layer_named(&this->point_data, ATTR_HANDLE_TYPE_LEFT.c_str(), points_num);
- CustomData_free_layer_named(&this->point_data, ATTR_HANDLE_TYPE_RIGHT.c_str(), points_num);
- CustomData_free_layer_named(&this->point_data, ATTR_HANDLE_POSITION_LEFT.c_str(), points_num);
- CustomData_free_layer_named(&this->point_data, ATTR_HANDLE_POSITION_RIGHT.c_str(), points_num);
+ attributes.remove(ATTR_HANDLE_TYPE_LEFT);
+ attributes.remove(ATTR_HANDLE_TYPE_RIGHT);
+ attributes.remove(ATTR_HANDLE_POSITION_LEFT);
+ attributes.remove(ATTR_HANDLE_POSITION_RIGHT);
}
if (!this->has_curve_with_type(CURVE_TYPE_NURBS)) {
- CustomData_free_layer_named(&this->point_data, ATTR_NURBS_WEIGHT.c_str(), points_num);
- CustomData_free_layer_named(&this->curve_data, ATTR_NURBS_ORDER.c_str(), curves_num);
- CustomData_free_layer_named(&this->curve_data, ATTR_NURBS_KNOTS_MODE.c_str(), curves_num);
+ attributes.remove(ATTR_NURBS_WEIGHT);
+ attributes.remove(ATTR_NURBS_ORDER);
+ attributes.remove(ATTR_NURBS_KNOTS_MODE);
}
if (!this->has_curve_with_type({CURVE_TYPE_BEZIER, CURVE_TYPE_CATMULL_ROM, CURVE_TYPE_NURBS})) {
- CustomData_free_layer_named(&this->curve_data, ATTR_RESOLUTION.c_str(), curves_num);
+ attributes.remove(ATTR_RESOLUTION);
}
}