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.cc209
1 files changed, 71 insertions, 138 deletions
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index b58781ce806..3050e01e528 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -62,9 +62,11 @@ CurvesGeometry::CurvesGeometry(const int point_num, const int curve_num)
this->point_num,
ATTR_POSITION.c_str());
- this->curve_offsets = (int *)MEM_calloc_arrayN(this->curve_num + 1, sizeof(int), __func__);
-
- this->update_customdata_pointers();
+ this->curve_offsets = (int *)MEM_malloc_arrayN(this->curve_num + 1, sizeof(int), __func__);
+#ifdef DEBUG
+ this->offsets_for_write().fill(-1);
+#endif
+ this->offsets_for_write().first() = 0;
this->runtime = MEM_new<CurvesGeometryRuntime>(__func__);
/* Fill the type counts with the default so they're in a valid state. */
@@ -84,15 +86,13 @@ static void copy_curves_geometry(CurvesGeometry &dst, const CurvesGeometry &src)
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, CD_DUPLICATE, dst.curve_num);
MEM_SAFE_FREE(dst.curve_offsets);
- dst.curve_offsets = (int *)MEM_calloc_arrayN(dst.point_num + 1, sizeof(int), __func__);
+ dst.curve_offsets = (int *)MEM_malloc_arrayN(dst.point_num + 1, sizeof(int), __func__);
dst.offsets_for_write().copy_from(src.offsets());
dst.tag_topology_changed();
/* Though type counts are a cache, they must be copied because they are calculated eagerly. */
dst.runtime->type_counts = src.runtime->type_counts;
-
- dst.update_customdata_pointers();
}
CurvesGeometry::CurvesGeometry(const CurvesGeometry &other)
@@ -126,9 +126,6 @@ static void move_curves_geometry(CurvesGeometry &dst, CurvesGeometry &src)
MEM_SAFE_FREE(src.curve_offsets);
std::swap(dst.runtime, src.runtime);
-
- src.update_customdata_pointers();
- dst.update_customdata_pointers();
}
CurvesGeometry::CurvesGeometry(CurvesGeometry &&other)
@@ -302,13 +299,11 @@ void CurvesGeometry::update_curve_types()
Span<float3> CurvesGeometry::positions() const
{
- return {(const float3 *)this->position, this->point_num};
+ return get_span_attribute<float3>(*this, ATTR_DOMAIN_POINT, ATTR_POSITION);
}
MutableSpan<float3> CurvesGeometry::positions_for_write()
{
- this->position = (float(*)[3])CustomData_duplicate_referenced_layer_named(
- &this->point_data, CD_PROP_FLOAT3, ATTR_POSITION.c_str(), this->point_num);
- return {(float3 *)this->position, this->point_num};
+ return get_mutable_attribute<float3>(*this, ATTR_DOMAIN_POINT, ATTR_POSITION);
}
Span<int> CurvesGeometry::offsets() const
@@ -473,8 +468,8 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
VArray<int> resolution = curves.resolution();
VArray<bool> cyclic = curves.cyclic();
- VArray_Span<int8_t> handle_types_left{curves.handle_types_left()};
- VArray_Span<int8_t> handle_types_right{curves.handle_types_right()};
+ VArraySpan<int8_t> handle_types_left{curves.handle_types_left()};
+ VArraySpan<int8_t> handle_types_right{curves.handle_types_right()};
VArray<int8_t> nurbs_orders = curves.nurbs_orders();
VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
@@ -720,8 +715,9 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
}
});
- /* Correct the first and last tangents of Bezier curves so that they align with the inner
- * handles. This is a separate loop to avoid the cost when Bezier type curves are not used. */
+ /* Correct the first and last tangents of non-cyclic Bezier curves so that they align with the
+ * inner handles. This is a separate loop to avoid the cost when Bezier type curves are not
+ * used. */
Vector<int64_t> bezier_indices;
const IndexMask bezier_mask = this->indices_for_curve_type(CURVE_TYPE_BEZIER, bezier_indices);
if (!bezier_mask.is_empty()) {
@@ -731,6 +727,9 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
threading::parallel_for(bezier_mask.index_range(), 1024, [&](IndexRange range) {
for (const int curve_index : bezier_mask.slice(range)) {
+ if (cyclic[curve_index]) {
+ continue;
+ }
const IndexRange points = this->points_for_curve(curve_index);
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
@@ -957,7 +956,6 @@ void CurvesGeometry::resize(const int points_num, const int curves_num)
this->curve_offsets = (int *)MEM_reallocN(this->curve_offsets, sizeof(int) * (curves_num + 1));
}
this->tag_topology_changed();
- this->update_customdata_pointers();
}
void CurvesGeometry::tag_positions_changed()
@@ -1009,8 +1007,8 @@ void CurvesGeometry::calculate_bezier_auto_handles()
return;
}
const VArray<bool> cyclic = this->cyclic();
- const VArray_Span<int8_t> types_left{this->handle_types_left()};
- const VArray_Span<int8_t> types_right{this->handle_types_right()};
+ const VArraySpan<int8_t> types_left{this->handle_types_left()};
+ const VArraySpan<int8_t> types_right{this->handle_types_right()};
const Span<float3> positions = this->positions();
MutableSpan<float3> positions_left = this->handle_positions_left_for_write();
MutableSpan<float3> positions_right = this->handle_positions_right_for_write();
@@ -1056,10 +1054,11 @@ void CurvesGeometry::transform(const float4x4 &matrix)
static std::optional<bounds::MinMaxResult<float3>> curves_bounds(const CurvesGeometry &curves)
{
- Span<float3> positions = curves.positions();
- if (curves.radius) {
- Span<float> radii{curves.radius, curves.points_num()};
- return bounds::min_max_with_radii(positions, radii);
+ const Span<float3> positions = curves.positions();
+ const VArray<float> radii = curves.attributes().lookup_or_default<float>(
+ ATTR_RADIUS, ATTR_DOMAIN_POINT, 0.0f);
+ if (!(radii.is_single() && radii.get_internal_single() == 0.0f)) {
+ return bounds::min_max_with_radii(positions, radii.get_internal_span());
}
return bounds::min_max(positions);
}
@@ -1075,31 +1074,6 @@ bool CurvesGeometry::bounds_min_max(float3 &min, float3 &max) const
return true;
}
-void CurvesGeometry::update_customdata_pointers()
-{
- this->position = (float(*)[3])CustomData_get_layer_named(
- &this->point_data, CD_PROP_FLOAT3, ATTR_POSITION.c_str());
- this->radius = (float *)CustomData_get_layer_named(
- &this->point_data, CD_PROP_FLOAT, ATTR_RADIUS.c_str());
- this->curve_type = (int8_t *)CustomData_get_layer_named(
- &this->point_data, CD_PROP_INT8, ATTR_CURVE_TYPE.c_str());
-}
-
-static void *ensure_customdata_layer(CustomData &custom_data,
- const StringRefNull name,
- const eCustomDataType data_type,
- const int tot_elements)
-{
- for (const int other_layer_i : IndexRange(custom_data.totlayer)) {
- CustomDataLayer &new_layer = custom_data.layers[other_layer_i];
- if (name == StringRef(new_layer.name)) {
- return new_layer.data;
- }
- }
- return CustomData_add_layer_named(
- &custom_data, data_type, CD_DEFAULT, nullptr, tot_elements, name.c_str());
-}
-
static void copy_between_buffers(const CPPType &type,
const void *src_buffer,
void *dst_buffer,
@@ -1193,58 +1167,38 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves,
threading::parallel_invoke(
/* Initialize curve offsets. */
[&]() { new_curves.offsets_for_write().copy_from(new_curve_offsets); },
- /* Copy over point attributes. */
[&]() {
- const CustomData &old_point_data = curves.point_data;
- CustomData &new_point_data = new_curves.point_data;
- for (const int layer_i : IndexRange(old_point_data.totlayer)) {
- const CustomDataLayer &old_layer = old_point_data.layers[layer_i];
- const eCustomDataType data_type = static_cast<eCustomDataType>(old_layer.type);
- const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
- void *dst_buffer = ensure_customdata_layer(
- new_point_data, old_layer.name, data_type, new_point_count);
-
- threading::parallel_for(
- copy_point_ranges.index_range(), 128, [&](const IndexRange ranges_range) {
- for (const int range_i : ranges_range) {
- const IndexRange src_range = copy_point_ranges[range_i];
- copy_between_buffers(type,
- old_layer.data,
- dst_buffer,
- src_range,
- {copy_point_range_dst_offsets[range_i], src_range.size()});
- }
- });
+ /* Copy over point attributes. */
+ for (auto &attribute : bke::retrieve_attributes_for_transfer(
+ curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_POINT)) {
+ threading::parallel_for(copy_point_ranges.index_range(), 128, [&](IndexRange range) {
+ for (const int range_i : range) {
+ const IndexRange src_range = copy_point_ranges[range_i];
+ copy_between_buffers(attribute.src.type(),
+ attribute.src.data(),
+ attribute.dst.span.data(),
+ src_range,
+ {copy_point_range_dst_offsets[range_i], src_range.size()});
+ }
+ });
+ attribute.dst.finish();
}
- },
- /* Copy over curve attributes.
- * In some cases points are just dissolved, so the the number of
- * curves will be the same. That could be optimized in the future. */
- [&]() {
- const CustomData &old_curve_data = curves.curve_data;
- CustomData &new_curve_data = new_curves.curve_data;
- for (const int layer_i : IndexRange(old_curve_data.totlayer)) {
- const CustomDataLayer &old_layer = old_curve_data.layers[layer_i];
- const eCustomDataType data_type = static_cast<eCustomDataType>(old_layer.type);
- const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
- void *dst_buffer = ensure_customdata_layer(
- new_curve_data, old_layer.name, data_type, new_curve_count);
+ /* Copy over curve attributes.
+ * In some cases points are just dissolved, so the the number of
+ * curves will be the same. That could be optimized in the future. */
+ for (auto &attribute : bke::retrieve_attributes_for_transfer(
+ curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_CURVE)) {
if (new_curves.curves_num() == curves.curves_num()) {
- type.copy_construct_n(old_layer.data, dst_buffer, new_curves.curves_num());
+ attribute.dst.span.copy_from(attribute.src);
}
else {
- copy_with_map({type, old_layer.data, curves.curves_num()},
- new_curve_orig_indices,
- {type, dst_buffer, new_curves.curves_num()});
+ copy_with_map(attribute.src, new_curve_orig_indices, attribute.dst.span);
}
+ attribute.dst.finish();
}
});
- new_curves.update_curve_types();
-
return new_curves;
}
@@ -1309,57 +1263,37 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves,
}
});
},
- /* Copy over point attributes. */
[&]() {
- const CustomData &old_point_data = curves.point_data;
- CustomData &new_point_data = new_curves.point_data;
- for (const int layer_i : IndexRange(old_point_data.totlayer)) {
- const CustomDataLayer &old_layer = old_point_data.layers[layer_i];
- const eCustomDataType data_type = static_cast<eCustomDataType>(old_layer.type);
- const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
- void *dst_buffer = ensure_customdata_layer(
- new_point_data, old_layer.name, data_type, new_tot_points);
-
- threading::parallel_for(
- old_curve_ranges.index_range(), 128, [&](const IndexRange ranges_range) {
- for (const int range_i : ranges_range) {
- copy_between_buffers(type,
- old_layer.data,
- dst_buffer,
- old_point_ranges[range_i],
- new_point_ranges[range_i]);
- }
- });
+ /* Copy over point attributes. */
+ for (auto &attribute : bke::retrieve_attributes_for_transfer(
+ curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_POINT)) {
+ threading::parallel_for(old_curve_ranges.index_range(), 128, [&](IndexRange range) {
+ for (const int range_i : range) {
+ copy_between_buffers(attribute.src.type(),
+ attribute.src.data(),
+ attribute.dst.span.data(),
+ old_point_ranges[range_i],
+ new_point_ranges[range_i]);
+ }
+ });
+ attribute.dst.finish();
}
- },
- /* Copy over curve attributes. */
- [&]() {
- const CustomData &old_curve_data = curves.curve_data;
- CustomData &new_curve_data = new_curves.curve_data;
- for (const int layer_i : IndexRange(old_curve_data.totlayer)) {
- const CustomDataLayer &old_layer = old_curve_data.layers[layer_i];
- const eCustomDataType data_type = static_cast<eCustomDataType>(old_layer.type);
- const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
- void *dst_buffer = ensure_customdata_layer(
- new_curve_data, old_layer.name, data_type, new_tot_curves);
-
- threading::parallel_for(
- old_curve_ranges.index_range(), 128, [&](const IndexRange ranges_range) {
- for (const int range_i : ranges_range) {
- copy_between_buffers(type,
- old_layer.data,
- dst_buffer,
- old_curve_ranges[range_i],
- new_curve_ranges[range_i]);
- }
- });
+ /* Copy over curve attributes. */
+ for (auto &attribute : bke::retrieve_attributes_for_transfer(
+ curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_CURVE)) {
+ threading::parallel_for(old_curve_ranges.index_range(), 128, [&](IndexRange range) {
+ for (const int range_i : range) {
+ copy_between_buffers(attribute.src.type(),
+ attribute.src.data(),
+ attribute.dst.span.data(),
+ old_curve_ranges[range_i],
+ new_curve_ranges[range_i]);
+ }
+ });
+ attribute.dst.finish();
}
});
- new_curves.update_curve_types();
-
return new_curves;
}
@@ -1493,7 +1427,6 @@ void CurvesGeometry::remove_attributes_based_on_types()
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);
}
- this->update_customdata_pointers();
}
/** \} */