Merged changes in the trunk up to revision 28600.
[blender.git] / source / blender / freestyle / intern / stroke / ChainingIterators.cpp
1
2 //
3 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
4 //   with this source distribution. 
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 //
20 ///////////////////////////////////////////////////////////////////////////////
21 #include "ChainingIterators.h"
22 #include "../system/TimeStamp.h"
23
24 ViewEdge* AdjacencyIterator::operator*() {
25   return (*_internalIterator).first;
26 }
27 bool AdjacencyIterator::isIncoming() const{
28   return (*_internalIterator).second;
29 }
30
31 int AdjacencyIterator::increment(){
32   ++_internalIterator;
33   while((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first)))
34     ++_internalIterator;
35   return 0;
36 }
37
38 bool AdjacencyIterator::isValid(ViewEdge* edge){
39   if(_restrictToSelection)
40     if(edge->getTimeStamp() != TimeStamp::instance()->getTimeStamp())
41       return false;
42   if(_restrictToUnvisited)
43     if(edge->getChainingTimeStamp() > TimeStamp::instance()->getTimeStamp())
44       return false;
45     return true;
46 }
47
48 int ChainingIterator::increment() {
49   _increment = true;
50   ViewVertex * vertex = getVertex();
51   if(!vertex){
52     _edge = 0;
53     return 0;
54   }
55   AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited);
56   if(it.isEnd()) {
57     _edge = 0;
58         return 0;
59   }
60   if (traverse(it) < 0)
61         return -1;
62   _edge = result;
63   if(_edge == 0)
64     return 0;
65   if(_edge->A() == vertex)
66     _orientation = true;
67   else
68     _orientation = false;
69   return 0;
70 }
71
72 int ChainingIterator::decrement() {
73   _increment = false;
74   ViewVertex * vertex = getVertex();
75   if(!vertex){
76     _edge = 0;
77     return 0;
78   }
79   AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited);
80   if(it.isEnd()) {
81     _edge = 0;
82         return 0;
83   }
84   if (traverse(it) < 0)
85         return -1;
86   _edge = result;
87   if(_edge == 0)
88     return 0;
89   if(_edge->B() == vertex)
90     _orientation = true;
91   else
92     _orientation = false;
93   return 0;
94 }
95
96 //
97 // ChainSilhouetteIterators
98 //
99 ///////////////////////////////////////////////////////////
100
101 int ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait){
102   AdjacencyIterator it(ait);
103   ViewVertex* nextVertex = getVertex();
104   // we can't get a NULL nextVertex here, it was intercepted
105   // before
106   if(nextVertex->getNature() & Nature::T_VERTEX){
107     TVertex * tvertex = (TVertex*)nextVertex;
108     ViewEdge *mate = (tvertex)->mate(getCurrentEdge());
109     while(!it.isEnd()){
110       ViewEdge *ve = *it;
111           if(ve == mate) {
112             result = ve;
113         return 0;
114           }
115       ++it;
116     }
117     result = 0;
118         return 0;
119   }
120   if(nextVertex->getNature() & Nature::NON_T_VERTEX){
121     //soc NonTVertex * nontvertex = (NonTVertex*)nextVertex;
122     ViewEdge * newEdge(0);
123     // we'll try to chain the edges by keeping the same nature...
124     // the preseance order is : SILHOUETTE, BORDER, CREASE, SUGGESTIVE, VALLEY, RIDGE
125     Nature::EdgeNature natures[6] = {Nature::SILHOUETTE, Nature::BORDER, Nature::CREASE, Nature::SUGGESTIVE_CONTOUR, Nature::VALLEY, Nature::RIDGE};
126     for(unsigned i=0; i<6; ++i){
127       if(getCurrentEdge()->getNature() & natures[i]){
128         int n = 0;
129         while(!it.isEnd()){
130           ViewEdge *ve = *it;
131           if(ve->getNature() & natures[i]){
132             ++n;
133             newEdge = ve;
134           } 
135           ++it;
136         } 
137         if(n == 1){
138           result = newEdge;
139         }else{
140           result = 0;
141         }   
142                 return 0;
143           } 
144     }
145   }
146   result = 0;
147   return 0;
148 }
149
150 int ChainPredicateIterator::traverse(const AdjacencyIterator& ait){
151   AdjacencyIterator it(ait);
152   // Iterates over next edges to see if one of them 
153   // respects the predicate:
154   while(!it.isEnd()) {
155     ViewEdge *ve = *it;
156         if (_unary_predicate->operator()(*ve) < 0)
157           return -1;
158         if (_unary_predicate->result) {
159           if (_binary_predicate->operator()(*(getCurrentEdge()), *(ve)) < 0)
160                 return -1;
161           if (_binary_predicate->result) {
162         result = ve;
163             return 0;
164           }
165         }
166     ++it;
167   }
168   result = 0;
169   return 0;
170