Blender  V3.3
curves_utils.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "BLI_index_mask_ops.hh"
8 
9 #include "BKE_curves_utils.hh"
10 
11 namespace blender::bke::curves {
12 
14  const Span<IndexRange> curve_ranges,
15  MutableSpan<int> counts)
16 {
17  threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange ranges_range) {
18  for (const IndexRange curves_range : curve_ranges.slice(ranges_range)) {
19  threading::parallel_for(curves_range, 4096, [&](IndexRange range) {
20  for (const int i : range) {
21  counts[i] = curves.points_for_curve(i).size();
22  }
23  });
24  }
25  });
26 }
27 
28 void accumulate_counts_to_offsets(MutableSpan<int> counts_to_offsets, const int start_offset)
29 {
30  int offset = start_offset;
31  for (const int i : counts_to_offsets.index_range().drop_back(1)) {
32  const int count = counts_to_offsets[i];
33  BLI_assert(count > 0);
34  counts_to_offsets[i] = offset;
35  offset += count;
36  }
37  counts_to_offsets.last() = offset;
38 }
39 
40 void copy_point_data(const CurvesGeometry &src_curves,
41  const CurvesGeometry &dst_curves,
42  const Span<IndexRange> curve_ranges,
43  const GSpan src,
44  GMutableSpan dst)
45 {
46  threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) {
47  for (const IndexRange range : curve_ranges.slice(range)) {
48  const IndexRange src_points = src_curves.points_for_curves(range);
49  const IndexRange dst_points = dst_curves.points_for_curves(range);
50  /* The arrays might be large, so a threaded copy might make sense here too. */
51  dst.slice(dst_points).copy_from(src.slice(src_points));
52  }
53  });
54 }
55 
56 void copy_point_data(const CurvesGeometry &src_curves,
57  const CurvesGeometry &dst_curves,
58  const IndexMask src_curve_selection,
59  const GSpan src,
60  GMutableSpan dst)
61 {
62  threading::parallel_for(src_curve_selection.index_range(), 512, [&](IndexRange range) {
63  for (const int i : src_curve_selection.slice(range)) {
64  const IndexRange src_points = src_curves.points_for_curve(i);
65  const IndexRange dst_points = dst_curves.points_for_curve(i);
66  /* The arrays might be large, so a threaded copy might make sense here too. */
67  dst.slice(dst_points).copy_from(src.slice(src_points));
68  }
69  });
70 }
71 
73  const IndexMask curve_selection,
74  const GPointer value,
75  GMutableSpan dst)
76 {
77  BLI_assert(*value.type() == dst.type());
78  const CPPType &type = dst.type();
79  threading::parallel_for(curve_selection.index_range(), 512, [&](IndexRange range) {
80  for (const int i : curve_selection.slice(range)) {
81  const IndexRange points = curves.points_for_curve(i);
82  type.fill_assign_n(value.get(), dst.slice(curves.points_for_curve(i)).data(), points.size());
83  }
84  });
85 }
86 
88 {
89  bke::CurvesGeometry dst_curves(0, src_curves.curves_num());
90  CustomData_copy(&src_curves.curve_data,
91  &dst_curves.curve_data,
94  src_curves.curves_num());
95  dst_curves.runtime->type_counts = src_curves.runtime->type_counts;
96  return dst_curves;
97 }
98 
100  const std::array<int, CURVE_TYPES_NUM> &type_counts,
101  const CurveType type,
102  const IndexMask selection,
103  Vector<int64_t> &r_indices)
104 {
105  if (type_counts[type] == types.size()) {
106  return selection;
107  }
108  if (types.is_single()) {
109  return types.get_internal_single() == type ? IndexMask(types.size()) : IndexMask(0);
110  }
111  Span<int8_t> types_span = types.get_internal_span();
113  selection, 4096, r_indices, [&](const int index) { return types_span[index] == type; });
114 }
115 
117  const std::array<int, CURVE_TYPES_NUM> &counts,
118  const IndexMask selection,
119  FunctionRef<void(IndexMask)> catmull_rom_fn,
120  FunctionRef<void(IndexMask)> poly_fn,
121  FunctionRef<void(IndexMask)> bezier_fn,
122  FunctionRef<void(IndexMask)> nurbs_fn)
123 {
125  auto call_if_not_empty = [&](const CurveType type, FunctionRef<void(IndexMask)> fn) {
126  indices.clear();
127  const IndexMask mask = indices_for_type(types, counts, type, selection, indices);
128  if (!mask.is_empty()) {
129  fn(mask);
130  }
131  };
132  call_if_not_empty(CURVE_TYPE_CATMULL_ROM, catmull_rom_fn);
133  call_if_not_empty(CURVE_TYPE_POLY, poly_fn);
134  call_if_not_empty(CURVE_TYPE_BEZIER, bezier_fn);
135  call_if_not_empty(CURVE_TYPE_NURBS, nurbs_fn);
136 }
137 
138 } // namespace blender::bke::curves
Low-level operations for curves.
@ CD_DUPLICATE
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
#define BLI_assert(a)
Definition: BLI_assert.h:46
CurveType
@ CURVE_TYPE_BEZIER
@ CURVE_TYPE_NURBS
@ CURVE_TYPE_POLY
@ CURVE_TYPE_CATMULL_ROM
#define CD_MASK_ALL
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
const CPPType & type() const
const CPPType * type() const
IndexRange index_range() const
constexpr IndexRange drop_back(int64_t n) const
constexpr T & last(const int64_t n=0) const
Definition: BLI_span.hh:680
constexpr IndexRange index_range() const
Definition: BLI_span.hh:661
constexpr IndexRange index_range() const
Definition: BLI_span.hh:401
SyclQueue void void * src
SyclQueue void void size_t num_bytes void
int count
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_gpu_kernel_postfix int ccl_global int * indices
static char ** types
Definition: makesdna.c:67
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
void fill_curve_counts(const bke::CurvesGeometry &curves, Span< IndexRange > curve_ranges, MutableSpan< int > counts)
Definition: curves_utils.cc:13
IndexMask indices_for_type(const VArray< int8_t > &types, const std::array< int, CURVE_TYPES_NUM > &type_counts, const CurveType type, const IndexMask selection, Vector< int64_t > &r_indices)
Definition: curves_utils.cc:99
void accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
Definition: curves_utils.cc:28
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
Definition: curves_utils.cc:87
void fill_points(const CurvesGeometry &curves, IndexMask curve_selection, GPointer value, GMutableSpan dst)
Definition: curves_utils.cc:72
void copy_point_data(const CurvesGeometry &src_curves, const CurvesGeometry &dst_curves, Span< IndexRange > curve_ranges, GSpan src, GMutableSpan dst)
Definition: curves_utils.cc:40
void foreach_curve_by_type(const VArray< int8_t > &types, const std::array< int, CURVE_TYPES_NUM > &type_counts, IndexMask selection, FunctionRef< void(IndexMask)> catmull_rom_fn, FunctionRef< void(IndexMask)> poly_fn, FunctionRef< void(IndexMask)> bezier_fn, FunctionRef< void(IndexMask)> nurbs_fn)
IndexMask find_indices_based_on_predicate(const IndexMask indices_to_check, const int64_t parallel_grain_size, Vector< int64_t > &r_indices, const Predicate &predicate)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
CurvesGeometryRuntimeHandle * runtime
CustomData curve_data