Fix T77456: Broken vertex paint undo on high-poly objects.
[blender.git] / source / blender / freestyle / intern / view_map / ViewMapAdvancedIterators.h
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 #ifndef __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
18 #define __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
19
20 /** \file
21  * \ingroup freestyle
22  * \brief Iterators used to iterate over the various elements of the ViewMap.
23  *         These iterators can't be exported to python.
24  */
25
26 #include "ViewMap.h"
27 #include "ViewMapIterators.h"
28
29 #include "../system/Iterator.h"  //soc
30
31 namespace Freestyle {
32
33 /**********************************/
34 /*                                */
35 /*                                */
36 /*             ViewMap            */
37 /*                                */
38 /*                                */
39 /**********************************/
40
41 /**********************************/
42 /*                                */
43 /*                                */
44 /*             ViewVertex         */
45 /*                                */
46 /*                                */
47 /**********************************/
48
49 namespace ViewVertexInternal {
50
51 class edge_const_traits : public Const_traits<ViewVertex::directedViewEdge> {
52  public:
53   typedef vector<ViewVertex::directedViewEdge> edges_container;
54   typedef edges_container::const_iterator edges_container_iterator;
55   typedef vector<ViewVertex::directedViewEdge *> edge_pointers_container;
56   typedef edge_pointers_container::const_iterator edge_pointers_container_iterator;
57 };
58
59 class edge_nonconst_traits : public Nonconst_traits<ViewVertex::directedViewEdge> {
60  public:
61   typedef vector<ViewVertex::directedViewEdge> edges_container;
62   typedef edges_container::iterator edges_container_iterator;
63   typedef vector<ViewVertex::directedViewEdge *> edge_pointers_container;
64   typedef edge_pointers_container::iterator edge_pointers_container_iterator;
65 };
66
67 template<class Traits>
68 class edge_iterator_base : public IteratorBase<Traits, InputIteratorTag_Traits> {
69  public:
70   typedef typename Traits::value_type value_type;
71   typedef typename Traits::difference_type difference_type;
72   typedef typename Traits::pointer pointer;
73   typedef typename Traits::reference reference;
74   typedef edge_iterator_base<Traits> Self;
75   typedef typename Traits::edges_container_iterator edges_container_iterator;
76   typedef typename Traits::edge_pointers_container_iterator edge_pointers_container_iterator;
77   typedef edge_iterator_base<edge_nonconst_traits> iterator;
78   typedef edge_iterator_base<edge_const_traits> const_iterator;
79
80  public:
81   friend class ViewVertex;
82   friend class TVertex;
83   friend class NonTVertex;
84   friend class ViewEdge;
85   friend class edge_iterator;
86
87  protected:
88   Nature::VertexNature _Nature;  // the nature of the underlying vertex
89   // T vertex attributes
90   edge_pointers_container_iterator _tbegin;
91   edge_pointers_container_iterator _tend;
92   edge_pointers_container_iterator _tvertex_iter;
93
94 #if 0
95   mutable value_type _tvertex_iter;
96   value_type _feA;
97   value_type _feB;
98   value_type _beA;
99   value_type _beB;
100 #endif
101
102   // Non TVertex attributes
103   edges_container_iterator _begin;
104   edges_container_iterator _end;
105   edges_container_iterator _nontvertex_iter;
106
107   typedef IteratorBase<Traits, InputIteratorTag_Traits> parent_class;
108
109  public:
110   inline edge_iterator_base() : parent_class()
111   {
112   }
113
114   inline edge_iterator_base(Nature::VertexNature iNature) : parent_class()
115   {
116     _Nature = iNature;
117   }
118
119   edge_iterator_base(const edge_iterator_base<edge_nonconst_traits> &iBrother)
120       : parent_class(iBrother)
121   {
122     _Nature = iBrother._Nature;
123     if (_Nature & Nature::T_VERTEX) {
124 #if 0
125       _feA = iBrother._feA;
126       _feB = iBrother._feB;
127       _beA = iBrother._beA;
128       _beB = iBrother._beB;
129       _tvertex_iter = iBrother._tvertex_iter;
130 #endif
131       _tbegin = iBrother._tbegin;
132       _tend = iBrother._tend;
133       _tvertex_iter = iBrother._tvertex_iter;
134     }
135     else {
136       _begin = iBrother._begin;
137       _end = iBrother._end;
138       _nontvertex_iter = iBrother._nontvertex_iter;
139     }
140   }
141
142   edge_iterator_base(const edge_iterator_base<edge_const_traits> &iBrother)
143       : parent_class(iBrother)
144   {
145     _Nature = iBrother._Nature;
146     if (_Nature & Nature::T_VERTEX) {
147 #if 0
148       _feA = iBrother._feA;
149       _feB = iBrother._feB;
150       _beA = iBrother._beA;
151       _beB = iBrother._beB;
152       _tvertex_iter = iBrother._tvertex_iter;
153 #endif
154       _tbegin = iBrother._tbegin;
155       _tend = iBrother._tend;
156       _tvertex_iter = iBrother._tvertex_iter;
157     }
158     else {
159       _begin = iBrother._begin;
160       _end = iBrother._end;
161       _nontvertex_iter = iBrother._nontvertex_iter;
162     }
163   }
164
165   virtual ~edge_iterator_base()
166   {
167   }
168
169   // protected://FIXME
170  public:
171 #if 0
172   inline edge_iterator_base(
173       value_type ifeA, value_type ifeB, value_type ibeA, value_type ibeB, value_type iter)
174       : parent_class()
175   {
176     _Nature = Nature::T_VERTEX;
177     _feA = ifeA;
178     _feB = ifeB;
179     _beA = ibeA;
180     _beB = ibeB;
181     _tvertex_iter = iter;
182   }
183 #endif
184
185   inline edge_iterator_base(edge_pointers_container_iterator begin,
186                             edge_pointers_container_iterator end,
187                             edge_pointers_container_iterator iter)
188       : parent_class()
189   {
190     _Nature = Nature::T_VERTEX;
191     _tbegin = begin;
192     _tend = end;
193     _tvertex_iter = iter;
194   }
195
196   inline edge_iterator_base(edges_container_iterator begin,
197                             edges_container_iterator end,
198                             edges_container_iterator iter)
199       : parent_class()
200   {
201     _Nature = Nature::NON_T_VERTEX;
202     _begin = begin;
203     _end = end;
204     _nontvertex_iter = iter;
205   }
206
207  public:
208   virtual bool begin() const
209   {
210     if (_Nature & Nature::T_VERTEX) {
211       return (_tvertex_iter == _tbegin);
212       // return (_tvertex_iter == _feA);
213     }
214     else {
215       return (_nontvertex_iter == _begin);
216     }
217   }
218
219   virtual bool end() const
220   {
221     if (_Nature & Nature::T_VERTEX) {
222       // return (_tvertex_iter.first == 0);
223       return (_tvertex_iter == _tend);
224     }
225     else {
226       return (_nontvertex_iter == _end);
227     }
228   }
229
230   // operators
231   // operator corresponding to ++i
232   virtual Self &operator++()
233   {
234     increment();
235     return *this;
236   }
237
238   // operator corresponding to i++, i.e. which returns the value *and then* increments it.
239   // That's why we store the value in a temp.
240   virtual Self operator++(int)
241   {
242     Self tmp = *this;
243     increment();
244     return tmp;
245   }
246
247   // comparibility
248   virtual bool operator!=(const Self &b) const
249   {
250     if (_Nature & Nature::T_VERTEX) {
251       return (_tvertex_iter != b._tvertex_iter);
252     }
253     else {
254       return (_nontvertex_iter != b._nontvertex_iter);
255     }
256   }
257
258   virtual bool operator==(const Self &b) const
259   {
260     return !(*this != b);
261   }
262
263   // dereferencing
264   virtual reference operator*() const
265   {
266     if (_Nature & Nature::T_VERTEX) {
267       // return _tvertex_iter;
268       return **_tvertex_iter;
269     }
270     else {
271       return (*_nontvertex_iter);
272     }
273   }
274
275   virtual pointer operator->() const
276   {
277     return &(operator*());
278   }
279
280  protected:
281   inline void increment()
282   {
283     if (_Nature & Nature::T_VERTEX) {
284       value_type tmp = (**_tvertex_iter);
285       ++_tvertex_iter;
286       value_type tmp2 = (**_tvertex_iter);
287       if (tmp2.first == tmp.first) {
288         ++_tvertex_iter;
289       }
290 #if 0
291       // Hack to deal with cusp. the result of a cusp is a TVertex having two identical viewedges.
292       // In order to iterate properly, we chose to skip these last ones.
293       if (_feB.first == _beA.first) {
294         if (_feA.first == _beB.first) {
295           _tvertex_iter.first = 0;
296           return;
297         }
298
299         if (_tvertex_iter.first == _feA.first) {
300           _tvertex_iter.first = _beB.first;
301         }
302         else if (_tvertex_iter.first == _beB.first) {
303           _tvertex_iter.first = 0;
304         }
305         else {
306           _tvertex_iter.first = _feA.first;
307         }
308         return;
309       }
310       if (_feA.first == _beB.first) {
311         if (_feB.first == _beA.first) {
312           _tvertex_iter.first = 0;
313           return;
314         }
315
316         if (_tvertex_iter.first == _feB.first) {
317           _tvertex_iter.first = _beA.first;
318         }
319         else if (_tvertex_iter.first == _beA.first) {
320           _tvertex_iter.first = 0;
321         }
322         else {
323           _tvertex_iter.first = _feB.first;
324         }
325         return;
326       }
327       // End of hack
328
329       if (_tvertex_iter.first == _feA.first) {
330         // we return bea or beb
331         // choose one of them
332         _tvertex_iter.first = _feB.first;
333         return;
334       }
335       if (_tvertex_iter.first == _feB.first) {
336         _tvertex_iter.first = _beA.first;
337         return;
338       }
339       if (_tvertex_iter.first == _beA.first) {
340         _tvertex_iter.first = _beB.first;
341         return;
342       }
343       if (_tvertex_iter.first == _beB.first) {
344         _tvertex_iter.first = 0;
345         return;
346       }
347 #endif
348     }
349     else {
350       ++_nontvertex_iter;
351     }
352   }
353 };
354
355 }  // namespace ViewVertexInternal
356
357 /**********************************/
358 /*                                */
359 /*                                */
360 /*             ViewEdge           */
361 /*                                */
362 /*                                */
363 /**********************************/
364
365 namespace ViewEdgeInternal {
366
367 /*!----------------------*/
368 /*! Iterators definition */
369 /*!----------------------*/
370 template<class Traits>
371 class edge_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits> {
372  public:
373   typedef typename Traits::value_type value_type;
374   typedef typename Traits::difference_type difference_type;
375   typedef typename Traits::pointer pointer;
376   typedef typename Traits::reference reference;
377   typedef edge_iterator_base<Traits> Self;
378
379  public:
380   mutable value_type _ViewEdge;
381   // friend class edge_iterator_base<Nonconst_traits<ViewEdge*> >;
382   // friend class edge_iterator_base<Const_traits<ViewEdge*> >;
383   value_type _first;
384   bool _orientation;
385   typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
386
387  public:
388   friend class ViewEdge;
389   inline edge_iterator_base() : parent_class()
390   {
391     _orientation = true;
392     _first = 0;
393   }
394
395   inline edge_iterator_base(const edge_iterator_base<Nonconst_traits<ViewEdge *>> &iBrother)
396       : parent_class()
397   {
398     _ViewEdge = iBrother._ViewEdge;
399     _first = iBrother._first;
400     _orientation = iBrother._orientation;
401   }
402
403   inline edge_iterator_base(const edge_iterator_base<Const_traits<ViewEdge *>> &iBrother)
404       : parent_class()
405   {
406     _ViewEdge = iBrother._ViewEdge;
407     _first = iBrother._first;
408     _orientation = iBrother._orientation;
409   }
410
411   // protected://FIXME
412  public:
413   inline edge_iterator_base(value_type iEdge, bool orientation = true) : parent_class()
414   {
415     _ViewEdge = iEdge;
416     _first = iEdge;
417     _orientation = orientation;
418   }
419
420  public:
421   virtual Self *clone() const
422   {
423     return new edge_iterator_base(*this);
424   }
425
426   virtual ~edge_iterator_base()
427   {
428   }
429
430  public:
431   virtual bool orientation()
432   {
433     return _orientation;
434   }
435
436   virtual void set_edge(value_type iVE)
437   {
438     _ViewEdge = iVE;
439   }
440
441   virtual void set_orientation(bool iOrientation)
442   {
443     _orientation = iOrientation;
444   }
445
446   virtual void change_orientation()
447   {
448     _orientation = !_orientation;
449   }
450
451   // operators
452   // operator corresponding to ++i
453   inline Self &operator++()
454   {
455     //++_ViewEdge->getTimeStamp();
456     increment();
457     return *this;
458   }
459
460   // operator corresponding to i++, i.e. which returns the value *and then* increments it.
461   // That's why we store the value in a temp.
462   inline Self operator++(int)
463   {
464     //++_ViewEdge->getTimeStamp();
465     Self tmp = *this;
466     increment();
467     return tmp;
468   }
469
470   // operator corresponding to --i
471   inline Self &operator--()
472   {
473     //++_ViewEdge->getTimeStamp();
474     decrement();
475     return *this;
476   }
477
478   // operator corresponding to i--, i.e. which returns the value *and then* increments it.
479   // That's why we store the value in a temp.
480   inline Self operator--(int)
481   {
482     //++_ViewEdge->getTimeStamp();
483     Self tmp = *this;
484     decrement();
485     return tmp;
486   }
487
488   // comparibility
489   virtual bool operator!=(const Self &b) const
490   {
491     return (_ViewEdge != b._ViewEdge);
492   }
493
494   virtual bool operator==(const Self &b) const
495   {
496     return !(*this != b);
497   }
498
499   // dereferencing
500   virtual reference operator*() const
501   {
502     return (_ViewEdge);
503   }
504
505   virtual pointer operator->() const
506   {
507     return &(operator*());
508   }
509
510  public:
511   virtual bool begin() const
512   {
513     return (_ViewEdge == _first) ? true : false;
514   }
515
516   virtual bool end() const
517   {
518     return (_ViewEdge == 0) ? true : false;
519   }
520
521  protected:
522   virtual void increment()
523   {
524   }
525   virtual void decrement()
526   {
527   }
528 };
529
530 template<class Traits>
531 class fedge_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits> {
532  public:
533   typedef typename Traits::value_type value_type;
534   typedef typename Traits::difference_type difference_type;
535   typedef typename Traits::pointer pointer;
536   typedef typename Traits::reference reference;
537   typedef fedge_iterator_base<Traits> Self;
538
539  public:
540   typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
541   mutable value_type _FEdge;
542   value_type _first;
543   value_type _FEdgeB;  // last fedge of the view edge
544
545  public:
546   friend class ViewEdge;
547   friend class fedge_iterator;
548
549   inline fedge_iterator_base() : parent_class()
550   {
551   }
552
553   inline fedge_iterator_base(const fedge_iterator_base<Nonconst_traits<FEdge *>> &iBrother)
554       : parent_class()
555   {
556     _FEdge = iBrother._FEdge;
557     _first = iBrother._first;
558     _FEdgeB = iBrother._FEdgeB;
559   }
560
561   inline fedge_iterator_base(const fedge_iterator_base<Const_traits<FEdge *>> &iBrother)
562       : parent_class()
563   {
564     _FEdge = iBrother._FEdge;
565     _first = iBrother._first;
566     _FEdgeB = iBrother._FEdgeB;
567   }
568
569   // protected://FIXME
570  public:
571   inline fedge_iterator_base(value_type iEdge, value_type iFEdgeB) : parent_class()
572   {
573     _FEdge = iEdge;
574     _first = iEdge;
575     _FEdgeB = iFEdgeB;
576   }
577
578  public:
579   virtual ~fedge_iterator_base()
580   {
581   }
582
583   // operators
584   // operator corresponding to ++i.
585   inline Self &operator++()
586   {
587     increment();
588     return *this;
589   }
590
591   // operator corresponding to i++, i.e. which returns the value *and then* increments it.
592   // That's why we store the value in a temp.
593   inline Self operator++(int)
594   {
595     Self tmp = *this;
596     increment();
597     return tmp;
598   }
599
600   // operator corresponding to --i
601   inline Self &operator--()
602   {
603     decrement();
604     return *this;
605   }
606
607   // operator corresponding to i--, i.e. which returns the value *and then* increments it.
608   // That's why we store the value in a temp.
609   inline Self operator--(int)
610   {
611     Self tmp = *this;
612     decrement();
613     return tmp;
614   }
615
616   // comparibility
617   virtual bool operator!=(const Self &b) const
618   {
619     return (_FEdge != b._FEdge);
620   }
621
622   virtual bool operator==(const Self &b) const
623   {
624     return !(*this != b);
625   }
626
627   // dereferencing
628   virtual reference operator*() const
629   {
630     return (_FEdge);
631   }
632
633   virtual pointer operator->() const
634   {
635     return &(operator*());
636   }
637
638  public:
639   virtual bool begin() const
640   {
641     return (_FEdge == _first) ? true : false;
642   }
643
644   virtual bool end() const
645   {
646     return (_FEdge == 0) ? true : false;
647   }
648
649  protected:
650   virtual void increment()
651   {
652     _FEdge = _FEdge->nextEdge();  // we don't change or
653   }
654
655   virtual void decrement()
656   {
657     if (0 == _FEdge) {
658       _FEdge = _FEdgeB;
659       return;
660     }
661     _FEdge = _FEdge->previousEdge();  // we don't change or
662   }
663 };
664
665 template<class Traits>
666 class vertex_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTag_Traits> {
667  public:
668   typedef typename Traits::value_type value_type;
669   typedef typename Traits::difference_type difference_type;
670   typedef typename Traits::pointer pointer;
671   typedef typename Traits::reference reference;
672   typedef vertex_iterator_base<Traits> Self;
673
674  protected:
675   typedef IteratorBase<Traits, BidirectionalIteratorTag_Traits> parent_class;
676
677  public:
678   mutable value_type _SVertex;
679   FEdge *_NextFEdge;
680   FEdge *_PreviousFEdge;
681
682  public:
683   friend class ViewEdge;
684   friend class vertex_iterator;
685
686   inline vertex_iterator_base() : parent_class()
687   {
688   }
689
690   inline vertex_iterator_base(const vertex_iterator_base<Const_traits<SVertex *>> &iBrother)
691       : parent_class()
692   {
693     _SVertex = iBrother._SVertex;
694     _NextFEdge = iBrother._NextFEdge;
695     _PreviousFEdge = iBrother._PreviousFEdge;
696   }
697
698   inline vertex_iterator_base(const vertex_iterator_base<Nonconst_traits<SVertex *>> &iBrother)
699       : parent_class()
700   {
701     _SVertex = iBrother._SVertex;
702     _NextFEdge = iBrother._NextFEdge;
703     _PreviousFEdge = iBrother._PreviousFEdge;
704   }
705
706   // protected://FIXME
707  public:
708   inline vertex_iterator_base(value_type iVertex, FEdge *iPreviousFEdge, FEdge *iNextFEdge)
709       : parent_class()
710   {
711     _SVertex = iVertex;
712     _NextFEdge = iNextFEdge;
713     _PreviousFEdge = iPreviousFEdge;
714   }
715
716  public:
717   virtual ~vertex_iterator_base()
718   {
719   }
720
721   virtual bool begin() const
722   {
723     return (_PreviousFEdge == 0) ? true : false;
724   }
725
726   virtual bool end() const
727   {
728     return (_SVertex == 0) ? true : false;
729   }
730
731   // operators
732   // operator corresponding to ++i
733   inline Self &operator++()
734   {
735     increment();
736     return *this;
737   }
738
739   // operator corresponding to i++, i.e. which returns the value *and then* increments it.
740   // That's why we store the value in a temp.
741   inline Self operator++(int)
742   {
743     Self tmp = *this;
744     increment();
745     return tmp;
746   }
747
748   // operator corresponding to --i
749   inline Self &operator--()
750   {
751     decrement();
752     return *this;
753   }
754
755   // operator corresponding to --i, i.e. which returns the value *and then* increments it.
756   // That's why we store the value in a temp.
757   inline Self operator--(int)
758   {
759     Self tmp = *this;
760     decrement();
761     return tmp;
762   }
763
764   // comparibility
765   virtual bool operator!=(const Self &b) const
766   {
767     return (_SVertex != b._SVertex);
768   }
769
770   virtual bool operator==(const Self &b) const
771   {
772     return !(*this != b);
773   }
774
775   // dereferencing
776   virtual reference operator*() const
777   {
778     return (_SVertex);
779   }
780
781   virtual pointer operator->() const
782   {
783     return &(operator*());
784   }
785
786  protected:
787   virtual void increment()
788   {
789     if (!_NextFEdge) {
790       _SVertex = NULL;
791       return;
792     }
793     _SVertex = _NextFEdge->vertexB();
794     _PreviousFEdge = _NextFEdge;
795     _NextFEdge = _NextFEdge->nextEdge();
796   }
797
798   virtual void decrement()
799   {
800 #if 0
801     if (!_SVertex) {
802       _SVertex = _PreviousFEdge->vertexB();
803       return;
804     }
805 #endif
806     if (!_PreviousFEdge) {
807       _SVertex = NULL;
808       return;
809     }
810     _SVertex = _PreviousFEdge->vertexA();
811     _NextFEdge = _PreviousFEdge;
812     _PreviousFEdge = _PreviousFEdge->previousEdge();
813   }
814 };
815
816 }  // end of namespace ViewEdgeInternal
817
818 } /* namespace Freestyle */
819
820 #endif  // __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__