21 return {curve_index + points.
start(), points.
size() + 1};
35 for (const int curve_i : selection.slice(range)) {
36 const IndexRange src_points = src_curves.points_for_curve(curve_i);
37 const IndexRange src_segments = curve_dst_offsets(src_points, curve_i);
39 MutableSpan<int> point_offsets = dst_point_offsets.slice(src_segments);
40 MutableSpan<int> point_counts = point_offsets.drop_back(1);
42 if (src_points.size() == 1) {
43 point_counts.first() = 1;
46 cuts.materialize_compressed(src_points, point_counts);
47 for (int &count : point_counts) {
49 count = std::max(count, 0) + 1;
51 if (!cyclic[curve_i]) {
53 point_counts.last() = 1;
57 bke::curves::accumulate_counts_to_offsets(point_offsets);
58 dst_curve_offsets[curve_i] = point_offsets.last();
68 const float step = 1.0f / dst.
size();
83 for (const int curve_i : selection.slice(selection_range)) {
84 const IndexRange src_points = src_curves.points_for_curve(curve_i);
85 const IndexRange src_segments = curve_dst_offsets(src_points, curve_i);
86 const Span<int> offsets = point_offsets.slice(src_segments);
88 const IndexRange dst_points = dst_curves.points_for_curve(curve_i);
89 const Span<T> curve_src = src.slice(src_points);
90 MutableSpan<T> curve_dst = dst.slice(dst_points);
92 threading::parallel_for(curve_src.index_range().drop_back(1), 1024, [&](IndexRange range) {
93 for (const int i : range) {
94 const IndexRange segment_points = bke::offsets_to_range(offsets, i);
95 linear_interpolation(curve_src[i], curve_src[i + 1], curve_dst.slice(segment_points));
99 const IndexRange dst_last_segment = dst_points.slice(
100 bke::offsets_to_range(offsets, src_points.size() - 1));
101 linear_interpolation(curve_src.last(), curve_src.first(), dst.slice(dst_last_segment));
114 using T = decltype(dummy);
115 subdivide_attribute_linear(
116 src_curves, dst_curves, selection, point_offsets, src.typed<T>(), dst.typed<T>());
130 for (const int curve_i : selection.slice(selection_range)) {
131 const IndexRange src_points = src_curves.points_for_curve(curve_i);
132 const IndexRange src_segments = curve_dst_offsets(src_points, curve_i);
133 const IndexRange dst_points = dst_curves.points_for_curve(curve_i);
135 bke::curves::catmull_rom::interpolate_to_evaluated(src.slice(src_points),
137 point_offsets.slice(src_segments),
138 dst.slice(dst_points));
152 using T = decltype(dummy);
153 subdivide_attribute_catmull_rom(
154 src_curves, dst_curves, selection, point_offsets, cyclic, src.typed<T>(), dst.typed<T>());
159 const float3 &handle_prev,
160 const float3 &handle_next,
161 const float3 &position_next,
170 const bool is_last_cyclic_segment)
185 dst_positions[segment_points.
first()] = position_prev;
195 float3 segment_start = position_prev;
196 float3 segment_handle_prev = handle_prev;
197 float3 segment_handle_next = handle_next;
198 const float3 segment_end = position_next;
201 const float parameter = 1.0f / (segment_points.
size() - i);
202 const int point_i = segment_points[i];
204 segment_start, segment_handle_prev, segment_handle_next, segment_end, parameter);
218 const int i_segment_last = is_last_cyclic_segment ? 0 : segment_points.
one_after_last();
219 dst_handles_r[segment_points.
last()] = segment_handle_prev;
220 dst_handles_l[i_segment_last] = segment_handle_next;
238 for (const int segment_i : range) {
239 const IndexRange segment = bke::offsets_to_range(evaluated_offsets, segment_i);
240 subdivide_bezier_segment(src_positions[segment_i],
241 src_handles_r[segment_i],
242 src_handles_l[segment_i + 1],
243 src_positions[segment_i + 1],
244 HandleType(src_types_r[segment_i]),
245 HandleType(src_types_l[segment_i + 1]),
257 const int last_index = src_positions.index_range().last();
262 src_handles_r.last(),
263 src_handles_l.first(),
264 src_positions.first(),
285 dst_positions.last() = src_positions.last();
286 dst_types_l.first() = src_types_l.first();
287 dst_types_r.last() = src_types_r.last();
288 dst_handles_l.first() = src_handles_l.first();
289 dst_handles_r.last() = src_handles_r.last();
294 cyclic, dst_types_l, dst_types_r, dst_positions, dst_handles_l, dst_handles_r);
323 dst_point_offsets.
fill(-1);
339 auto subdivide_catmull_rom = [&](
IndexMask selection) {
353 auto subdivide_poly = [&](
IndexMask selection) {
362 auto subdivide_bezier = [&](
IndexMask selection) {
376 for (const int curve_i : selection.slice(range)) {
377 const IndexRange src_points = src_curves.points_for_curve(curve_i);
378 const IndexRange src_segments = curve_dst_offsets(src_points, curve_i);
380 const IndexRange dst_points = dst_curves.points_for_curve(curve_i);
381 subdivide_bezier_positions(src_positions.slice(src_points),
382 src_types_l.slice(src_points),
383 src_types_r.slice(src_points),
384 src_handles_l.slice(src_points),
385 src_handles_r.slice(src_points),
386 point_offsets.slice(src_segments),
388 dst_positions.slice(dst_points),
389 dst_types_l.slice(dst_points),
390 dst_types_r.slice(dst_points),
391 dst_handles_l.slice(dst_points),
392 dst_handles_r.slice(dst_points));
412 auto subdivide_nurbs = subdivide_poly;
415 src_curves.curve_type_counts(),
417 subdivide_catmull_rom,
422 if (!unselected_ranges.is_empty()) {
Low-level operations for curves.
Low-level operations for curves.
_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
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
Span< T > as_span() const
void fill(const T &value) const
const CPPType & type() const
Vector< IndexRange > extract_ranges_invert(const IndexRange full_range, Vector< int64_t > *r_skip_amounts=nullptr) const
IndexRange index_range() const
constexpr int64_t first() const
constexpr int64_t one_after_last() const
constexpr IndexRange shift(int64_t n) const
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr int64_t start() const
constexpr IndexRange drop_front(int64_t n) const
constexpr int64_t size() const
constexpr void fill(const T &value)
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr IndexRange index_range() const
constexpr T & first() const
constexpr const T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
VArray< int8_t > handle_types_left() const
MutableSpan< float3 > positions_for_write()
MutableSpan< int8_t > handle_types_right_for_write()
VArray< int8_t > handle_types_right() const
IndexRange curves_range() const
MutableSpan< float3 > handle_positions_left_for_write()
MutableAttributeAccessor attributes_for_write()
MutableSpan< float3 > handle_positions_right_for_write()
Span< float3 > handle_positions_left() const
Span< int > offsets() const
Span< float3 > positions() const
void resize(int points_num, int curves_num)
Span< float3 > handle_positions_right() const
AttributeAccessor attributes() const
MutableSpan< int > offsets_for_write()
VArray< bool > cyclic() const
MutableSpan< int8_t > handle_types_left_for_write()
SyclQueue void void * src
Segment< FEdge *, Vec3r > segment
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
T mix2(float factor, const T &a, const T &b)
Insertion insert(const float3 &point_prev, const float3 &handle_prev, const float3 &handle_next, const float3 &point_next, float parameter)
bool segment_is_vector(const HandleType left, const HandleType right)
void calculate_auto_handles(bool cyclic, Span< int8_t > types_left, Span< int8_t > types_right, Span< float3 > positions, MutableSpan< float3 > positions_left, MutableSpan< float3 > positions_right)
void fill_curve_counts(const bke::CurvesGeometry &curves, Span< IndexRange > curve_ranges, MutableSpan< int > counts)
void accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
void copy_point_data(const CurvesGeometry &src_curves, const CurvesGeometry &dst_curves, Span< IndexRange > curve_ranges, GSpan src, GMutableSpan dst)
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)
Vector< AttributeTransferData > retrieve_attributes_for_transfer(const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes, eAttrDomainMask domain_mask, const Set< std::string > &skip={})
constexpr IndexRange offsets_to_range(Span< T > offsets, int64_t index)
static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, const IndexMask selection, const Span< IndexRange > unselected_ranges, const VArray< int > &cuts, const Span< bool > cyclic, MutableSpan< int > dst_curve_offsets, MutableSpan< int > dst_point_offsets)
static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, const IndexMask selection, const Span< IndexRange > unselected_ranges, const VArray< float > &radii, const VArray< int > &counts, const Span< bool > cyclic, MutableSpan< int > dst_curve_offsets, MutableSpan< int > dst_point_offsets)
static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curves, const bke::CurvesGeometry &dst_curves, const IndexMask selection, const Span< int > point_offsets, const Span< bool > cyclic, const GSpan src, GMutableSpan dst)
static IndexRange curve_dst_offsets(const IndexRange points, const int curve_index)
static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, const bke::CurvesGeometry &dst_curves, const IndexMask selection, const Span< int > point_offsets, const GSpan src, GMutableSpan dst)
static void linear_interpolation(const T &a, const T &b, MutableSpan< T > dst)
static void subdivide_bezier_segment(const float3 &position_prev, const float3 &handle_prev, const float3 &handle_next, const float3 &position_next, const HandleType type_prev, const HandleType type_next, const IndexRange segment_points, MutableSpan< float3 > dst_positions, MutableSpan< float3 > dst_handles_l, MutableSpan< float3 > dst_handles_r, MutableSpan< int8_t > dst_types_l, MutableSpan< int8_t > dst_types_r, const bool is_last_cyclic_segment)
static void subdivide_bezier_positions(const Span< float3 > src_positions, const Span< int8_t > src_types_l, const Span< int8_t > src_types_r, const Span< float3 > src_handles_l, const Span< float3 > src_handles_r, const Span< int > evaluated_offsets, const bool cyclic, MutableSpan< float3 > dst_positions, MutableSpan< int8_t > dst_types_l, MutableSpan< int8_t > dst_types_r, MutableSpan< float3 > dst_handles_l, MutableSpan< float3 > dst_handles_r)
bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, IndexMask selection, const VArray< int > &cuts)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)