Fix for a static variable in BlenderStrokeRenderer::RenderStrokeRep() left after
[blender.git] / source / blender / freestyle / intern / view_map / ViewMapIterators.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2010 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #ifndef __FREESTYLE_VIEW_MAP_ITERATORS_H__
29 #define __FREESTYLE_VIEW_MAP_ITERATORS_H__
30
31 /** \file blender/freestyle/intern/view_map/ViewMapIterators.h
32  *  \ingroup freestyle
33  *  \brief Iterators used to iterate over the various elements of the ViewMap
34  *  \author Stephane Grabli
35  *  \date 01/07/2003
36  */
37
38 #include "ViewMap.h"
39
40 #include "../system/Iterator.h" //soc 
41
42
43 /**********************************/
44 /*                                */
45 /*                                */
46 /*             ViewMap            */
47 /*                                */
48 /*                                */
49 /**********************************/
50
51 /**********************************/
52 /*                                */
53 /*                                */
54 /*             ViewVertex         */
55 /*                                */
56 /*                                */
57 /**********************************/
58
59 namespace ViewVertexInternal {
60
61 /*! Class representing an iterator over oriented ViewEdges around a ViewVertex. This iterator allows a CCW iteration
62  *  (in the image plane).
63  *  An instance of an orientedViewEdgeIterator can only be obtained from a ViewVertex by calling edgesBegin()
64  *  or edgesEnd().
65  */
66 class orientedViewEdgeIterator : public Iterator
67 {
68 public:
69         friend class ViewVertex;
70         friend class TVertex;
71         friend class NonTVertex;
72         friend class ViewEdge;
73
74         // FIXME
75         typedef ::TVertex::edge_pointers_container edge_pointers_container;
76         typedef ::NonTVertex::edges_container edges_container;
77
78 protected:
79         Nature::VertexNature _Nature; // the nature of the underlying vertex
80         // T vertex attributes
81         edge_pointers_container::iterator _tbegin;
82         edge_pointers_container::iterator _tend;
83         edge_pointers_container::iterator _tvertex_iter;
84
85         // Non TVertex attributes
86         edges_container::iterator _begin;
87         edges_container::iterator _end;
88         edges_container::iterator _nontvertex_iter;
89
90 public:
91         /*! Default constructor */
92         inline orientedViewEdgeIterator() {}
93
94         inline orientedViewEdgeIterator(Nature::VertexNature iNature)
95         {
96                 _Nature = iNature;
97         }
98
99         /*! Copy constructor */
100         orientedViewEdgeIterator(const orientedViewEdgeIterator& iBrother)
101         {
102                 _Nature = iBrother._Nature;
103                 if (_Nature & Nature::T_VERTEX) {
104                         _tbegin = iBrother._tbegin;
105                         _tend = iBrother._tend;
106                         _tvertex_iter = iBrother._tvertex_iter;
107                 }
108                 else {
109                         _begin = iBrother._begin;
110                         _end = iBrother._end;
111                         _nontvertex_iter = iBrother._nontvertex_iter;
112                 }
113         }
114
115         virtual ~orientedViewEdgeIterator() {}
116
117 public:
118         inline orientedViewEdgeIterator(edge_pointers_container::iterator begin, edge_pointers_container::iterator end,
119                                         edge_pointers_container::iterator iter)
120         {
121                 _Nature = Nature::T_VERTEX;
122                 _tbegin = begin;
123                 _tend = end;
124                 _tvertex_iter = iter;
125         }
126
127         inline orientedViewEdgeIterator(edges_container::iterator begin, edges_container::iterator end,
128                                         edges_container::iterator iter)
129         {
130                 _Nature = Nature::NON_T_VERTEX;
131                 _begin = begin;
132                 _end = end;
133                 _nontvertex_iter = iter;
134         }
135
136 public:
137         /*! Tells whether the ViewEdge pointed by this iterator is the first one of the iteration list or not. */
138         virtual bool isBegin() const
139         {
140                 if (_Nature & Nature::T_VERTEX)
141                         return (_tvertex_iter == _tbegin);
142                 else
143                         return (_nontvertex_iter == _begin);
144         }
145
146         /*! Tells whether the ViewEdge pointed by this iterator is after the last one of the iteration list or not. */
147         virtual bool isEnd() const
148         {
149                 if (_Nature & Nature::T_VERTEX)
150                         return (_tvertex_iter == _tend);
151                 else
152                         return (_nontvertex_iter == _end);
153         }
154
155         // operators
156         /*! Increments. In the scripting language, call "increment()". */
157         // operator corresponding to ++i
158         virtual orientedViewEdgeIterator& operator++()
159         {
160                 increment();
161                 return *this;
162         }
163
164         // operator corresponding to i++, i.e. which returns the value *and then* increments.
165         // That's why we store the value in a temp.
166         virtual orientedViewEdgeIterator operator++(int)
167         {
168                 orientedViewEdgeIterator tmp = *this;
169                 increment();
170                 return tmp;
171         }
172
173         // comparibility
174         /*! operator != */
175         virtual bool operator!=(const orientedViewEdgeIterator& b) const
176         {
177                 if (_Nature & Nature::T_VERTEX)
178                         return (_tvertex_iter != b._tvertex_iter);
179                 else
180                         return (_nontvertex_iter != b._nontvertex_iter);
181         }
182
183         /*! operator == */
184         virtual bool operator==(const orientedViewEdgeIterator& b) const
185         {
186                 return !(*this != b);
187         }
188
189         // dereferencing
190         /*! Returns a reference to the pointed orientedViewEdge.
191          *  In the scripting language, you must call "getObject()" instead.
192          */
193         virtual ::ViewVertex::directedViewEdge& operator*() const
194         {
195                 if (_Nature & Nature::T_VERTEX)
196                         //return _tvertex_iter;
197                         return **_tvertex_iter;
198                 else
199                         return (*_nontvertex_iter);
200         }
201         /*! Returns a pointer to the pointed orientedViewEdge.
202          * Can't be called in the scripting language.
203          */
204         virtual ::ViewVertex::directedViewEdge *operator->() const
205         {
206                 return &(operator*());
207         }
208
209 public:
210         /*! increments.*/
211         virtual inline int increment()
212         {
213                 if (_Nature & Nature::T_VERTEX) {
214                         ::ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
215                         ++_tvertex_iter;
216                         if (_tvertex_iter != _tend) {
217                                 // FIXME : pquoi deja ?
218                                 ::ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
219                                 if (tmp2.first == tmp.first)
220                                         ++_tvertex_iter;
221                         }
222                 }
223                 else {
224                         ++_nontvertex_iter;
225                 }
226                 return 0;
227         }
228 };
229
230 }  // ViewVertexInternal namespace
231
232 /**********************************/
233 /*                                */
234 /*                                */
235 /*             ViewEdge           */
236 /*                                */
237 /*                                */
238 /**********************************/
239
240 namespace ViewEdgeInternal {
241
242 //
243 // SVertexIterator
244 //
245 /////////////////////////////////////////////////
246
247 class SVertexIterator : public Interface0DIteratorNested
248 {
249 public:
250         SVertexIterator()
251         {
252                 _vertex = NULL;
253                 _begin = NULL;
254                 _previous_edge = NULL;
255                 _next_edge = NULL;
256                 _t = 0;
257         }
258
259         SVertexIterator(const SVertexIterator& vi)
260         {
261                 _vertex = vi._vertex;
262                 _begin = vi._begin;
263                 _previous_edge = vi._previous_edge;
264                 _next_edge = vi._next_edge;
265                 _t = vi._t;
266         }
267
268         SVertexIterator(SVertex *v, SVertex *begin, FEdge *prev, FEdge *next, float t)
269         {
270                 _vertex = v;
271                 _begin = begin;
272                 _previous_edge = prev;
273                 _next_edge = next;
274                 _t = t;
275         }
276
277         SVertexIterator& operator=(const SVertexIterator& vi)
278         {
279                 _vertex = vi._vertex;
280                 _begin = vi._begin;
281                 _previous_edge = vi._previous_edge;
282                 _next_edge = vi._next_edge;
283                 _t = vi._t;
284                 return *this;
285         }
286
287         virtual ~SVertexIterator() {}
288
289         virtual string getExactTypeName() const
290         {
291                 return "SVertexIterator";
292         }
293
294         virtual SVertex& operator*()
295         {
296                 return *_vertex;
297         }
298
299         virtual SVertex *operator->()
300         {
301                 return &(operator*());
302         }
303
304         virtual SVertexIterator& operator++()
305         {
306                 increment();
307                 return *this;
308         }
309
310         virtual SVertexIterator operator++(int)
311         {
312                 SVertexIterator ret(*this);
313                 increment();
314                 return ret;
315         }
316
317         virtual SVertexIterator& operator--()
318         {
319                 decrement();
320                 return *this;
321         }
322
323         virtual SVertexIterator operator--(int)
324         {
325                 SVertexIterator ret(*this);
326                 decrement();
327                 return ret;
328         }
329
330         virtual int increment()
331         {
332                 if (!_next_edge) {
333                         _vertex = NULL;
334                         return 0;
335                 }
336                 _t += (float)_next_edge->getLength2D();
337                 _vertex = _next_edge->vertexB();
338                 _previous_edge = _next_edge;
339                 _next_edge = _next_edge->nextEdge();
340                 return 0;
341         }
342
343         virtual int decrement()
344         {
345                 if (!_previous_edge) {
346                         _vertex = NULL;
347                         return 0;
348                 }
349                 if ((!_next_edge) && (!_vertex)) {
350                         _vertex = _previous_edge->vertexB();
351                         return 0;
352                 }
353                 _t -= (float)_previous_edge->getLength2D();
354                 _vertex = _previous_edge->vertexA();
355                 _next_edge = _previous_edge;
356                 _previous_edge = _previous_edge->previousEdge();
357                 return 0;
358         }
359
360         virtual bool isBegin() const
361         {
362                 return _vertex == _begin;
363         }
364
365         virtual bool isEnd() const
366         {
367                 return (!_vertex) || (_vertex == _begin && _previous_edge);
368         }
369
370         virtual float t() const
371         {
372                 return _t;
373         }
374
375         virtual float u() const
376         {
377                 return _t / (float)_next_edge->viewedge()->getLength2D();
378         }
379
380         virtual bool operator==(const Interface0DIteratorNested& it) const
381         {
382                 const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator*>(&it);
383                 if (!it_exact)
384                         return false;
385                 return (_vertex == it_exact->_vertex);
386         }
387
388         virtual SVertexIterator *copy() const
389         {
390                 return new SVertexIterator(*this);
391         }
392
393 private:
394         SVertex *_vertex;
395         SVertex *_begin;
396         FEdge *_previous_edge;
397         FEdge *_next_edge;
398         float _t; // curvilinear abscissa
399 };
400
401
402 //
403 // ViewEdgeIterator (base class)
404 //
405 ///////////////////////////////////////////////////////////
406
407 /*! Base class for iterators over ViewEdges of the ViewMap Graph.
408  *  Basically the "increment()" operator of this class should be able to take the decision of "where" (on which
409  *  ViewEdge) to go when pointing on a given ViewEdge.
410  *  ::Caution::: the dereferencing operator returns a *pointer* to the pointed ViewEdge.
411  */
412 class ViewEdgeIterator : public Iterator
413 {
414 public:
415         /*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation.
416          *  \param begin
417          *    The ViewEdge from where to start the iteration.
418          *  \param orientation
419          *    If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending ViewVertex of begin.
420          *    If false, we'll search over the ViewEdges surrounding the ending ViewVertex of begin.
421          */
422         ViewEdgeIterator(ViewEdge *begin = NULL, bool orientation = true)
423         {
424                 _orientation = orientation;
425                 _edge = begin;
426                 _begin = begin;
427         }
428
429         /*! Copy constructor */
430         ViewEdgeIterator(const ViewEdgeIterator& it)
431         {
432                 _orientation = it._orientation;
433                 _edge = it._edge;
434                 _begin = it._begin;
435         }
436
437         virtual ~ViewEdgeIterator() {}
438
439         /*! Returns the string "ViewEdgeIterator" */
440         virtual string getExactTypeName() const
441         {
442                 return "ViewEdgeIterator";
443         }
444
445         /*! Returns the current pointed ViewEdge. */
446         ViewEdge *getCurrentEdge()
447         {
448                 return _edge;
449         }
450
451         /*! Sets the current pointed ViewEdge. */
452         void setCurrentEdge(ViewEdge *edge)
453         {
454                 _edge = edge;
455         }
456
457         /*! Returns the first ViewEdge used for the iteration. */
458         ViewEdge *getBegin()
459         {
460                 return _begin;
461         }
462
463         /*! Sets the first ViewEdge used for the iteration. */
464         void setBegin(ViewEdge *begin)
465         {
466                 _begin = begin;
467         }
468
469         /*! Gets the orientation of the pointed ViewEdge in the iteration. */
470         bool getOrientation() const
471         {
472                 return _orientation;
473         }
474
475         /*! Sets the orientation of the pointed ViewEdge in the iteration. */
476         void setOrientation(bool orientation)
477         {
478                 _orientation = orientation;
479         }
480
481         /*! Changes the current orientation. */
482         void changeOrientation()
483         {
484                 _orientation = !_orientation;
485         }
486
487         /*! Returns a *pointer* to the pointed ViewEdge. */
488         virtual ViewEdge *operator*()
489         {
490                 return _edge;
491         }
492
493         virtual ViewEdge *operator->()
494         {
495                 return operator*();
496         }
497
498         /*! Increments. In the scripting language, call "increment()". */
499         virtual ViewEdgeIterator& operator++()
500         {
501                 increment();
502                 return *this;
503         }
504
505         /*! Increments. In the scripting language, call "increment()". */
506         virtual ViewEdgeIterator operator++(int)
507         {
508                 ViewEdgeIterator tmp(*this);
509                 increment();
510                 return tmp;
511         }
512
513         /*! increments. */
514         virtual int increment()
515         {
516                 cerr << "Warning: method increment() not implemented" << endl;
517                 return 0;
518         }
519
520         /*! Decrements. In the scripting language, call "decrement()". */
521         virtual ViewEdgeIterator& operator--()
522         {
523                 decrement();
524                 return *this;
525         }
526
527         /*! Decrements. In the scripting language, call "decrement()". */
528         virtual ViewEdgeIterator operator--(int)
529         {
530                 ViewEdgeIterator tmp(*this);
531                 decrement();
532                 return tmp;
533         }
534
535         /*! decrements. */
536         virtual int decrement()
537         {
538                 cerr << "Warning: method decrement() not implemented" << endl;
539                 return 0;
540         }
541
542         /*! Returns true if the pointed ViewEdge is the first one used for the iteration. */
543         virtual bool isBegin() const
544         {
545                 return _edge == _begin;
546         }
547
548         /*! Returns true if the pointed ViewEdge* equals 0. */
549         virtual bool isEnd() const
550         {
551                 return !_edge;
552         }
553
554         /*! operator == */
555         virtual bool operator==(ViewEdgeIterator& it) const
556         {
557                 return _edge == it._edge;
558         }
559
560         /*! operator != */
561         virtual bool operator!=(ViewEdgeIterator& it) const
562         {
563                 return !(*this == it);
564         }
565
566 protected:
567         bool _orientation;
568         ViewEdge *_edge;
569         ViewEdge *_begin;
570 };
571
572 } // end of namespace ViewEdgeInternal
573
574 #endif // __FREESTYLE_VIEW_MAP_ITERATORS_H__