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 /** \file
18  * \ingroup freestyle
19  * \brief Classes to define a View Map (ViewVertex, ViewEdge, etc.)
20  */
21 
22 #include <float.h>
23 
24 #include "ViewMap.h"
25 #include "ViewMapAdvancedIterators.h"
26 #include "ViewMapIterators.h"
27 
28 #include "../geometry/GeomUtils.h"
29 
30 namespace Freestyle {
31 
32 /**********************************/
33 /*                                */
34 /*                                */
35 /*             ViewMap            */
36 /*                                */
37 /*                                */
38 /**********************************/
39 
40 ViewMap *ViewMap::_pInstance = NULL;
41 
~ViewMap()42 ViewMap::~ViewMap()
43 {
44   // The view vertices must be deleted here as some of them are shared between two shapes:
45   for (vector<ViewVertex *>::iterator vv = _VVertices.begin(), vvend = _VVertices.end();
46        vv != vvend;
47        vv++) {
48     delete (*vv);
49   }
50   _VVertices.clear();
51 
52   for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
53        vs++) {
54     delete (*vs);
55   }
56   _VShapes.clear();
57 
58   _FEdges.clear();
59   _SVertices.clear();
60   _VEdges.clear();
61 }
62 
Clean()63 void ViewMap::Clean()
64 {
65   vector<FEdge *> tmpEdges;
66 
67   for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
68        vs++) {
69     vector<FEdge *> &edges = (*vs)->sshape()->getEdgeList();
70     for (vector<FEdge *>::iterator it = edges.begin(), itend = edges.end(); it != itend; it++) {
71       if ((*it)->isTemporary()) {
72         (*it)->setTemporary(false);  // avoid being counted multiple times
73         tmpEdges.push_back(*it);
74       }
75     }
76   }
77 
78   for (vector<FEdge *>::iterator it = tmpEdges.begin(), itend = tmpEdges.end(); it != itend;
79        it++) {
80     for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
81          vs++) {
82       (*vs)->sshape()->RemoveEdge(*it);
83     }
84     (*it)->vertexA()->RemoveFEdge(*it);
85     (*it)->vertexB()->RemoveFEdge(*it);
86     delete (*it);
87   }
88 }
89 
viewShape(unsigned id)90 ViewShape *ViewMap::viewShape(unsigned id)
91 {
92   int index = _shapeIdToIndex[id];
93   return _VShapes[index];
94 }
95 
AddViewShape(ViewShape * iVShape)96 void ViewMap::AddViewShape(ViewShape *iVShape)
97 {
98   _shapeIdToIndex[iVShape->getId().getFirst()] = _VShapes.size();
99   _VShapes.push_back(iVShape);
100 }
101 
getClosestFEdge(real x,real y) const102 const FEdge *ViewMap::getClosestFEdge(real x, real y) const
103 {
104   // find the closest of this candidates:
105   real minDist = DBL_MAX;
106   FEdge *winner = NULL;
107   for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend;
108        fe++) {
109     Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
110     Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
111     real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
112     if (dist < minDist) {
113       minDist = dist;
114       winner = (*fe);
115     }
116   }
117 
118   return winner;
119 }
120 
getClosestViewEdge(real x,real y) const121 const ViewEdge *ViewMap::getClosestViewEdge(real x, real y) const
122 {
123   // find the closest of this candidates:
124   real minDist = DBL_MAX;
125   FEdge *winner = NULL;
126   for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend;
127        fe++) {
128     Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
129     Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
130     real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
131     if (dist < minDist) {
132       minDist = dist;
133       winner = (*fe);
134     }
135   }
136   if (!winner) {
137     return NULL;
138   }
139 
140   return winner->viewedge();
141 }
142 
CreateTVertex(const Vec3r & iA3D,const Vec3r & iA2D,FEdge * iFEdgeA,const Vec3r & iB3D,const Vec3r & iB2D,FEdge * iFEdgeB,const Id & id)143 TVertex *ViewMap::CreateTVertex(const Vec3r &iA3D,
144                                 const Vec3r &iA2D,
145                                 FEdge *iFEdgeA,
146                                 const Vec3r &iB3D,
147                                 const Vec3r &iB2D,
148                                 FEdge *iFEdgeB,
149                                 const Id &id)
150 {
151   ViewShape *vshapeA = iFEdgeA->viewedge()->viewShape();
152   SShape *shapeA = iFEdgeA->shape();
153   ViewShape *vshapeB = iFEdgeB->viewedge()->viewShape();
154   SShape *shapeB = iFEdgeB->shape();
155 
156   SVertex *Ia = shapeA->CreateSVertex(iA3D, iA2D, iFEdgeA->vertexA()->getId());
157   SVertex *Ib = shapeB->CreateSVertex(iB3D, iB2D, iFEdgeB->vertexA()->getId());
158 
159   // depending on which of these 2 svertices is the nearest from the viewpoint, we're going to
160   // build the TVertex by giving them in an order or another (the first one must be the nearest)
161   real dista = Ia->point2D()[2];
162   real distb = Ib->point2D()[2];
163 
164   TVertex *tvertex;
165   if (dista < distb) {
166     tvertex = new TVertex(Ia, Ib);
167   }
168   else {
169     tvertex = new TVertex(Ib, Ia);
170   }
171 
172   tvertex->setId(id);
173 
174   // add these vertices to the view map
175   AddViewVertex(tvertex);
176   AddSVertex(Ia);
177   AddSVertex(Ib);
178 
179   // and this T Vertex to the view shapes:
180   vshapeA->AddVertex(tvertex);
181   vshapeB->AddVertex(tvertex);
182 
183   return tvertex;
184 }
185 
InsertViewVertex(SVertex * iVertex,vector<ViewEdge * > & newViewEdges)186 ViewVertex *ViewMap::InsertViewVertex(SVertex *iVertex, vector<ViewEdge *> &newViewEdges)
187 {
188   NonTVertex *vva = dynamic_cast<NonTVertex *>(iVertex->viewvertex());
189   if (vva) {
190     return vva;
191   }
192   // because it is not already a ViewVertex, this SVertex must have only 2 FEdges. The incoming one
193   // still belongs to ioEdge, the outgoing one now belongs to newVEdge
194   const vector<FEdge *> &fedges = iVertex->fedges();
195   if (fedges.size() != 2) {
196     cerr << "ViewMap warning: Can't split the ViewEdge" << endl;
197     return NULL;
198   }
199   FEdge *fend(NULL), *fbegin(NULL);
200   for (vector<FEdge *>::const_iterator fe = fedges.begin(), feend = fedges.end(); fe != feend;
201        ++fe) {
202     if ((*fe)->vertexB() == iVertex) {
203       fend = (*fe);
204     }
205     if ((*fe)->vertexA() == iVertex) {
206       fbegin = (*fe);
207     }
208     if ((fbegin != NULL) && (fend != NULL)) {
209       break;
210     }
211   }
212   ViewEdge *ioEdge = fbegin->viewedge();
213   ViewShape *vshape = ioEdge->viewShape();
214   vva = new NonTVertex(iVertex);
215   // if the ViewEdge is a closed loop, we don't create a new VEdge
216   if (ioEdge->A() == 0) {
217     // closed loop
218     ioEdge->setA(vva);
219     ioEdge->setB(vva);
220     // update sshape
221     vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeA());
222     vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeB());
223 
224     ioEdge->setFEdgeA(fbegin);
225     ioEdge->setFEdgeB(fend);
226 
227     // Update FEdges
228     fend->setNextEdge(NULL);
229     fbegin->setPreviousEdge(NULL);
230 
231     // update new View Vertex:
232     vva->AddOutgoingViewEdge(ioEdge);
233     vva->AddIncomingViewEdge(ioEdge);
234 
235     vshape->sshape()->AddChain(ioEdge->fedgeA());
236     vshape->sshape()->AddChain(ioEdge->fedgeB());
237   }
238   else {
239     // Create new ViewEdge
240     ViewEdge *newVEdge = new ViewEdge(vva, ioEdge->B(), fbegin, ioEdge->fedgeB(), vshape);
241     newVEdge->setId(Id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1));
242     newVEdge->setNature(ioEdge->getNature());
243     // newVEdge->UpdateFEdges(); // done in the ViewEdge constructor
244     // Update old ViewEdge
245     ioEdge->setB(vva);
246     ioEdge->setFEdgeB(fend);
247 
248     // Update FEdges
249     fend->setNextEdge(NULL);
250     fbegin->setPreviousEdge(NULL);
251 
252     // update new View Vertex:
253     vva->AddOutgoingViewEdge(newVEdge);
254     vva->AddIncomingViewEdge(ioEdge);
255 
256     NonTVertex *vvb = dynamic_cast<NonTVertex *>(newVEdge->B());
257     if (vvb) {
258       vvb->Replace(ioEdge, newVEdge);
259     }
260 
261     // update ViewShape
262     // vshape->AddEdge(newVEdge);
263     // update SShape
264     vshape->sshape()->AddChain(fbegin);
265     // update ViewMap
266     //_VEdges.push_back(newVEdge);
267     newViewEdges.push_back(newVEdge);
268   }
269 
270   // update ViewShape
271   vshape->AddVertex(vva);
272 
273   // update ViewMap
274   _VVertices.push_back(vva);
275 
276   return vva;
277 }
278 
279 #if 0
280 FEdge *ViewMap::Connect(FEdge *ioEdge, SVertex *ioVertex, vector<ViewEdge *> &oNewVEdges)
281 {
282   SShape *sshape = ioEdge->shape();
283   FEdge *newFEdge = sshape->SplitEdgeIn2(ioEdge, ioVertex);
284   AddFEdge(newFEdge);
285   InsertViewVertex(ioVertex, oNewVEdges);
286   return newFEdge;
287 }
288 #endif
289 
290 /**********************************/
291 /*                                */
292 /*                                */
293 /*             TVertex            */
294 /*                                */
295 /*                                */
296 /**********************************/
297 
298 // is dve1 before dve2 ? (does it have a smaller angle ?)
ViewEdgeComp(ViewVertex::directedViewEdge & dve1,ViewVertex::directedViewEdge & dve2)299 static bool ViewEdgeComp(ViewVertex::directedViewEdge &dve1, ViewVertex::directedViewEdge &dve2)
300 {
301   FEdge *fe1;
302   if (dve1.second) {
303     fe1 = dve1.first->fedgeB();
304   }
305   else {
306     fe1 = dve1.first->fedgeA();
307   }
308   FEdge *fe2;
309   if (dve2.second) {
310     fe2 = dve2.first->fedgeB();
311   }
312   else {
313     fe2 = dve2.first->fedgeA();
314   }
315 
316   Vec3r V1 = fe1->orientation2d();
317   Vec2r v1(V1.x(), V1.y());
318   v1.normalize();
319   Vec3r V2 = fe2->orientation2d();
320   Vec2r v2(V2.x(), V2.y());
321   v2.normalize();
322   if (v1.y() > 0) {
323     if (v2.y() < 0) {
324       return true;
325     }
326 
327     return (v1.x() > v2.x());
328   }
329 
330   if (v2.y() > 0) {
331     return false;
332   }
333 
334   return (v1.x() < v2.x());
335 
336   return false;
337 }
338 
setFrontEdgeA(ViewEdge * iFrontEdgeA,bool incoming)339 void TVertex::setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming)
340 {
341   if (!iFrontEdgeA) {
342     cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeA()" << endl;
343     return;
344   }
345   _FrontEdgeA = directedViewEdge(iFrontEdgeA, incoming);
346   if (!_sortedEdges.empty()) {
347     edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
348     for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeA); ++dve) {
349       /* pass */
350     }
351     _sortedEdges.insert(dve, &_FrontEdgeA);
352   }
353   else {
354     _sortedEdges.push_back(&_FrontEdgeA);
355   }
356 }
357 
setFrontEdgeB(ViewEdge * iFrontEdgeB,bool incoming)358 void TVertex::setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming)
359 {
360   if (!iFrontEdgeB) {
361     cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeB()" << endl;
362     return;
363   }
364   _FrontEdgeB = directedViewEdge(iFrontEdgeB, incoming);
365   if (!_sortedEdges.empty()) {
366     edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
367     for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeB); ++dve) {
368       /* pass */
369     }
370     _sortedEdges.insert(dve, &_FrontEdgeB);
371   }
372   else {
373     _sortedEdges.push_back(&_FrontEdgeB);
374   }
375 }
376 
setBackEdgeA(ViewEdge * iBackEdgeA,bool incoming)377 void TVertex::setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming)
378 {
379   if (!iBackEdgeA) {
380     cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeA()" << endl;
381     return;
382   }
383   _BackEdgeA = directedViewEdge(iBackEdgeA, incoming);
384   if (!_sortedEdges.empty()) {
385     edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
386     for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeA); ++dve) {
387       /* pass */
388     }
389     _sortedEdges.insert(dve, &_BackEdgeA);
390   }
391   else {
392     _sortedEdges.push_back(&_BackEdgeA);
393   }
394 }
395 
setBackEdgeB(ViewEdge * iBackEdgeB,bool incoming)396 void TVertex::setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming)
397 {
398   if (!iBackEdgeB) {
399     cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeB()" << endl;
400     return;
401   }
402   _BackEdgeB = directedViewEdge(iBackEdgeB, incoming);
403   if (!_sortedEdges.empty()) {
404     edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
405     for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeB); ++dve) {
406       /* pass */
407     }
408     _sortedEdges.insert(dve, &_BackEdgeB);
409   }
410   else {
411     _sortedEdges.push_back(&_BackEdgeB);
412   }
413 }
414 
Replace(ViewEdge * iOld,ViewEdge * iNew)415 void TVertex::Replace(ViewEdge *iOld, ViewEdge *iNew)
416 {
417   // theoritically, we only replace edges for which this
418   // view vertex is the B vertex
419   if ((iOld == _FrontEdgeA.first) && (_FrontEdgeA.first->B() == this)) {
420     _FrontEdgeA.first = iNew;
421     return;
422   }
423   if ((iOld == _FrontEdgeB.first) && (_FrontEdgeB.first->B() == this)) {
424     _FrontEdgeB.first = iNew;
425     return;
426   }
427   if ((iOld == _BackEdgeA.first) && (_BackEdgeA.first->B() == this)) {
428     _BackEdgeA.first = iNew;
429     return;
430   }
431   if ((iOld == _BackEdgeB.first) && (_BackEdgeB.first->B() == this)) {
432     _BackEdgeB.first = iNew;
433     return;
434   }
435 }
436 
437 /*! iterators access */
edges_begin()438 ViewVertex::edge_iterator TVertex::edges_begin()
439 {
440   // return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
441   return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
442 }
443 
edges_begin() const444 ViewVertex::const_edge_iterator TVertex::edges_begin() const
445 {
446   // return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
447   return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
448 }
449 
edges_end()450 ViewVertex::edge_iterator TVertex::edges_end()
451 {
452   // return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB,
453   // directedViewEdge(0,true));
454   return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
455 }
456 
edges_end() const457 ViewVertex::const_edge_iterator TVertex::edges_end() const
458 {
459   // return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB,
460   // directedViewEdge(0, true));
461   return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
462 }
463 
edges_iterator(ViewEdge * iEdge)464 ViewVertex::edge_iterator TVertex::edges_iterator(ViewEdge *iEdge)
465 {
466   for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end();
467        it != itend;
468        it++) {
469     if ((*it)->first == iEdge) {
470       return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
471     }
472   }
473   return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
474 
475 #if 0
476   directedViewEdge dEdge;
477   if (_FrontEdgeA.first == iEdge) {
478     dEdge = _FrontEdgeA;
479   }
480   else if (_FrontEdgeB.first == iEdge) {
481     dEdge = _FrontEdgeB;
482   }
483   else if (_BackEdgeA.first == iEdge) {
484     dEdge = _BackEdgeA;
485   }
486   else if (_BackEdgeB.first == iEdge) {
487     dEdge = _BackEdgeB;
488   }
489   return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
490 #endif
491 }
492 
edges_iterator(ViewEdge * iEdge) const493 ViewVertex::const_edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) const
494 {
495   for (edge_pointers_container::const_iterator it = _sortedEdges.begin(),
496                                                itend = _sortedEdges.end();
497        it != itend;
498        it++) {
499     if ((*it)->first == iEdge) {
500       return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
501     }
502   }
503   return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
504 
505 #if 0
506   directedViewEdge dEdge;
507   if (_FrontEdgeA.first == iEdge) {
508     dEdge = _FrontEdgeA;
509   }
510   else if (_FrontEdgeB.first == iEdge) {
511     dEdge = _FrontEdgeB;
512   }
513   else if (_BackEdgeA.first == iEdge) {
514     dEdge = _BackEdgeA;
515   }
516   else if (_BackEdgeB.first == iEdge) {
517     dEdge = _BackEdgeB;
518   }
519   return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
520 #endif
521 }
522 
edgesBegin()523 ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesBegin()
524 {
525   return ViewVertexInternal::orientedViewEdgeIterator(
526       _sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
527 }
528 
edgesEnd()529 ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesEnd()
530 {
531   return ViewVertexInternal::orientedViewEdgeIterator(
532       _sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
533 }
534 
edgesIterator(ViewEdge * iEdge)535 ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesIterator(ViewEdge *iEdge)
536 {
537   for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end();
538        it != itend;
539        it++) {
540     if ((*it)->first == iEdge) {
541       return ViewVertexInternal::orientedViewEdgeIterator(
542           _sortedEdges.begin(), _sortedEdges.end(), it);
543     }
544   }
545   return ViewVertexInternal::orientedViewEdgeIterator(
546       _sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
547 }
548 
549 /**********************************/
550 /*                                */
551 /*                                */
552 /*             NonTVertex         */
553 /*                                */
554 /*                                */
555 /**********************************/
556 
AddOutgoingViewEdge(ViewEdge * iVEdge)557 void NonTVertex::AddOutgoingViewEdge(ViewEdge *iVEdge)
558 {
559   // let's keep the viewedges ordered in CCW order in the 2D image plan
560   directedViewEdge idve(iVEdge, false);
561   if (!_ViewEdges.empty()) {
562     edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
563     for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve) {
564       /* pass */
565     }
566     _ViewEdges.insert(dve, idve);
567   }
568   else {
569     _ViewEdges.push_back(idve);
570   }
571 }
572 
AddIncomingViewEdge(ViewEdge * iVEdge)573 void NonTVertex::AddIncomingViewEdge(ViewEdge *iVEdge)
574 {
575   // let's keep the viewedges ordered in CCW order in the 2D image plan
576   directedViewEdge idve(iVEdge, true);
577   if (!_ViewEdges.empty()) {
578     edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
579     for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve) {
580       /* pass */
581     }
582     _ViewEdges.insert(dve, idve);
583   }
584   else {
585     _ViewEdges.push_back(idve);
586   }
587 }
588 
589 /*! iterators access */
edges_begin()590 ViewVertex::edge_iterator NonTVertex::edges_begin()
591 {
592   return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
593 }
594 
edges_begin() const595 ViewVertex::const_edge_iterator NonTVertex::edges_begin() const
596 {
597   return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
598 }
599 
edges_end()600 ViewVertex::edge_iterator NonTVertex::edges_end()
601 {
602   return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
603 }
604 
edges_end() const605 ViewVertex::const_edge_iterator NonTVertex::edges_end() const
606 {
607   return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
608 }
609 
edges_iterator(ViewEdge * iEdge)610 ViewVertex::edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge)
611 {
612   for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend;
613        it++) {
614     if ((it)->first == iEdge) {
615       return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
616     }
617   }
618   return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
619 }
620 
edges_iterator(ViewEdge * iEdge) const621 ViewVertex::const_edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge) const
622 {
623   for (edges_container::const_iterator it = _ViewEdges.begin(), itend = _ViewEdges.end();
624        it != itend;
625        it++) {
626     if ((it)->first == iEdge) {
627       return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
628     }
629   }
630   return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
631 }
632 
edgesBegin()633 ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesBegin()
634 {
635   return ViewVertexInternal::orientedViewEdgeIterator(
636       _ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
637 }
638 
edgesEnd()639 ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesEnd()
640 {
641   return ViewVertexInternal::orientedViewEdgeIterator(
642       _ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
643 }
644 
edgesIterator(ViewEdge * iEdge)645 ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesIterator(ViewEdge *iEdge)
646 {
647   for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend;
648        it++) {
649     if ((it)->first == iEdge) {
650       return ViewVertexInternal::orientedViewEdgeIterator(
651           _ViewEdges.begin(), _ViewEdges.end(), it);
652     }
653   }
654   return ViewVertexInternal::orientedViewEdgeIterator(
655       _ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
656 }
657 
658 /**********************************/
659 /*                                */
660 /*                                */
661 /*             ViewEdge           */
662 /*                                */
663 /*                                */
664 /**********************************/
665 
getLength2D() const666 real ViewEdge::getLength2D() const
667 {
668   float length = 0.0f;
669   ViewEdge::const_fedge_iterator itlast = fedge_iterator_last();
670   ViewEdge::const_fedge_iterator it = fedge_iterator_begin(), itend = fedge_iterator_end();
671   Vec2r seg;
672   do {
673     seg = Vec2r((*it)->orientation2d()[0], (*it)->orientation2d()[1]);
674     length += seg.norm();
675     ++it;
676   } while ((it != itend) && (it != itlast));
677   return length;
678 }
679 
680 //! view edge iterator
ViewEdge_iterator()681 ViewEdge::edge_iterator ViewEdge::ViewEdge_iterator()
682 {
683   return edge_iterator(this);
684 }
685 
ViewEdge_iterator() const686 ViewEdge::const_edge_iterator ViewEdge::ViewEdge_iterator() const
687 {
688   return const_edge_iterator((ViewEdge *)this);
689 }
690 
691 //! feature edge iterator
fedge_iterator_begin()692 ViewEdge::fedge_iterator ViewEdge::fedge_iterator_begin()
693 {
694   return fedge_iterator(this->_FEdgeA, this->_FEdgeB);
695 }
696 
fedge_iterator_begin() const697 ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_begin() const
698 {
699   return const_fedge_iterator(this->_FEdgeA, this->_FEdgeB);
700 }
701 
fedge_iterator_last()702 ViewEdge::fedge_iterator ViewEdge::fedge_iterator_last()
703 {
704   return fedge_iterator(this->_FEdgeB, this->_FEdgeB);
705 }
706 
fedge_iterator_last() const707 ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_last() const
708 {
709   return const_fedge_iterator(this->_FEdgeB, this->_FEdgeB);
710 }
711 
fedge_iterator_end()712 ViewEdge::fedge_iterator ViewEdge::fedge_iterator_end()
713 {
714   return fedge_iterator(0, this->_FEdgeB);
715 }
716 
fedge_iterator_end() const717 ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_end() const
718 {
719   return const_fedge_iterator(0, this->_FEdgeB);
720 }
721 
722 //! embedding vertex iterator
vertices_begin() const723 ViewEdge::const_vertex_iterator ViewEdge::vertices_begin() const
724 {
725   return const_vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
726 }
727 
vertices_begin()728 ViewEdge::vertex_iterator ViewEdge::vertices_begin()
729 {
730   return vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);
731 }
732 
vertices_last() const733 ViewEdge::const_vertex_iterator ViewEdge::vertices_last() const
734 {
735   return const_vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);
736 }
737 
vertices_last()738 ViewEdge::vertex_iterator ViewEdge::vertices_last()
739 {
740   return vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);
741 }
742 
vertices_end() const743 ViewEdge::const_vertex_iterator ViewEdge::vertices_end() const
744 {
745   return const_vertex_iterator(0, _FEdgeB, 0);
746 }
747 
vertices_end()748 ViewEdge::vertex_iterator ViewEdge::vertices_end()
749 {
750   return vertex_iterator(0, _FEdgeB, 0);
751 }
752 
verticesBegin()753 Interface0DIterator ViewEdge::verticesBegin()
754 {
755   Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(
756       this->_FEdgeA->vertexA(), this->_FEdgeA->vertexA(), NULL, _FEdgeA, 0.0f));
757   return ret;
758 }
759 
verticesEnd()760 Interface0DIterator ViewEdge::verticesEnd()
761 {
762   Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(
763       NULL, this->_FEdgeA->vertexA(), _FEdgeB, NULL, getLength2D()));
764   return ret;
765 }
766 
pointsBegin(float)767 Interface0DIterator ViewEdge::pointsBegin(float /*t*/)
768 {
769   return verticesBegin();
770 }
771 
pointsEnd(float)772 Interface0DIterator ViewEdge::pointsEnd(float /*t*/)
773 {
774   return verticesEnd();
775 }
776 
777 /**********************************/
778 /*                                */
779 /*                                */
780 /*             ViewShape          */
781 /*                                */
782 /*                                */
783 /**********************************/
784 
~ViewShape()785 ViewShape::~ViewShape()
786 {
787   _Vertices.clear();
788 
789   if (!(_Edges.empty())) {
790     for (vector<ViewEdge *>::iterator e = _Edges.begin(), eend = _Edges.end(); e != eend; e++) {
791       delete (*e);
792     }
793     _Edges.clear();
794   }
795 
796   if (_SShape) {
797     delete _SShape;
798     _SShape = NULL;
799   }
800 }
801 
RemoveEdge(ViewEdge * iViewEdge)802 void ViewShape::RemoveEdge(ViewEdge *iViewEdge)
803 {
804   FEdge *fedge = iViewEdge->fedgeA();
805   for (vector<ViewEdge *>::iterator ve = _Edges.begin(), veend = _Edges.end(); ve != veend; ve++) {
806     if (iViewEdge == (*ve)) {
807       _Edges.erase(ve);
808       _SShape->RemoveEdge(fedge);
809       break;
810     }
811   }
812 }
813 
RemoveVertex(ViewVertex * iViewVertex)814 void ViewShape::RemoveVertex(ViewVertex *iViewVertex)
815 {
816   for (vector<ViewVertex *>::iterator vv = _Vertices.begin(), vvend = _Vertices.end(); vv != vvend;
817        vv++) {
818     if (iViewVertex == (*vv)) {
819       _Vertices.erase(vv);
820       break;
821     }
822   }
823 }
824 
825 /**********************************/
826 /*                                */
827 /*                                */
828 /*             ViewEdge           */
829 /*                                */
830 /*                                */
831 /**********************************/
832 
UpdateFEdges()833 void ViewEdge::UpdateFEdges()
834 {
835   FEdge *currentEdge = _FEdgeA;
836   do {
837     currentEdge->setViewEdge(this);
838     currentEdge = currentEdge->nextEdge();
839   } while ((currentEdge != NULL) && (currentEdge != _FEdgeB));
840   // last one
841   _FEdgeB->setViewEdge(this);
842 }
843 
844 } /* namespace Freestyle */
845