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