101 const int iterable_range_size,
103 : start_(start), end_(end), range_size_(iterable_range_size), cycles_(
cycles)
112 end_(end == iterable_range_size ? 0 : end),
113 range_size_(iterable_range_size),
126 const int iterator_size,
127 const int iterable_range_size)
132 const int num_until_loop = iterable_range_size - start_index;
133 if (iterator_size < num_until_loop) {
134 return IndexRangeCyclic(start_index, start_index + iterator_size, iterable_range_size, 0);
137 const int num_remaining = iterator_size - num_until_loop;
140 const int num_full_cycles = num_remaining / iterable_range_size;
142 const int end_index = num_remaining - num_full_cycles * iterable_range_size;
143 return IndexRangeCyclic(start_index, end_index, iterable_range_size, num_full_cycles + 1);
156 const int iterable_range_size)
159 const int start_index = start_point.
parameter == 0.0 ? start_point.
index :
167 if (end_index == iterable_range_size) {
172 cycles = end_index <= start_index;
175 cycles = end_point < start_point || end_index < start_index;
183 template<
typename IndexT>
constexpr IndexT
next_index(
const IndexT index,
const bool cyclic)
188 return cyclic ? 0 : index;
196 template<
typename IndexT>
constexpr IndexT
previous_index(
const IndexT index,
const bool cyclic)
199 const IndexT prev_index = index - 1;
200 if (prev_index < 0) {
212 return {this->start_, this->end_, this->range_size_, this->cycles_ + n};
222 int new_start = this->start_ - n;
225 const int new_cycles = n / this->
size_range();
226 const int remainder = new_start + this->
size_range() * new_cycles;
227 const bool underflow = remainder < 0;
228 new_start = remainder + (underflow ? this->
size_range() : 0);
229 num_cycles += new_cycles +
int(underflow);
233 (new_start <= this->end_ || (this->end_ == 0 && new_start < this->
size_range())));
234 return {new_start, this->end_, this->range_size_,
num_cycles};
244 int new_end = this->end_ + n;
247 const int new_cycles = n / this->
size_range();
248 const int remainder = new_end - this->
size_range() * new_cycles;
249 const bool overflow = remainder >= this->
size_range();
250 new_end = remainder - (overflow ? this->
size_range() : 0);
251 num_cycles += new_cycles +
int(overflow);
255 return {this->start_, new_end, this->range_size_,
num_cycles};
265 int new_start = this->start_ + n;
268 const int dropped_cycles = n / this->
size_range();
269 const int remainder = new_start - this->
size_range() * dropped_cycles;
270 const bool overflow = remainder >= this->
size_range();
271 new_start = remainder - (overflow ? this->
size_range() : 0);
272 num_cycles -= dropped_cycles +
int(overflow);
276 (new_start <= this->end_ || (this->end_ == 0 && new_start < this->
size_range())));
277 return {new_start, this->end_, this->range_size_,
num_cycles};
287 int new_end = this->end_ - n;
290 const int dropped_cycles = n / this->
size_range();
291 const int remainder = new_end + this->
size_range() * dropped_cycles;
292 const bool underflow = remainder < 0;
293 new_end = remainder + (underflow ? this->
size_range() : 0);
294 num_cycles -= dropped_cycles +
int(underflow);
298 return {this->start_, new_end, this->range_size_,
num_cycles};
330 return this->range_size_;
338 return this->range_size_ - this->start_;
355 if (this->cycles_ > 0) {
356 return this->
size_before_loop() + this->end_ + (this->cycles_ - 1) * this->range_size_;
359 return int(this->end_ - this->start_);
368 return this->cycles_;
379 return int(this->end_ - 1);
389 return this->start_ == other.start_ && this->end_ == other.end_ &&
390 this->cycles_ == other.cycles_ && this->range_size_ == other.range_size_;
397 struct CyclicIterator;
406 return CyclicIterator(this->range_size_, this->end_, this->cycles_);
430 this->range_end_ =
copy.range_end_;
431 this->cycles_ =
copy.cycles_;
437 if (this->index_ == this->range_end_) {
446 for (
int i = 0; i < n; i++) {
458 return this->index_ == other.index_ && this->cycles_ == other.cycles_;
484 fill_points(points_by_curve, curve_selection, &value, dst);
499 const std::array<int, CURVE_TYPES_NUM> &type_counts,
505 const std::array<int, CURVE_TYPES_NUM> &type_counts,
543 return parameter == 0.0 || parameter == 1.0;
548 return (parameter == other.parameter && index == other.index) ||
549 (parameter == 1.0 && other.parameter == 0.0 &&
next_index == other.index) ||
550 (parameter == 0.0 && other.parameter == 1.0 && index == other.next_index);
559 if (index == other.index) {
560 return parameter < other.parameter;
565 !(
next_index == other.index && parameter == 1.0 && other.parameter == 0.0);
Low-level operations for curves.
constexpr CyclicIterator begin() const
constexpr IndexRangeCyclic push_back(const int n=1) const
constexpr IndexRangeCyclic push_loop(const int n=1) const
constexpr IndexRangeCyclic drop_back(const int n=1) const
constexpr int first() const
constexpr IndexRangeCyclic(const int start, const int end, const int iterable_range_size, const int cycles)
constexpr IndexRangeCyclic drop_front(const int n=1) const
constexpr int size_after_loop() const
constexpr IndexT previous_index(const IndexT index, const bool cyclic)
constexpr int size_range() const
constexpr IndexRange curve_range() const
static IndexRangeCyclic get_range_between_endpoints(const CurvePoint start_point, const CurvePoint end_point, const int iterable_range_size)
constexpr int size_before_loop() const
constexpr IndexRangeCyclic push_front(const int n=1) const
constexpr int last() const
constexpr int one_after_last() const
static IndexRangeCyclic get_range_from_size(const int start_index, const int iterator_size, const int iterable_range_size)
~IndexRangeCyclic()=default
constexpr IndexRange range_after_loop() const
constexpr int size() const
constexpr bool operator==(const IndexRangeCyclic &other) const
constexpr bool operator!=(const IndexRangeCyclic &other) const
constexpr CyclicIterator end() const
constexpr IndexRangeCyclic()=default
constexpr IndexRangeCyclic(const int start, const int end, const int iterable_range_size)
constexpr int cycles() const
constexpr IndexT next_index(const IndexT index, const bool cyclic)
constexpr IndexRange range_before_loop() const
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
Array< float3 > retrieve_all_positions(const bke::CurvesGeometry &curves, const IndexMask &curves_selection)
void write_all_positions(bke::CurvesGeometry &curves, const IndexMask &curves_selection, Span< float3 > all_positions)
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_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)
void fill_points(OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, GPointer value, GMutableSpan dst)
void foreach_curve_by_type(const VArray< int8_t > &types, const std::array< int, CURVE_TYPES_NUM > &type_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)
constexpr bool is_same_any_v
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
bool operator==(const CurvePoint &other) const
bool operator!=(const CurvePoint &other) const
bool is_controlpoint() const
bool operator<(const CurvePoint &other) const
constexpr bool operator==(const CyclicIterator &other) const
constexpr CyclicIterator(const int range_end, const int index, const int cycles)
constexpr CyclicIterator & operator++()
constexpr CyclicIterator(const CyclicIterator ©)
void increment(const int n)
constexpr bool operator!=(const CyclicIterator &other) const
~CyclicIterator()=default
constexpr const int & operator*() const
constexpr CyclicIterator & operator=(const CyclicIterator ©)