Blender V4.3
CurveAdvancedIterators.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
12#include "CurveIterators.h"
13#include "Stroke.h"
14
15namespace Freestyle {
16
17namespace CurveInternal {
18
19class CurvePoint_const_traits : public Const_traits<CurvePoint *> {
20 public:
21 typedef deque<CurvePoint *> vertex_container;
22 typedef vertex_container::const_iterator vertex_container_iterator;
24};
25
26class CurvePoint_nonconst_traits : public Nonconst_traits<CurvePoint *> {
27 public:
28 typedef deque<CurvePoint *> vertex_container;
29 typedef vertex_container::iterator vertex_container_iterator;
31};
32
33/**********************************/
34/* */
35/* */
36/* CurvePoint Iterator */
37/* */
38/* */
39/**********************************/
40
44template<class Traits>
45class __point_iterator : public IteratorBase<Traits, BidirectionalIteratorTag_Traits> {
46 public:
48 typedef typename Traits::vertex_container_iterator vertex_container_iterator;
49 typedef typename Traits::vertex_type vertex_type;
52
55
56#if 0
57 typedef Vertex vertex_type;
58 typedef vertex_container_iterator vertex_iterator_type;
60 typedef Point point_type;
61#endif
63#if 0
64# if defined(__GNUC__) && (__GNUC__ < 3)
65 typedef bidirectional_iterator<CurvePoint<Vertex>, ptrdiff_t> bidirectional_point_iterator;
66# else
68 bidirectional_point_iterator;
69# endif
70#endif
71 friend class Curve;
72#if 0
73 friend class Curve::vertex_iterator;
75 friend class iterator;
76#endif
77 // protected:
78 public:
80 float _step;
85 int _n;
87 float _t;
88 mutable Point *_Point;
89
90 public:
91 inline __point_iterator(float step = 0.0f) : parent_class()
92 {
93 _step = step;
94 _CurvilinearLength = 0.0f;
95 _t = 0.0f;
96 _Point = 0;
97 _n = 0;
98 _currentn = 0;
99 }
100
101 inline __point_iterator(const iterator &iBrother) : parent_class()
102 {
103 __A = iBrother.__A;
104 __B = iBrother.__B;
105 _begin = iBrother._begin;
106 _end = iBrother._end;
108 _step = iBrother._step;
109 _t = iBrother._t;
110 if (iBrother._Point == 0) {
111 _Point = 0;
112 }
113 else {
114 _Point = new Point(*(iBrother._Point));
115 }
116 _n = iBrother._n;
117 _currentn = iBrother._currentn;
118 }
119
120 inline __point_iterator(const const_iterator &iBrother) : parent_class()
121 {
122 __A = iBrother.__A;
123 __B = iBrother.__B;
124 _begin = iBrother._begin;
125 _end = iBrother._end;
127 _step = iBrother._step;
128 _t = iBrother._t;
129 if (iBrother._Point == 0) {
130 _Point = 0;
131 }
132 else {
133 _Point = new Point(*(iBrother._Point));
134 }
135 _n = iBrother._n;
136 _currentn = iBrother._currentn;
137 }
138
139 inline Self &operator=(const Self &iBrother)
140 {
141 //((bidirectional_point_iterator*)this)->operator=(iBrother);
142 __A = iBrother.__A;
143 __B = iBrother.__B;
144 _begin = iBrother._begin;
145 _end = iBrother._end;
147 _step = iBrother._step;
148 _t = iBrother._t;
149 if (iBrother._Point == 0) {
150 _Point = 0;
151 }
152 else {
153 _Point = new Point(*(iBrother._Point));
154 }
155 _n = iBrother._n;
156 _currentn = iBrother._currentn;
157 return *this;
158 }
159
161 {
162 if (_Point != 0) {
163 delete _Point;
164 }
165 }
166
167 // protected: //FIXME
168 public:
173 int currentn,
174 int n,
175 float step,
176 float t = 0.0f,
177 float iCurvilinearLength = 0.0f)
178 : parent_class()
179 {
180 __A = iA;
181 __B = iB;
182 _begin = ibegin;
183 _end = iend;
184 _CurvilinearLength = iCurvilinearLength;
185 _step = step;
186 _t = t;
187 _Point = 0;
188 _n = n;
189 _currentn = currentn;
190 }
191
192 public:
193 // operators
194 inline Self &operator++() // operator corresponding to ++i
195 {
196 increment();
197 return *this;
198 }
199
200 /* Operator corresponding to i++, i.e. it returns the value *and then* increments.
201 * That’s why we store the value in a temp.
202 */
203 inline Self operator++(int)
204 {
205 Self tmp = *this;
206 increment();
207 return tmp;
208 }
209
210 inline Self &operator--() // operator corresponding to --i
211 {
212 decrement();
213 return *this;
214 }
215
216 inline Self operator--(int) // operator corresponding to i--
217 {
218 Self tmp = *this;
219 decrement();
220 return tmp;
221 }
222
223 // comparibility
224 virtual bool operator!=(const Self &b) const
225 {
226 return ((__A != b.__A) || (__B != b.__B) || (_t != b._t));
227 }
228
229 virtual bool operator==(const Self &b) const
230 {
231 return !(*this != b);
232 }
233
234 // dereferencing
235 virtual typename Traits::reference operator*() const
236 {
237 if (_Point != 0) {
238 delete _Point;
239 _Point = 0;
240 }
241 if ((_currentn < 0) || (_currentn >= _n)) {
242 return _Point; // 0 in this case
243 }
244 return (_Point = new Point(*__A, *__B, _t));
245 }
246
247 virtual typename Traits::pointer operator->() const
248 {
249 return &(operator*());
250 }
251
252 virtual bool begin() const
253 {
254 if ((__A == _begin) && (_t < (float)M_EPSILON)) {
255 return true;
256 }
257 return false;
258 }
259
260 virtual bool end() const
261 {
262 if ((__B == _end)) {
263 return true;
264 }
265 return false;
266 }
267
268 protected:
269 virtual void increment()
270 {
271 if (_Point != 0) {
272 delete _Point;
273 _Point = 0;
274 }
275 if ((_currentn == _n - 1) && (_t == 1.0f)) {
276 // we're setting the iterator to end
277 ++__A;
278 ++__B;
279 ++_currentn;
280 _t = 0.0f;
281 return;
282 }
283
284 if (0 == _step) { // means we iterate over initial vertices
285 Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d());
286 _CurvilinearLength += vec_tmp.norm();
287 if (_currentn == _n - 1) {
288 _t = 1.0f;
289 return;
290 }
291 ++__B;
292 ++__A;
293 ++_currentn;
294 return;
295 }
296
297 // compute the new position:
298 Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d());
299 float normAB = vec_tmp2.norm();
300
301 if (normAB > M_EPSILON) {
303 _t = _t + _step / normAB;
304 }
305 else {
306 _t = 1.0f; // AB is a null segment, we're directly at its end
307 }
308 // if normAB ~= 0, we don't change these values
309 if (_t >= 1) {
310 _CurvilinearLength -= normAB * (_t - 1);
311 if (_currentn == _n - 1) {
312 _t = 1.0f;
313 }
314 else {
315 _t = 0.0f;
316 ++_currentn;
317 ++__A;
318 ++__B;
319 }
320 }
321 }
322
323 virtual void decrement()
324 {
325 if (_Point != 0) {
326 delete _Point;
327 _Point = 0;
328 }
329
330 if (_t == 0.0f) { // we're at the beginning of the edge
331 _t = 1.0f;
332 --_currentn;
333 --__A;
334 --__B;
335 if (_currentn == _n - 1) {
336 return;
337 }
338 }
339
340 if (0 == _step) { // means we iterate over initial vertices
341 Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d());
342 _CurvilinearLength -= vec_tmp.norm();
343 _t = 0;
344 return;
345 }
346
347 // compute the new position:
348 Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d());
349 float normAB = vec_tmp2.norm();
350
351 if (normAB > M_EPSILON) {
353 _t = _t - _step / normAB;
354 }
355 else {
356 _t = -1.0f; // We just need a negative value here
357 }
358
359 // round value
360 if (fabs(_t) < (float)M_EPSILON) {
361 _t = 0.0f;
362 }
363 if (_t < 0) {
364 if (_currentn == 0) {
365 _CurvilinearLength = 0.0f;
366 }
367 else {
368 _CurvilinearLength += normAB * (-_t);
369 }
370 _t = 0.0f;
371 }
372 }
373};
374
375} // end of namespace CurveInternal
376
377} /* namespace Freestyle */
Iterators used to iterate over the elements of the Curve.
Classes to define a stroke.
vertex_container::const_iterator vertex_container_iterator
virtual bool operator!=(const Self &b) const
__point_iterator(const const_iterator &iBrother)
virtual bool operator==(const Self &b) const
__point_iterator< CurvePoint_const_traits > const_iterator
Traits::vertex_container_iterator vertex_container_iterator
__point_iterator< CurvePoint_nonconst_traits > iterator
virtual Traits::reference operator*() const
__point_iterator(vertex_container_iterator iA, vertex_container_iterator iB, vertex_container_iterator ibegin, vertex_container_iterator iend, int currentn, int n, float step, float t=0.0f, float iCurvilinearLength=0.0f)
IteratorBase< Traits, BidirectionalIteratorTag_Traits > parent_class
value_type norm() const
Definition VecMat.h:94
local_group_size(16, 16) .push_constant(Type b
ccl_device_inline float2 fabs(const float2 a)
inherits from class Rep
Definition AppCanvas.cpp:20
static const real M_EPSILON
Definition Precision.h:17