Curves: Use simpler index mask logic in various places
In several nodes, and sculpt brushes, use the proper `IndexMask` type instead of a span of ranges to encode a selection. This allows deleting the duplicate data copying utilities using the second format.
This commit is contained in:
@@ -473,12 +473,6 @@ class IndexRangeCyclic {
|
||||
* ranges, assuming that all curves have the same number of control points in #src_curves
|
||||
* and #dst_curves.
|
||||
*/
|
||||
void copy_point_data(OffsetIndices<int> src_points_by_curve,
|
||||
OffsetIndices<int> dst_points_by_curve,
|
||||
Span<IndexRange> curve_ranges,
|
||||
GSpan src,
|
||||
GMutableSpan dst);
|
||||
|
||||
void copy_point_data(OffsetIndices<int> src_points_by_curve,
|
||||
OffsetIndices<int> dst_points_by_curve,
|
||||
const IndexMask &src_curve_selection,
|
||||
@@ -513,20 +507,6 @@ void fill_points(const OffsetIndices<int> points_by_curve,
|
||||
fill_points(points_by_curve, curve_selection, &value, dst);
|
||||
}
|
||||
|
||||
void fill_points(const OffsetIndices<int> points_by_curve,
|
||||
Span<IndexRange> curve_ranges,
|
||||
GPointer value,
|
||||
GMutableSpan dst);
|
||||
|
||||
template<typename T>
|
||||
void fill_points(const OffsetIndices<int> points_by_curve,
|
||||
Span<IndexRange> curve_ranges,
|
||||
const T &value,
|
||||
MutableSpan<T> dst)
|
||||
{
|
||||
fill_points(points_by_curve, curve_ranges, &value, dst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new curves with the same number of curves as the input, but no points. Copy all curve
|
||||
* domain attributes to the new curves, except the offsets encoding the size of each curve.
|
||||
@@ -538,14 +518,6 @@ void fill_points(const OffsetIndices<int> points_by_curve,
|
||||
*/
|
||||
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves);
|
||||
|
||||
/**
|
||||
* Copy the number of points in every curve in #curve_ranges to the corresponding index in
|
||||
* #sizes.
|
||||
*/
|
||||
void copy_curve_sizes(OffsetIndices<int> points_by_curve,
|
||||
Span<IndexRange> curve_ranges,
|
||||
MutableSpan<int> sizes);
|
||||
|
||||
IndexMask indices_for_type(const VArray<int8_t> &types,
|
||||
const std::array<int, CURVE_TYPES_NUM> &type_counts,
|
||||
const CurveType type,
|
||||
|
||||
@@ -8,37 +8,6 @@
|
||||
|
||||
namespace blender::bke::curves {
|
||||
|
||||
void copy_curve_sizes(const OffsetIndices<int> points_by_curve,
|
||||
const Span<IndexRange> curve_ranges,
|
||||
MutableSpan<int> sizes)
|
||||
{
|
||||
threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange ranges_range) {
|
||||
for (const IndexRange curves_range : curve_ranges.slice(ranges_range)) {
|
||||
threading::parallel_for(curves_range, 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
sizes[i] = points_by_curve[i].size();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void copy_point_data(const OffsetIndices<int> src_points_by_curve,
|
||||
const OffsetIndices<int> dst_points_by_curve,
|
||||
const Span<IndexRange> curve_ranges,
|
||||
const GSpan src,
|
||||
GMutableSpan dst)
|
||||
{
|
||||
threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) {
|
||||
for (const IndexRange range : curve_ranges.slice(range)) {
|
||||
const IndexRange src_points = src_points_by_curve[range];
|
||||
const IndexRange dst_points = dst_points_by_curve[range];
|
||||
/* The arrays might be large, so a threaded copy might make sense here too. */
|
||||
dst.slice(dst_points).copy_from(src.slice(src_points));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void copy_point_data(const OffsetIndices<int> src_points_by_curve,
|
||||
const OffsetIndices<int> dst_points_by_curve,
|
||||
const IndexMask &src_curve_selection,
|
||||
@@ -66,21 +35,6 @@ void fill_points(const OffsetIndices<int> points_by_curve,
|
||||
});
|
||||
}
|
||||
|
||||
void fill_points(const OffsetIndices<int> points_by_curve,
|
||||
Span<IndexRange> curve_ranges,
|
||||
GPointer value,
|
||||
GMutableSpan dst)
|
||||
{
|
||||
BLI_assert(*value.type() == dst.type());
|
||||
const CPPType &type = dst.type();
|
||||
threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) {
|
||||
for (const IndexRange range : curve_ranges.slice(range)) {
|
||||
const IndexRange points = points_by_curve[range];
|
||||
type.fill_assign_n(value.get(), dst.slice(points).data(), points.size());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
|
||||
{
|
||||
bke::CurvesGeometry dst_curves(0, src_curves.curves_num());
|
||||
|
||||
@@ -131,14 +131,14 @@ struct DeleteOperationExecutor {
|
||||
const IndexMask mask_to_delete = IndexMask::from_bools(curves_to_delete, mask_memory);
|
||||
|
||||
/* Remove deleted curves from the stored deformed positions. */
|
||||
const Vector<IndexRange> ranges_to_keep = mask_to_delete.to_ranges_invert(
|
||||
curves_->curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask mask_to_keep = mask_to_delete.complement(curves_->curves_range(), memory);
|
||||
const OffsetIndices points_by_curve = curves_->points_by_curve();
|
||||
Vector<float3> new_deformed_positions;
|
||||
for (const IndexRange curves_range : ranges_to_keep) {
|
||||
mask_to_keep.foreach_index([&](const int64_t i) {
|
||||
new_deformed_positions.extend(
|
||||
self_->deformed_positions_.as_span().slice(points_by_curve[curves_range]));
|
||||
}
|
||||
self_->deformed_positions_.as_span().slice(points_by_curve[i]));
|
||||
});
|
||||
self_->deformed_positions_ = std::move(new_deformed_positions);
|
||||
|
||||
curves_->remove_curves(mask_to_delete);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "BLI_array_utils.hh"
|
||||
#include "BLI_enumerable_thread_specific.hh"
|
||||
#include "BLI_kdtree.h"
|
||||
#include "BLI_rand.hh"
|
||||
@@ -607,13 +608,13 @@ struct DensitySubtractOperationExecutor {
|
||||
const IndexMask mask_to_delete = IndexMask::from_bools(curves_to_delete, mask_memory);
|
||||
|
||||
/* Remove deleted curves from the stored deformed root positions. */
|
||||
const Vector<IndexRange> ranges_to_keep = mask_to_delete.to_ranges_invert(
|
||||
curves_->curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask mask_to_keep = mask_to_delete.complement(curves_->curves_range(), memory);
|
||||
BLI_assert(curves_->curves_num() == self_->deformed_root_positions_.size());
|
||||
Vector<float3> new_deformed_positions;
|
||||
for (const IndexRange range : ranges_to_keep) {
|
||||
new_deformed_positions.extend(self_->deformed_root_positions_.as_span().slice(range));
|
||||
}
|
||||
Vector<float3> new_deformed_positions(mask_to_keep.size());
|
||||
array_utils::gather(self_->deformed_root_positions_.as_span(),
|
||||
mask_to_keep,
|
||||
new_deformed_positions.as_mutable_span());
|
||||
self_->deformed_root_positions_ = std::move(new_deformed_positions);
|
||||
|
||||
curves_->remove_curves(mask_to_delete);
|
||||
|
||||
@@ -63,7 +63,7 @@ static void duplicate_fillet_point_data(const OffsetIndices<int> src_points_by_c
|
||||
|
||||
static void calculate_result_offsets(const OffsetIndices<int> src_points_by_curve,
|
||||
const IndexMask &selection,
|
||||
const Span<IndexRange> unselected_ranges,
|
||||
const IndexMask &unselected,
|
||||
const VArray<float> &radii,
|
||||
const VArray<int> &counts,
|
||||
const Span<bool> cyclic,
|
||||
@@ -71,7 +71,7 @@ static void calculate_result_offsets(const OffsetIndices<int> src_points_by_curv
|
||||
MutableSpan<int> dst_point_offsets)
|
||||
{
|
||||
/* Fill the offsets array with the curve point counts, then accumulate them to form offsets. */
|
||||
bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_curve_offsets);
|
||||
offset_indices::copy_group_sizes(src_points_by_curve, unselected, dst_curve_offsets);
|
||||
selection.foreach_index(GrainSize(512), [&](const int curve_i) {
|
||||
const IndexRange src_points = src_points_by_curve[curve_i];
|
||||
const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points,
|
||||
@@ -404,8 +404,8 @@ static bke::CurvesGeometry fillet_curves(
|
||||
const Span<float3> positions = src_curves.positions();
|
||||
const VArraySpan<bool> cyclic{src_curves.cyclic()};
|
||||
const bke::AttributeAccessor src_attributes = src_curves.attributes();
|
||||
const Vector<IndexRange> unselected_ranges = curve_selection.to_ranges_invert(
|
||||
src_curves.curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask unselected = curve_selection.complement(src_curves.curves_range(), memory);
|
||||
|
||||
bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves);
|
||||
/* Stores the offset of every result point for every original point.
|
||||
@@ -413,7 +413,7 @@ static bke::CurvesGeometry fillet_curves(
|
||||
Array<int> dst_point_offsets(src_curves.points_num() + src_curves.curves_num());
|
||||
calculate_result_offsets(src_points_by_curve,
|
||||
curve_selection,
|
||||
unselected_ranges,
|
||||
unselected,
|
||||
radius_input,
|
||||
counts,
|
||||
cyclic,
|
||||
@@ -531,15 +531,12 @@ static bke::CurvesGeometry fillet_curves(
|
||||
attribute.dst.finish();
|
||||
}
|
||||
|
||||
if (!unselected_ranges.is_empty()) {
|
||||
if (!unselected.is_empty()) {
|
||||
for (auto &attribute : bke::retrieve_attributes_for_transfer(
|
||||
src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info))
|
||||
{
|
||||
bke::curves::copy_point_data(src_points_by_curve,
|
||||
dst_points_by_curve,
|
||||
unselected_ranges,
|
||||
attribute.src,
|
||||
attribute.dst.span);
|
||||
bke::curves::copy_point_data(
|
||||
src_points_by_curve, dst_points_by_curve, unselected, attribute.src, attribute.dst.span);
|
||||
attribute.dst.finish();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ static void gather_point_attributes_to_interpolate(
|
||||
}
|
||||
|
||||
static void copy_or_defaults_for_unselected_curves(const CurvesGeometry &src_curves,
|
||||
const Span<IndexRange> unselected_ranges,
|
||||
const IndexMask &unselected_curves,
|
||||
const AttributesForInterpolation &attributes,
|
||||
CurvesGeometry &dst_curves)
|
||||
{
|
||||
@@ -194,32 +194,32 @@ static void copy_or_defaults_for_unselected_curves(const CurvesGeometry &src_cur
|
||||
const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve();
|
||||
bke::curves::copy_point_data(src_points_by_curve,
|
||||
dst_points_by_curve,
|
||||
unselected_ranges,
|
||||
unselected_curves,
|
||||
src_curves.positions(),
|
||||
dst_curves.positions_for_write());
|
||||
|
||||
for (const int i : attributes.src.index_range()) {
|
||||
bke::curves::copy_point_data(src_points_by_curve,
|
||||
dst_points_by_curve,
|
||||
unselected_ranges,
|
||||
unselected_curves,
|
||||
attributes.src[i],
|
||||
attributes.dst[i]);
|
||||
}
|
||||
for (const int i : attributes.src_no_interpolation.index_range()) {
|
||||
bke::curves::copy_point_data(src_points_by_curve,
|
||||
dst_points_by_curve,
|
||||
unselected_ranges,
|
||||
unselected_curves,
|
||||
attributes.src_no_interpolation[i],
|
||||
attributes.dst_no_interpolation[i]);
|
||||
}
|
||||
|
||||
if (!attributes.dst_tangents.is_empty()) {
|
||||
bke::curves::fill_points(
|
||||
dst_points_by_curve, unselected_ranges, float3(0), attributes.dst_tangents);
|
||||
dst_points_by_curve, unselected_curves, float3(0), attributes.dst_tangents);
|
||||
}
|
||||
if (!attributes.dst_normals.is_empty()) {
|
||||
bke::curves::fill_points(
|
||||
dst_points_by_curve, unselected_ranges, float3(0), attributes.dst_normals);
|
||||
dst_points_by_curve, unselected_curves, float3(0), attributes.dst_normals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,11 +259,11 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
|
||||
evaluator.add_with_destination(count_field, dst_offsets.drop_back(1));
|
||||
evaluator.evaluate();
|
||||
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
|
||||
const Vector<IndexRange> unselected_ranges = selection.to_ranges_invert(
|
||||
src_curves.curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask unselected = selection.complement(src_curves.curves_range(), memory);
|
||||
|
||||
/* Fill the counts for the curves that aren't selected and accumulate the counts into offsets. */
|
||||
bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_offsets);
|
||||
offset_indices::copy_group_sizes(src_points_by_curve, unselected, dst_offsets);
|
||||
offset_indices::accumulate_counts_to_offsets(dst_offsets);
|
||||
dst_curves.resize(dst_offsets.last(), dst_curves.curves_num());
|
||||
|
||||
@@ -376,7 +376,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
|
||||
}
|
||||
});
|
||||
|
||||
copy_or_defaults_for_unselected_curves(src_curves, unselected_ranges, attributes, dst_curves);
|
||||
copy_or_defaults_for_unselected_curves(src_curves, unselected, attributes, dst_curves);
|
||||
|
||||
for (bke::GSpanAttributeWriter &attribute : attributes.dst_attributes) {
|
||||
attribute.finish();
|
||||
@@ -416,14 +416,14 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
|
||||
evaluator.set_selection(selection_field);
|
||||
evaluator.evaluate();
|
||||
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
|
||||
const Vector<IndexRange> unselected_ranges = selection.to_ranges_invert(
|
||||
src_curves.curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask unselected = selection.complement(src_curves.curves_range(), memory);
|
||||
|
||||
CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves);
|
||||
dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY);
|
||||
MutableSpan<int> dst_offsets = dst_curves.offsets_for_write();
|
||||
offset_indices::copy_group_sizes(src_evaluated_points_by_curve, selection, dst_offsets);
|
||||
bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_offsets);
|
||||
offset_indices::copy_group_sizes(src_points_by_curve, unselected, dst_offsets);
|
||||
offset_indices::accumulate_counts_to_offsets(dst_offsets);
|
||||
const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve();
|
||||
|
||||
@@ -482,7 +482,7 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
|
||||
}
|
||||
});
|
||||
|
||||
copy_or_defaults_for_unselected_curves(src_curves, unselected_ranges, attributes, dst_curves);
|
||||
copy_or_defaults_for_unselected_curves(src_curves, unselected, attributes, dst_curves);
|
||||
|
||||
for (bke::GSpanAttributeWriter &attribute : attributes.dst_attributes) {
|
||||
attribute.finish();
|
||||
|
||||
@@ -288,14 +288,14 @@ static bke::CurvesGeometry convert_curves_to_bezier(
|
||||
const VArray<bool> src_cyclic = src_curves.cyclic();
|
||||
const Span<float3> src_positions = src_curves.positions();
|
||||
const bke::AttributeAccessor src_attributes = src_curves.attributes();
|
||||
const Vector<IndexRange> unselected_ranges = selection.to_ranges_invert(
|
||||
src_curves.curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask unselected = selection.complement(src_curves.curves_range(), memory);
|
||||
|
||||
bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves);
|
||||
dst_curves.fill_curve_types(selection, CURVE_TYPE_BEZIER);
|
||||
|
||||
MutableSpan<int> dst_offsets = dst_curves.offsets_for_write();
|
||||
bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_offsets);
|
||||
offset_indices::copy_group_sizes(src_points_by_curve, unselected, dst_offsets);
|
||||
selection.foreach_index(GrainSize(1024), [&](const int i) {
|
||||
dst_offsets[i] = to_bezier_size(CurveType(src_types[i]),
|
||||
src_cyclic[i],
|
||||
@@ -447,11 +447,8 @@ static bke::CurvesGeometry convert_curves_to_bezier(
|
||||
nurbs_to_bezier);
|
||||
|
||||
for (bke::AttributeTransferData &attribute : generic_attributes) {
|
||||
bke::curves::copy_point_data(src_points_by_curve,
|
||||
dst_points_by_curve,
|
||||
unselected_ranges,
|
||||
attribute.src,
|
||||
attribute.dst.span);
|
||||
bke::curves::copy_point_data(
|
||||
src_points_by_curve, dst_points_by_curve, unselected, attribute.src, attribute.dst.span);
|
||||
}
|
||||
|
||||
for (bke::AttributeTransferData &attribute : generic_attributes) {
|
||||
@@ -471,14 +468,14 @@ static bke::CurvesGeometry convert_curves_to_nurbs(
|
||||
const VArray<bool> src_cyclic = src_curves.cyclic();
|
||||
const Span<float3> src_positions = src_curves.positions();
|
||||
const bke::AttributeAccessor src_attributes = src_curves.attributes();
|
||||
const Vector<IndexRange> unselected_ranges = selection.to_ranges_invert(
|
||||
src_curves.curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask unselected = selection.complement(src_curves.curves_range(), memory);
|
||||
|
||||
bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves);
|
||||
dst_curves.fill_curve_types(selection, CURVE_TYPE_NURBS);
|
||||
|
||||
MutableSpan<int> dst_offsets = dst_curves.offsets_for_write();
|
||||
bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_offsets);
|
||||
offset_indices::copy_group_sizes(src_points_by_curve, unselected, dst_offsets);
|
||||
selection.foreach_index(GrainSize(1024), [&](const int i) {
|
||||
dst_offsets[i] = to_nurbs_size(CurveType(src_types[i]), src_points_by_curve[i].size());
|
||||
});
|
||||
@@ -615,11 +612,8 @@ static bke::CurvesGeometry convert_curves_to_nurbs(
|
||||
nurbs_to_nurbs);
|
||||
|
||||
for (bke::AttributeTransferData &attribute : generic_attributes) {
|
||||
bke::curves::copy_point_data(src_points_by_curve,
|
||||
dst_points_by_curve,
|
||||
unselected_ranges,
|
||||
attribute.src,
|
||||
attribute.dst.span);
|
||||
bke::curves::copy_point_data(
|
||||
src_points_by_curve, dst_points_by_curve, unselected, attribute.src, attribute.dst.span);
|
||||
}
|
||||
|
||||
for (bke::AttributeTransferData &attribute : generic_attributes) {
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace blender::geometry {
|
||||
|
||||
static void calculate_result_offsets(const bke::CurvesGeometry &src_curves,
|
||||
const IndexMask &selection,
|
||||
const Span<IndexRange> unselected_ranges,
|
||||
const IndexMask &unselected,
|
||||
const VArray<int> &cuts,
|
||||
const Span<bool> cyclic,
|
||||
MutableSpan<int> dst_curve_offsets,
|
||||
@@ -21,7 +21,7 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves,
|
||||
{
|
||||
/* Fill the array with each curve's point count, then accumulate them to the offsets. */
|
||||
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
|
||||
bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_curve_offsets);
|
||||
offset_indices::copy_group_sizes(src_points_by_curve, unselected, dst_curve_offsets);
|
||||
selection.foreach_index(GrainSize(1024), [&](const int curve_i) {
|
||||
const IndexRange src_points = src_points_by_curve[curve_i];
|
||||
const IndexRange src_segments = bke::curves::per_curve_point_offsets_range(src_points,
|
||||
@@ -276,8 +276,8 @@ bke::CurvesGeometry subdivide_curves(
|
||||
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
|
||||
/* Cyclic is accessed a lot, it's probably worth it to make sure it's a span. */
|
||||
const VArraySpan<bool> cyclic{src_curves.cyclic()};
|
||||
const Vector<IndexRange> unselected_ranges = selection.to_ranges_invert(
|
||||
src_curves.curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask unselected = selection.complement(src_curves.curves_range(), memory);
|
||||
|
||||
bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves);
|
||||
|
||||
@@ -299,7 +299,7 @@ bke::CurvesGeometry subdivide_curves(
|
||||
#endif
|
||||
calculate_result_offsets(src_curves,
|
||||
selection,
|
||||
unselected_ranges,
|
||||
unselected,
|
||||
cuts,
|
||||
cyclic,
|
||||
dst_curves.offsets_for_write(),
|
||||
@@ -404,15 +404,12 @@ bke::CurvesGeometry subdivide_curves(
|
||||
subdivide_bezier,
|
||||
subdivide_nurbs);
|
||||
|
||||
if (!unselected_ranges.is_empty()) {
|
||||
if (!unselected.is_empty()) {
|
||||
for (auto &attribute : bke::retrieve_attributes_for_transfer(
|
||||
src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info))
|
||||
{
|
||||
bke::curves::copy_point_data(src_points_by_curve,
|
||||
dst_points_by_curve,
|
||||
unselected_ranges,
|
||||
attribute.src,
|
||||
attribute.dst.span);
|
||||
bke::curves::copy_point_data(
|
||||
src_points_by_curve, dst_points_by_curve, unselected, attribute.src, attribute.dst.span);
|
||||
attribute.dst.finish();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -937,8 +937,8 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
|
||||
const bke::AnonymousAttributePropagationInfo &propagation_info)
|
||||
{
|
||||
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
|
||||
const Vector<IndexRange> unselected_ranges = selection.to_ranges_invert(
|
||||
src_curves.curves_range());
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask unselected = selection.complement(src_curves.curves_range(), memory);
|
||||
|
||||
BLI_assert(selection.size() > 0);
|
||||
BLI_assert(selection.last() <= src_curves.curves_num());
|
||||
@@ -960,7 +960,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
|
||||
start_points,
|
||||
end_points,
|
||||
src_ranges);
|
||||
bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_curve_offsets);
|
||||
offset_indices::copy_group_sizes(src_points_by_curve, unselected, dst_curve_offsets);
|
||||
offset_indices::accumulate_counts_to_offsets(dst_curve_offsets);
|
||||
const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve();
|
||||
dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num());
|
||||
@@ -1043,7 +1043,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
|
||||
}
|
||||
|
||||
/* Copy unselected */
|
||||
if (unselected_ranges.is_empty()) {
|
||||
if (unselected.is_empty()) {
|
||||
/* Since all curves were trimmed, none of them are cyclic and the attribute can be removed. */
|
||||
dst_curves.attributes_for_write().remove("cyclic");
|
||||
}
|
||||
@@ -1068,11 +1068,8 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
|
||||
propagation_info,
|
||||
copy_point_skip))
|
||||
{
|
||||
bke::curves::copy_point_data(src_points_by_curve,
|
||||
dst_points_by_curve,
|
||||
unselected_ranges,
|
||||
attribute.src,
|
||||
attribute.dst.span);
|
||||
bke::curves::copy_point_data(
|
||||
src_points_by_curve, dst_points_by_curve, unselected, attribute.src, attribute.dst.span);
|
||||
attribute.dst.finish();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user