Blender V4.3
ViewEdgeXBuilder.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include <list>
11
13#include "ViewEdgeXBuilder.h"
14#include "ViewMap.h"
15
17
18#include "BLI_sys_types.h"
19
20using namespace std;
21
22namespace Freestyle {
23
25{
26 if (nullptr == oVShape) {
27 return;
28 }
29
30 // for design convenience, we store the current SShape.
31 _pCurrentSShape = oVShape->sshape();
32 if (nullptr == _pCurrentSShape) {
33 return;
34 }
35
36 _pCurrentVShape = oVShape;
37
38 // Reset previous data
39 //--------------------
40 if (!_SVertexMap.empty()) {
41 _SVertexMap.clear();
42 }
43}
44
46 ViewShape *oVShape,
47 vector<ViewEdge *> &ioVEdges,
48 vector<ViewVertex *> &ioVVertices,
49 vector<FEdge *> &ioFEdges,
50 vector<SVertex *> &ioSVertices)
51{
52 // Reinit structures
53 Init(oVShape);
54
55 // ViewEdge *vedge; /* UNUSED. */
56
57 // Let us build the smooth stuff
58 //----------------------------------------
59 // We parse all faces to find the ones that contain smooth edges
60 vector<WFace *> &wfaces = iWShape->GetFaceList();
61 vector<WFace *>::iterator wf, wfend;
62 WXFace *wxf;
63 for (wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; wf++) {
64 wxf = dynamic_cast<WXFace *>(*wf);
65 if (false == (wxf)->hasSmoothEdges()) { // does it contain at least one smooth edge ?
66 continue;
67 }
68 // parse all smooth layers:
69 vector<WXFaceLayer *> &smoothLayers = wxf->getSmoothLayers();
70 for (vector<WXFaceLayer *>::iterator sl = smoothLayers.begin(), slend = smoothLayers.end();
71 sl != slend;
72 ++sl)
73 {
74 if (!(*sl)->hasSmoothEdge()) {
75 continue;
76 }
77 if (stopSmoothViewEdge(*sl)) { // has it been parsed already ?
78 continue;
79 }
80 // here we know that we're dealing with a face layer that has not been processed yet and that
81 // contains a smooth edge.
82 /* vedge =*//* UNUSED */ BuildSmoothViewEdge(OWXFaceLayer(*sl, true));
83 }
84 }
85
86 // Now let's build sharp view edges:
87 //----------------------------------
88 // Reset all userdata for WXEdge structure
89 //----------------------------------------
90 // iWShape->ResetUserData();
91
92 WXEdge *wxe;
93 vector<WEdge *> &wedges = iWShape->getEdgeList();
94 //------------------------------
95 for (vector<WEdge *>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; we++) {
96 wxe = dynamic_cast<WXEdge *>(*we);
97 if (Nature::NO_FEATURE == wxe->nature()) {
98 continue;
99 }
100
101 if (!stopSharpViewEdge(wxe)) {
102 bool b = true;
103 if (wxe->order() == -1) {
104 b = false;
105 }
107 }
108 }
109
110 // Reset all userdata for WXEdge structure
111 //----------------------------------------
112 iWShape->ResetUserData();
113
114 // Add all these new edges to the scene's feature edges list:
115 //-----------------------------------------------------------
116 vector<FEdge *> &newedges = _pCurrentSShape->getEdgeList();
117 vector<SVertex *> &newVertices = _pCurrentSShape->getVertexList();
118 vector<ViewVertex *> &newVVertices = _pCurrentVShape->vertices();
119 vector<ViewEdge *> &newVEdges = _pCurrentVShape->edges();
120
121 // inserts in ioFEdges, at its end, all the edges of newedges
122 ioFEdges.insert(ioFEdges.end(), newedges.begin(), newedges.end());
123 ioSVertices.insert(ioSVertices.end(), newVertices.begin(), newVertices.end());
124 ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end());
125 ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end());
126}
127
129{
130 // Find first edge:
131 OWXFaceLayer first = iFaceLayer;
132 OWXFaceLayer currentFace = first;
133
134 // bidirectional chaining.
135 // first direction
136 list<OWXFaceLayer> facesChain;
137 uint size = 0;
138 while (!stopSmoothViewEdge(currentFace.fl)) {
139 facesChain.push_back(currentFace);
140 ++size;
141 currentFace.fl->userdata = (void *)1; // processed
142 // Find the next edge!
143 currentFace = FindNextFaceLayer(currentFace);
144 }
145 OWXFaceLayer end = facesChain.back();
146 // second direction
147 currentFace = FindPreviousFaceLayer(first);
148 while (!stopSmoothViewEdge(currentFace.fl)) {
149 facesChain.push_front(currentFace);
150 ++size;
151 currentFace.fl->userdata = (void *)1; // processed
152 // Find the previous edge!
153 currentFace = FindPreviousFaceLayer(currentFace);
154 }
155 first = facesChain.front();
156
157 if (iFaceLayer.fl->nature() & Nature::RIDGE) {
158 if (size < 4) {
159 return nullptr;
160 }
161 }
162
163 // Start a new chain edges
164 ViewEdge *newVEdge = new ViewEdge;
165 newVEdge->setId(_currentViewId);
167
168 _pCurrentVShape->AddEdge(newVEdge);
169
170 // build FEdges
171 FEdge *feprevious = nullptr;
172 FEdge *fefirst = nullptr;
173 FEdge *fe = nullptr;
174 for (list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend = facesChain.end(); fl != flend;
175 ++fl)
176 {
177 fe = BuildSmoothFEdge(feprevious, (*fl));
178 if (feprevious && fe == feprevious) {
179 continue;
180 }
181 fe->setViewEdge(newVEdge);
182 if (!fefirst) {
183 fefirst = fe;
184 }
185 feprevious = fe;
186 }
187 // Store the chain starting edge:
188 _pCurrentSShape->AddChain(fefirst);
189 newVEdge->setNature(iFaceLayer.fl->nature());
190 newVEdge->setFEdgeA(fefirst);
191 newVEdge->setFEdgeB(fe);
192
193 // is it a closed loop ?
194 if ((first == end) && (size != 1)) {
195 fefirst->setPreviousEdge(fe);
196 fe->setNextEdge(fefirst);
197 newVEdge->setA(nullptr);
198 newVEdge->setB(nullptr);
199 }
200 else {
201 ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
202 ViewVertex *vvb = MakeViewVertex(fe->vertexB());
203
204 ((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge);
205 ((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge);
206
207 newVEdge->setA(vva);
208 newVEdge->setB(vvb);
209 }
210
211 return newVEdge;
212}
213
215{
216 // Start a new sharp chain edges
217 ViewEdge *newVEdge = new ViewEdge;
218 newVEdge->setId(_currentViewId);
220 uint size = 0;
221
222 _pCurrentVShape->AddEdge(newVEdge);
223
224 // Find first edge:
225 OWXEdge firstWEdge = iWEdge;
226 // OWXEdge previousWEdge = firstWEdge; /* UNUSED */
227 OWXEdge currentWEdge = firstWEdge;
228 list<OWXEdge> edgesChain;
229#if 0 /* TK 02-Sep-2012 Experimental fix for incorrect view edge visibility. */
230 // bidirectional chaining
231 // first direction:
232 while (!stopSharpViewEdge(currentWEdge.e)) {
233 edgesChain.push_back(currentWEdge);
234 ++size;
235 currentWEdge.e->userdata = (void *)1; // processed
236 // Find the next edge!
237 currentWEdge = FindNextWEdge(currentWEdge);
238 }
239 OWXEdge endWEdge = edgesChain.back();
240 // second direction
241 currentWEdge = FindPreviousWEdge(firstWEdge);
242 while (!stopSharpViewEdge(currentWEdge.e)) {
243 edgesChain.push_front(currentWEdge);
244 ++size;
245 currentWEdge.e->userdata = (void *)1; // processed
246 // Find the previous edge!
247 currentWEdge = FindPreviousWEdge(currentWEdge);
248 }
249#else
250 edgesChain.push_back(currentWEdge);
251 ++size;
252 currentWEdge.e->userdata = (void *)1; // processed
253 OWXEdge endWEdge = edgesChain.back();
254#endif
255 firstWEdge = edgesChain.front();
256
257 // build FEdges
258 FEdge *feprevious = nullptr;
259 FEdge *fefirst = nullptr;
260 FEdge *fe = nullptr;
261 for (list<OWXEdge>::iterator we = edgesChain.begin(), weend = edgesChain.end(); we != weend;
262 ++we)
263 {
264 fe = BuildSharpFEdge(feprevious, (*we));
265 fe->setViewEdge(newVEdge);
266 if (!fefirst) {
267 fefirst = fe;
268 }
269 feprevious = fe;
270 }
271 // Store the chain starting edge:
272 _pCurrentSShape->AddChain(fefirst);
273 newVEdge->setNature(iWEdge.e->nature());
274 newVEdge->setFEdgeA(fefirst);
275 newVEdge->setFEdgeB(fe);
276
277 // is it a closed loop ?
278 if ((firstWEdge == endWEdge) && (size != 1)) {
279 fefirst->setPreviousEdge(fe);
280 fe->setNextEdge(fefirst);
281 newVEdge->setA(nullptr);
282 newVEdge->setB(nullptr);
283 }
284 else {
285 ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
286 ViewVertex *vvb = MakeViewVertex(fe->vertexB());
287
288 ((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge);
289 ((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge);
290
291 newVEdge->setA(vva);
292 newVEdge->setB(vvb);
293 }
294
295 return newVEdge;
296}
297
299{
300 WXFace *nextFace = nullptr;
301 WOEdge *woeend;
302 real tend;
303 if (iFaceLayer.order) {
304 woeend = iFaceLayer.fl->getSmoothEdge()->woeb();
305 tend = iFaceLayer.fl->getSmoothEdge()->tb();
306 }
307 else {
308 woeend = iFaceLayer.fl->getSmoothEdge()->woea();
309 tend = iFaceLayer.fl->getSmoothEdge()->ta();
310 }
311 // special case of EDGE_VERTEX config:
312 if (ELEM(tend, 0.0, 1.0)) {
313 WVertex *nextVertex;
314 if (tend == 0.0) {
315 nextVertex = woeend->GetaVertex();
316 }
317 else {
318 nextVertex = woeend->GetbVertex();
319 }
320 if (nextVertex->isBoundary()) { // if it's a non-manifold vertex -> ignore
321 return OWXFaceLayer(nullptr, true);
322 }
323 bool found = false;
324 WVertex::face_iterator f = nextVertex->faces_begin();
325 WVertex::face_iterator fend = nextVertex->faces_end();
326 while ((!found) && (f != fend)) {
327 nextFace = dynamic_cast<WXFace *>(*f);
328 if ((nullptr != nextFace) && (nextFace != iFaceLayer.fl->getFace())) {
329 vector<WXFaceLayer *> sameNatureLayers;
330 nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
331 // don't know... Maybe should test whether this face has also a vertex_edge configuration.
332 if (sameNatureLayers.size() == 1) {
333 WXFaceLayer *winner = sameNatureLayers[0];
334 // check face mark continuity
335 if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) {
336 return OWXFaceLayer(nullptr, true);
337 }
338 if (woeend == winner->getSmoothEdge()->woea()->twin()) {
339 return OWXFaceLayer(winner, true);
340 }
341
342 return OWXFaceLayer(winner, false);
343 }
344 }
345 ++f;
346 }
347 }
348 else {
349 nextFace = dynamic_cast<WXFace *>(iFaceLayer.fl->getFace()->GetBordingFace(woeend));
350 if (!nextFace) {
351 return OWXFaceLayer(nullptr, true);
352 }
353 // if the next face layer has either no smooth edge or no smooth edge of same nature, no next
354 // face
355 if (!nextFace->hasSmoothEdges()) {
356 return OWXFaceLayer(nullptr, true);
357 }
358 vector<WXFaceLayer *> sameNatureLayers;
359 nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
360 // don't know how to deal with several edges of same nature on a single face
361 if (sameNatureLayers.empty() || (sameNatureLayers.size() != 1)) {
362 return OWXFaceLayer(nullptr, true);
363 }
364
365 WXFaceLayer *winner = sameNatureLayers[0];
366 // check face mark continuity
367 if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) {
368 return OWXFaceLayer(nullptr, true);
369 }
370 if (woeend == winner->getSmoothEdge()->woea()->twin()) {
371 return OWXFaceLayer(winner, true);
372 }
373
374 return OWXFaceLayer(winner, false);
375 }
376 return OWXFaceLayer(nullptr, true);
377}
378
380{
381 WXFace *previousFace = nullptr;
382 WOEdge *woebegin;
383 real tend;
384 if (iFaceLayer.order) {
385 woebegin = iFaceLayer.fl->getSmoothEdge()->woea();
386 tend = iFaceLayer.fl->getSmoothEdge()->ta();
387 }
388 else {
389 woebegin = iFaceLayer.fl->getSmoothEdge()->woeb();
390 tend = iFaceLayer.fl->getSmoothEdge()->tb();
391 }
392
393 // special case of EDGE_VERTEX config:
394 if (ELEM(tend, 0.0, 1.0)) {
395 WVertex *previousVertex;
396 if (tend == 0.0) {
397 previousVertex = woebegin->GetaVertex();
398 }
399 else {
400 previousVertex = woebegin->GetbVertex();
401 }
402 if (previousVertex->isBoundary()) { // if it's a non-manifold vertex -> ignore
403 return OWXFaceLayer(nullptr, true);
404 }
405 bool found = false;
406 WVertex::face_iterator f = previousVertex->faces_begin();
407 WVertex::face_iterator fend = previousVertex->faces_end();
408 for (; (!found) && (f != fend); ++f) {
409 previousFace = dynamic_cast<WXFace *>(*f);
410 if ((nullptr != previousFace) && (previousFace != iFaceLayer.fl->getFace())) {
411 vector<WXFaceLayer *> sameNatureLayers;
412 previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
413 // don't know... Maybe should test whether this face has also a vertex_edge configuration
414 if (sameNatureLayers.size() == 1) {
415 WXFaceLayer *winner = sameNatureLayers[0];
416 // check face mark continuity
417 if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) {
418 return OWXFaceLayer(nullptr, true);
419 }
420 if (woebegin == winner->getSmoothEdge()->woeb()->twin()) {
421 return OWXFaceLayer(winner, true);
422 }
423
424 return OWXFaceLayer(winner, false);
425 }
426 }
427 }
428 }
429 else {
430 previousFace = dynamic_cast<WXFace *>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
431 if (nullptr == previousFace) {
432 return OWXFaceLayer(nullptr, true);
433 }
434 // if the next face layer has either no smooth edge or no smooth edge of same nature, no next
435 // face
436 if (!previousFace->hasSmoothEdges()) {
437 return OWXFaceLayer(nullptr, true);
438 }
439 vector<WXFaceLayer *> sameNatureLayers;
440 previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
441 // don't know how to deal with several edges of same nature on a single face
442 if (sameNatureLayers.empty() || (sameNatureLayers.size() != 1)) {
443 return OWXFaceLayer(nullptr, true);
444 }
445
446 WXFaceLayer *winner = sameNatureLayers[0];
447 // check face mark continuity
448 if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) {
449 return OWXFaceLayer(nullptr, true);
450 }
451 if (woebegin == winner->getSmoothEdge()->woeb()->twin()) {
452 return OWXFaceLayer(winner, true);
453 }
454
455 return OWXFaceLayer(winner, false);
456 }
457 return OWXFaceLayer(nullptr, true);
458}
459
461{
462 WOEdge *woea, *woeb;
463 real ta, tb;
464 SVertex *va, *vb;
465 FEdgeSmooth *fe;
466 // retrieve exact silhouette data
467 WXSmoothEdge *se = ifl.fl->getSmoothEdge();
468
469 if (ifl.order) {
470 woea = se->woea();
471 woeb = se->woeb();
472 ta = se->ta();
473 tb = se->tb();
474 }
475 else {
476 woea = se->woeb();
477 woeb = se->woea();
478 ta = se->tb();
479 tb = se->ta();
480 }
481
482 Vec3r normal;
483 // Make the 2 Svertices
484
485 /* That means that we don't have any vertex already built for that face. */
486 if (feprevious == nullptr) {
487 Vec3r A1(woea->GetaVertex()->GetVertex());
488 Vec3r A2(woea->GetbVertex()->GetVertex());
489 Vec3r A(A1 + ta * (A2 - A1));
490
491 va = MakeSVertex(A, false);
492 // Set normal:
493 Vec3r NA1(ifl.fl->getFace()->GetVertexNormal(woea->GetaVertex()));
494 Vec3r NA2(ifl.fl->getFace()->GetVertexNormal(woea->GetbVertex()));
495 Vec3r na((1 - ta) * NA1 + ta * NA2);
496 na.normalize();
497 va->AddNormal(na);
498 normal = na;
499
500 // Set CurvatureInfo
501 CurvatureInfo *curvature_info_a = new CurvatureInfo(
502 *(dynamic_cast<WXVertex *>(woea->GetaVertex())->curvatures()),
503 *(dynamic_cast<WXVertex *>(woea->GetbVertex())->curvatures()),
504 ta);
505 va->setCurvatureInfo(curvature_info_a);
506 }
507 else {
508 va = feprevious->vertexB();
509 }
510
511 Vec3r B1(woeb->GetaVertex()->GetVertex());
512 Vec3r B2(woeb->GetbVertex()->GetVertex());
513 Vec3r B(B1 + tb * (B2 - B1));
514
515 if (feprevious && (B - va->point3D()).norm() < 1.0e-6) {
516 return feprevious;
517 }
518
519 vb = MakeSVertex(B, false);
520 // Set normal:
521 Vec3r NB1(ifl.fl->getFace()->GetVertexNormal(woeb->GetaVertex()));
522 Vec3r NB2(ifl.fl->getFace()->GetVertexNormal(woeb->GetbVertex()));
523 Vec3r nb((1 - tb) * NB1 + tb * NB2);
524 nb.normalize();
525 normal += nb;
526 vb->AddNormal(nb);
527
528 // Set CurvatureInfo
529 CurvatureInfo *curvature_info_b = new CurvatureInfo(
530 *(dynamic_cast<WXVertex *>(woeb->GetaVertex())->curvatures()),
531 *(dynamic_cast<WXVertex *>(woeb->GetbVertex())->curvatures()),
532 tb);
533 vb->setCurvatureInfo(curvature_info_b);
534
535 // Creates the corresponding feature edge
536 fe = new FEdgeSmooth(va, vb);
537 fe->setNature(ifl.fl->nature());
538 fe->setId(_currentFId);
540 fe->setFace(ifl.fl->getFace());
541 fe->setFaceMark(ifl.fl->getFace()->GetMark());
542 if (feprevious == nullptr) {
543 normal.normalize();
544 }
545 fe->setNormal(normal);
546 fe->setPreviousEdge(feprevious);
547 if (feprevious) {
548 feprevious->setNextEdge(fe);
549 }
551 va->AddFEdge(fe);
552 vb->AddFEdge(fe);
553
554 ++_currentFId;
555 ifl.fl->userdata = fe;
556 return fe;
557}
558
560{
561 if (nullptr == iFaceLayer) {
562 return true;
563 }
564 if (iFaceLayer->userdata == nullptr) {
565 return false;
566 }
567 return true;
568}
569
571{
572 WFace *aFace = iEdge->GetaFace();
573 WFace *bFace = iEdge->GetbFace();
574 int result = 0;
575 if (aFace && aFace->GetMark()) {
576 result += 1;
577 }
578 if (bFace && bFace->GetMark()) {
579 result += 2;
580 }
581 return result;
582}
583
585{
586 if (Nature::NO_FEATURE == iEdge.e->nature()) {
587 return OWXEdge(nullptr, true);
588 }
589
590 WVertex *v;
591 if (true == iEdge.order) {
592 v = iEdge.e->GetbVertex();
593 }
594 else {
595 v = iEdge.e->GetaVertex();
596 }
597
598 if (((WXVertex *)v)->isFeature()) {
599 return nullptr; /* XXX eeek? nullptr? OWXEdge(nullptr, true/false)? */
600 }
601
602 int faceMarks = retrieveFaceMarks(iEdge.e);
603 vector<WEdge *> &vEdges = (v)->GetEdges();
604 for (vector<WEdge *>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
605 WXEdge *wxe = dynamic_cast<WXEdge *>(*ve);
606 if (wxe == iEdge.e) {
607 continue; // same edge as the one processed
608 }
609
610 if (wxe->nature() != iEdge.e->nature()) {
611 continue;
612 }
613
614 // check face mark continuity
615 if (retrieveFaceMarks(wxe) != faceMarks) {
616 continue;
617 }
618
619 if (wxe->GetaVertex() == v) {
620 // That means that the face necessarily lies on the edge left.
621 // So the vertex order is OK.
622 return OWXEdge(wxe, true);
623 }
624
625 // That means that the face necessarily lies on the edge left.
626 // So the vertex order is OK.
627 return OWXEdge(wxe, false);
628 }
629 // we did not find:
630 return OWXEdge(nullptr, true);
631}
632
634{
635 if (Nature::NO_FEATURE == iEdge.e->nature()) {
636 return OWXEdge(nullptr, true);
637 }
638
639 WVertex *v;
640 if (true == iEdge.order) {
641 v = iEdge.e->GetaVertex();
642 }
643 else {
644 v = iEdge.e->GetbVertex();
645 }
646
647 if (((WXVertex *)v)->isFeature()) {
648 return nullptr;
649 }
650
651 int faceMarks = retrieveFaceMarks(iEdge.e);
652 vector<WEdge *> &vEdges = (v)->GetEdges();
653 for (vector<WEdge *>::iterator ve = vEdges.begin(), veend = vEdges.end(); ve != veend; ve++) {
654 WXEdge *wxe = dynamic_cast<WXEdge *>(*ve);
655 if (wxe == iEdge.e) {
656 continue; // same edge as the one processed
657 }
658
659 if (wxe->nature() != iEdge.e->nature()) {
660 continue;
661 }
662
663 // check face mark continuity
664 if (retrieveFaceMarks(wxe) != faceMarks) {
665 continue;
666 }
667
668 if (wxe->GetbVertex() == v) {
669 return OWXEdge(wxe, true);
670 }
671
672 return OWXEdge(wxe, false);
673 }
674 // we did not find:
675 return OWXEdge(nullptr, true);
676}
677
679{
680 SVertex *va, *vb;
681 FEdgeSharp *fe;
682 Vec3r vA, vB;
683 if (iwe.order) {
684 vA = iwe.e->GetaVertex()->GetVertex();
685 vB = iwe.e->GetbVertex()->GetVertex();
686 }
687 else {
688 vA = iwe.e->GetbVertex()->GetVertex();
689 vB = iwe.e->GetaVertex()->GetVertex();
690 }
691 // Make the 2 SVertex
692 va = MakeSVertex(vA, true);
693 vb = MakeSVertex(vB, true);
694
695 // get the faces normals and the material indices
696 Vec3r normalA, normalB;
697 uint matA(0), matB(0);
698 bool faceMarkA = false, faceMarkB = false;
699 if (iwe.order) {
700 normalB = iwe.e->GetbFace()->GetNormal();
701 matB = iwe.e->GetbFace()->frs_materialIndex();
702 faceMarkB = iwe.e->GetbFace()->GetMark();
703 if (!(iwe.e->nature() & Nature::BORDER)) {
704 normalA = iwe.e->GetaFace()->GetNormal();
705 matA = iwe.e->GetaFace()->frs_materialIndex();
706 faceMarkA = iwe.e->GetaFace()->GetMark();
707 }
708 }
709 else {
710 normalA = iwe.e->GetbFace()->GetNormal();
711 matA = iwe.e->GetbFace()->frs_materialIndex();
712 faceMarkA = iwe.e->GetbFace()->GetMark();
713 if (!(iwe.e->nature() & Nature::BORDER)) {
714 normalB = iwe.e->GetaFace()->GetNormal();
715 matB = iwe.e->GetaFace()->frs_materialIndex();
716 faceMarkB = iwe.e->GetaFace()->GetMark();
717 }
718 }
719 // Creates the corresponding feature edge
720 fe = new FEdgeSharp(va, vb);
721 fe->setNature(iwe.e->nature());
722 fe->setId(_currentFId);
723 fe->setaFrsMaterialIndex(matA);
724 fe->setbFrsMaterialIndex(matB);
725 fe->setaFaceMark(faceMarkA);
726 fe->setbFaceMark(faceMarkB);
727 fe->setNormalA(normalA);
728 fe->setNormalB(normalB);
729 fe->setPreviousEdge(feprevious);
730 if (feprevious) {
731 feprevious->setNextEdge(fe);
732 }
734 va->AddFEdge(fe);
735 vb->AddFEdge(fe);
736 // Add normals:
737 va->AddNormal(normalA);
738 va->AddNormal(normalB);
739 vb->AddNormal(normalA);
740 vb->AddNormal(normalB);
741
742 ++_currentFId;
743 iwe.e->userdata = fe;
744 return fe;
745}
746
748{
749 if (nullptr == iEdge) {
750 return true;
751 }
752 if (iEdge->userdata == nullptr) {
753 return false;
754 }
755 return true;
756}
757
759{
760 SVertex *va = new SVertex(iPoint, _currentSVertexId);
763 // Add the svertex to the SShape svertex list:
765 return va;
766}
767
769{
770 SVertex *va;
771 if (!shared) {
772 va = MakeSVertex(iPoint);
773 }
774 else {
775 // Check whether the iPoint is already in the table
776 SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
777 if (shared && found != _SVertexMap.end()) {
778 va = (*found).second;
779 }
780 else {
781 va = MakeSVertex(iPoint);
782 // Add the svertex into the table using iPoint as the key
783 _SVertexMap[iPoint] = va;
784 }
785 }
786 return va;
787}
788
790{
791 ViewVertex *vva = iSVertex->viewvertex();
792 if (vva) {
793 return vva;
794 }
795 vva = new NonTVertex(iSVertex);
796 // Add the view vertex to the ViewShape svertex list:
798 return vva;
799}
800
801} /* namespace Freestyle */
unsigned int uint
#define ELEM(...)
#define A2
Definition RandGen.cpp:28
#define A1
Definition RandGen.cpp:27
Class to perform all geometric operations dedicated to silhouette. That, for example,...
Class to build view edges and the underlying chains of feature edges...
Classes to define a View Map (ViewVertex, ViewEdge, etc.)
Classes to define an Extended Winged Edge data structure.
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void setaFaceMark(bool iFaceMark)
void setaFrsMaterialIndex(uint i)
void setNormalB(const Vec3r &iNormal)
void setbFrsMaterialIndex(uint i)
void setbFaceMark(bool iFaceMark)
void setNormalA(const Vec3r &iNormal)
void setNormal(const Vec3r &iNormal)
void setFrsMaterialIndex(uint i)
void setFaceMark(bool iFaceMark)
void setFace(void *iFace)
void setId(const Id &id)
Definition Silhouette.h:735
SVertex * vertexA()
Definition Silhouette.h:597
void setViewEdge(ViewEdge *iViewEdge)
Definition Silhouette.h:766
SVertex * vertexB()
Definition Silhouette.h:603
void setNextEdge(FEdge *iEdge)
Definition Silhouette.h:741
void setNature(Nature::EdgeNature iNature)
Definition Silhouette.h:753
void setPreviousEdge(FEdge *iEdge)
Definition Silhouette.h:747
vector< SVertex * > & getVertexList()
void AddChain(FEdge *iEdge)
void AddNewVertex(SVertex *iv)
vector< FEdge * > & getEdgeList()
void AddEdge(FEdge *iEdge)
ViewVertex * viewvertex()
Definition Silhouette.h:278
void setCurvatureInfo(CurvatureInfo *ci)
Definition Silhouette.h:303
void AddNormal(const Vec3r &iNormal)
Definition Silhouette.h:298
void AddFEdge(FEdge *iFEdge)
Definition Silhouette.h:361
const Vec3r & point3D() const
Definition Silhouette.h:225
static void ProjectSilhouette(std::vector< SVertex * > &ioVertices)
Vec< T, N > & normalize()
Definition VecMat.h:104
virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, std::vector< ViewEdge * > &ioVEdges, std::vector< ViewVertex * > &ioVVertices, std::vector< FEdge * > &ioFEdges, std::vector< SVertex * > &ioSVertices)
int retrieveFaceMarks(WXEdge *iEdge)
SVertex * MakeSVertex(Vec3r &iPoint)
OWXEdge FindNextWEdge(const OWXEdge &iEdge)
bool stopSharpViewEdge(WXEdge *iEdge)
ViewEdge * BuildSharpViewEdge(const OWXEdge &iWEdge)
OWXEdge FindPreviousWEdge(const OWXEdge &iEdge)
FEdge * BuildSharpFEdge(FEdge *feprevious, const OWXEdge &iwe)
ViewEdge * BuildSmoothViewEdge(const OWXFaceLayer &iFaceLayer)
FEdge * BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer &ifl)
OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer &iFaceLayer)
ViewVertex * MakeViewVertex(SVertex *iSVertex)
OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer &iFaceLayer)
virtual void Init(ViewShape *oVShape)
bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer)
void setId(const Id &id)
Definition ViewMap.h:1178
void setFEdgeB(FEdge *iFEdge)
Definition ViewMap.h:1166
void setA(ViewVertex *iA)
Definition ViewMap.h:1142
void setFEdgeA(FEdge *iFEdge)
Definition ViewMap.h:1160
void setNature(Nature::EdgeNature iNature)
Definition ViewMap.h:1154
void setB(ViewVertex *iB)
Definition ViewMap.h:1148
void AddVertex(ViewVertex *iVertex)
Definition ViewMap.h:1600
vector< ViewEdge * > & edges()
Definition ViewMap.h:1557
vector< ViewVertex * > & vertices()
Definition ViewMap.h:1551
void AddEdge(ViewEdge *iEdge)
Definition ViewMap.h:1607
SShape * sshape()
Definition ViewMap.h:1539
WVertex * GetaVertex()
Definition WEdge.h:601
WVertex * GetbVertex()
Definition WEdge.h:606
WFace * GetaFace()
Definition WEdge.h:611
void * userdata
Definition WEdge.h:509
WFace * GetbFace()
Definition WEdge.h:616
bool GetMark() const
Definition WEdge.h:741
WFace * GetBordingFace(int index)
Definition WEdge.h:800
Vec3f & GetNormal()
Definition WEdge.h:726
Vec3f & GetVertexNormal(int index)
Definition WEdge.h:826
uint frs_materialIndex() const
Definition WEdge.h:736
WOEdge * twin()
Definition WEdge.cpp:201
WVertex * GetaVertex()
Definition WEdge.h:387
WVertex * GetbVertex()
Definition WEdge.h:392
vector< WEdge * > & getEdgeList()
Definition WEdge.h:1048
vector< WFace * > & GetFaceList()
Definition WEdge.h:1058
void ResetUserData()
Definition WEdge.h:1209
Vec3f & GetVertex()
Definition WEdge.h:73
virtual face_iterator faces_end()
Definition WEdge.h:301
virtual face_iterator faces_begin()
Definition WEdge.h:296
short order() const
Definition WXEdge.h:159
WXNature nature()
Definition WXEdge.h:149
WXSmoothEdge * getSmoothEdge()
Definition WXEdge.h:400
WXFace * getFace()
Definition WXEdge.h:395
WXNature nature() const
Definition WXEdge.h:382
void retrieveSmoothEdgesLayers(WXNature iNature, vector< WXFaceLayer * > &oSmoothEdgesLayers)
Definition WXEdge.h:593
bool hasSmoothEdges() const
Definition WXEdge.h:561
vector< WXFaceLayer * > & getSmoothLayers()
Definition WXEdge.h:575
float ta() const
Definition WXEdge.h:245
float tb() const
Definition WXEdge.h:250
CurvatureInfo * curvatures()
Definition WXEdge.h:76
local_group_size(16, 16) .push_constant(Type b
#define B
static const EdgeNature NO_FEATURE
Definition Nature.h:38
static const EdgeNature BORDER
Definition Nature.h:42
static const EdgeNature RIDGE
Definition Nature.h:46
inherits from class Rep
Definition AppCanvas.cpp:20
static double B1(double u)
Definition FitCurve.cpp:308
static double B2(double u)
Definition FitCurve.cpp:314
double real
Definition Precision.h:14