Files
test/source/blender/blenkernel/intern/curves_utils.cc
Hans Goudey 7507251071 Cleanup: Extract attribute function to copy values from group to group
Use the typical combination of an "array utils" function used by an
attribute interpolation function. This helps moves us towards having
a more centralized implementaiton of attribute propagation that can
be changed and optimized more easily.
2023-10-09 15:23:48 +02:00

75 lines
2.6 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup bke
*/
#include "BKE_curves_utils.hh"
namespace blender::bke::curves {
void fill_points(const OffsetIndices<int> points_by_curve,
const IndexMask &curve_selection,
const GPointer value,
GMutableSpan dst)
{
BLI_assert(*value.type() == dst.type());
const CPPType &type = dst.type();
curve_selection.foreach_index(GrainSize(512), [&](const int i) {
const IndexRange points = points_by_curve[i];
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());
CustomData_copy(
&src_curves.curve_data, &dst_curves.curve_data, CD_MASK_ALL, src_curves.curves_num());
dst_curves.runtime->type_counts = src_curves.runtime->type_counts;
return dst_curves;
}
IndexMask indices_for_type(const VArray<int8_t> &types,
const std::array<int, CURVE_TYPES_NUM> &type_counts,
const CurveType type,
const IndexMask &selection,
IndexMaskMemory &memory)
{
if (type_counts[type] == types.size()) {
return selection;
}
if (types.is_single()) {
return types.get_internal_single() == type ? IndexMask(types.size()) : IndexMask(0);
}
Span<int8_t> types_span = types.get_internal_span();
return IndexMask::from_predicate(selection, GrainSize(4096), memory, [&](const int index) {
return types_span[index] == type;
});
}
void foreach_curve_by_type(const VArray<int8_t> &types,
const std::array<int, CURVE_TYPES_NUM> &counts,
const IndexMask &selection,
FunctionRef<void(IndexMask)> catmull_rom_fn,
FunctionRef<void(IndexMask)> poly_fn,
FunctionRef<void(IndexMask)> bezier_fn,
FunctionRef<void(IndexMask)> nurbs_fn)
{
auto call_if_not_empty = [&](const CurveType type, FunctionRef<void(IndexMask)> fn) {
IndexMaskMemory memory;
const IndexMask mask = indices_for_type(types, counts, type, selection, memory);
if (!mask.is_empty()) {
fn(mask);
}
};
call_if_not_empty(CURVE_TYPE_CATMULL_ROM, catmull_rom_fn);
call_if_not_empty(CURVE_TYPE_POLY, poly_fn);
call_if_not_empty(CURVE_TYPE_BEZIER, bezier_fn);
call_if_not_empty(CURVE_TYPE_NURBS, nurbs_fn);
}
} // namespace blender::bke::curves