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