Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp')
-rwxr-xr-xsource/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp724
1 files changed, 724 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
new file mode 100755
index 00000000000..7cf177dedb7
--- /dev/null
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
@@ -0,0 +1,724 @@
+//
+// Copyright (C) : Please refer to the COPYRIGHT file distributed
+// with this source distribution.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "ViewMap.h"
+#include "ViewEdgeXBuilder.h"
+#include "../winged_edge/WXEdge.h"
+#include "SilhouetteGeomEngine.h"
+#include <list>
+
+using namespace std;
+
+void ViewEdgeXBuilder::Init(ViewShape *oVShape){
+ if(0 == oVShape)
+ return;
+
+ // for design conveniance, we store the current SShape.
+ _pCurrentSShape = oVShape->sshape();
+ if(0 == _pCurrentSShape)
+ return;
+
+ _pCurrentVShape = oVShape;
+
+ // Reset previous data
+ //--------------------
+ if(!_SVertexMap.empty())
+ _SVertexMap.clear();
+}
+
+void ViewEdgeXBuilder::BuildViewEdges( WXShape *iWShape, ViewShape *oVShape,
+ vector<ViewEdge*>& ioVEdges,
+ vector<ViewVertex*>& ioVVertices,
+ vector<FEdge*>& ioFEdges,
+ vector<SVertex*>& ioSVertices){
+ // Reinit structures
+ Init(oVShape);
+
+ ViewEdge *vedge ;
+ // Let us build the smooth stuff
+ //----------------------------------------
+ // We parse all faces to find the ones
+ // that contain smooth edges
+ vector<WFace*>& wfaces = iWShape->GetFaceList();
+ vector<WFace*>::iterator wf, wfend;
+ WXFace *wxf;
+ for(wf=wfaces.begin(), wfend=wfaces.end();
+ wf!=wfend;
+ wf++){
+ wxf = dynamic_cast<WXFace*>(*wf);
+ if(false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ?
+ continue;
+ // parse all smooth layers:
+ vector<WXFaceLayer*>& smoothLayers = wxf->getSmoothLayers();
+ for(vector<WXFaceLayer*>::iterator sl = smoothLayers.begin(), slend=smoothLayers.end();
+ sl!=slend;
+ ++sl){
+ if(!(*sl)->hasSmoothEdge())
+ continue;
+ if(stopSmoothViewEdge((*sl))) // has it been parsed already ?
+ continue;
+ // here we know that we're dealing with a face layer that has not been
+ // processed yet and that contains a smooth edge.
+ vedge = BuildSmoothViewEdge(OWXFaceLayer(*sl, true));
+ }
+ }
+
+ // Now let's build sharp view edges:
+ //----------------------------------
+ // Reset all userdata for WXEdge structure
+ //----------------------------------------
+ //iWShape->ResetUserData();
+
+ WXEdge * wxe;
+ vector<WEdge*>& wedges = iWShape->getEdgeList();
+ //
+ //------------------------------
+ for(vector<WEdge*>::iterator we=wedges.begin(),weend=wedges.end();
+ we!=weend;
+ we++){
+ wxe = dynamic_cast<WXEdge*>(*we);
+ if(Nature::NO_FEATURE == wxe->nature())
+ continue;
+
+ if(!stopSharpViewEdge(wxe)){
+ bool b=true;
+ if(wxe->order() == -1)
+ b = false;
+ BuildSharpViewEdge(OWXEdge(wxe,b));
+ }
+ }
+
+ // Reset all userdata for WXEdge structure
+ //----------------------------------------
+ iWShape->ResetUserData();
+
+ // Add all these new edges to the scene's feature edges list:
+ //-----------------------------------------------------------
+ vector<FEdge*>& newedges = _pCurrentSShape->getEdgeList();
+ vector<SVertex*>& newVertices = _pCurrentSShape->getVertexList();
+ vector<ViewVertex*>& newVVertices = _pCurrentVShape->vertices();
+ vector<ViewEdge*>& newVEdges = _pCurrentVShape->edges();
+
+ // inserts in ioFEdges, at its end, all the edges of newedges
+ ioFEdges.insert(ioFEdges.end(), newedges.begin(), newedges.end());
+ ioSVertices.insert(ioSVertices.end(), newVertices.begin(), newVertices.end());
+ ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end());
+ ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end());
+
+}
+
+ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer){
+ // Find first edge:
+ OWXFaceLayer first = iFaceLayer;
+ OWXFaceLayer currentFace = first;
+
+ // bidirectional chaining.
+ // first direction
+ list<OWXFaceLayer> facesChain;
+ unsigned size = 0;
+ while(!stopSmoothViewEdge(currentFace.fl)){
+ facesChain.push_back(currentFace);
+ ++size;
+ currentFace.fl->userdata = (void*)1; // processed
+ // Find the next edge!
+ currentFace = FindNextFaceLayer(currentFace);
+ }
+ OWXFaceLayer end = facesChain.back();
+ // second direction
+ currentFace = FindPreviousFaceLayer(first);
+ while(!stopSmoothViewEdge(currentFace.fl)){
+ facesChain.push_front(currentFace);
+ ++size;
+ currentFace.fl->userdata = (void*)1; // processed
+ // Find the previous edge!
+ currentFace = FindPreviousFaceLayer(currentFace);
+ }
+ first = facesChain.front();
+
+ if(iFaceLayer.fl->nature() & Nature::RIDGE){
+ if(size<4){
+ return 0;
+ }
+ }
+
+ // Start a new chain edges
+ ViewEdge * newVEdge = new ViewEdge;
+ newVEdge->setId(_currentViewId);
+ ++_currentViewId;
+
+ _pCurrentVShape->AddEdge(newVEdge);
+
+
+ // build FEdges
+ FEdge * feprevious = 0;
+ FEdge * fefirst = 0;
+ FEdge * fe = 0;
+ for(list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend=facesChain.end();
+ fl!=flend;
+ ++fl){
+ fe = BuildSmoothFEdge(feprevious, (*fl));
+ fe->setViewEdge(newVEdge);
+ if(!fefirst)
+ fefirst = fe;
+ feprevious = fe;
+ }
+ // Store the chain starting edge:
+ _pCurrentSShape->AddChain(fefirst);
+ newVEdge->setNature(iFaceLayer.fl->nature());
+ newVEdge->setFEdgeA(fefirst);
+ newVEdge->setFEdgeB(fe);
+
+ // is it a closed loop ?
+ if((first == end) && (size != 1)){
+ fefirst->setPreviousEdge(fe);
+ fe->setNextEdge(fefirst);
+ newVEdge->setA(0);
+ newVEdge->setB(0);
+ }else{
+ ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
+ ViewVertex *vvb = MakeViewVertex(fe->vertexB());
+
+ ((NonTVertex*)vva)->AddOutgoingViewEdge(newVEdge);
+ ((NonTVertex*)vvb)->AddIncomingViewEdge(newVEdge);
+
+ newVEdge->setA(vva);
+ newVEdge->setB(vvb);
+ }
+
+ return newVEdge;
+}
+
+ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) {
+ // Start a new sharp chain edges
+ ViewEdge * newVEdge = new ViewEdge;
+ newVEdge->setId(_currentViewId);
+ ++_currentViewId;
+ unsigned size=0;
+
+ _pCurrentVShape->AddEdge(newVEdge);
+
+ // Find first edge:
+ OWXEdge firstWEdge = iWEdge;
+ OWXEdge previousWEdge = firstWEdge;
+ OWXEdge currentWEdge = firstWEdge;
+ list<OWXEdge> edgesChain;
+ // bidirectional chaining
+ // first direction:
+ while(!stopSharpViewEdge(currentWEdge.e)){
+ edgesChain.push_back(currentWEdge);
+ ++size;
+ currentWEdge.e->userdata = (void*)1; // processed
+ // Find the next edge!
+ currentWEdge = FindNextWEdge(currentWEdge);
+ }
+ OWXEdge endWEdge = edgesChain.back();
+ // second direction
+ currentWEdge = FindPreviousWEdge(firstWEdge);
+ while(!stopSharpViewEdge(currentWEdge.e)){
+ edgesChain.push_front(currentWEdge);
+ ++size;
+ currentWEdge.e->userdata = (void*)1; // processed
+ // Find the previous edge!
+ currentWEdge = FindPreviousWEdge(currentWEdge);
+ }
+ firstWEdge = edgesChain.front();
+
+ // build FEdges
+ FEdge * feprevious = 0;
+ FEdge * fefirst = 0;
+ FEdge * fe = 0;
+ for(list<OWXEdge>::iterator we = edgesChain.begin(), weend=edgesChain.end();
+ we!=weend;
+ ++we){
+ fe = BuildSharpFEdge(feprevious, (*we));
+ fe->setViewEdge(newVEdge);
+ if(!fefirst)
+ fefirst = fe;
+ feprevious = fe;
+ }
+ // Store the chain starting edge:
+ _pCurrentSShape->AddChain(fefirst);
+ newVEdge->setNature(iWEdge.e->nature());
+ newVEdge->setFEdgeA(fefirst);
+ newVEdge->setFEdgeB(fe);
+
+ // is it a closed loop ?
+ if((firstWEdge == endWEdge) && (size!=1)){
+ fefirst->setPreviousEdge(fe);
+ fe->setNextEdge(fefirst);
+ newVEdge->setA(0);
+ newVEdge->setB(0);
+ }else{
+ ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
+ ViewVertex *vvb = MakeViewVertex(fe->vertexB());
+
+ ((NonTVertex*)vva)->AddOutgoingViewEdge(newVEdge);
+ ((NonTVertex*)vvb)->AddIncomingViewEdge(newVEdge);
+
+ newVEdge->setA(vva);
+ newVEdge->setB(vvb);
+ }
+
+ return newVEdge;
+}
+
+OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer){
+ WXFace *nextFace = 0;
+ WOEdge * woeend;
+ real tend;
+ if(iFaceLayer.order){
+ woeend = iFaceLayer.fl->getSmoothEdge()->woeb();
+ tend = iFaceLayer.fl->getSmoothEdge()->tb();
+ }else{
+ woeend = iFaceLayer.fl->getSmoothEdge()->woea();
+ tend = iFaceLayer.fl->getSmoothEdge()->ta();
+ }
+ // special case of EDGE_VERTEX config:
+ if((tend == 0.0) || (tend == 1.0)){
+ WVertex *nextVertex;
+ if(tend == 0.0)
+ nextVertex = woeend->GetaVertex();
+ else
+ nextVertex = woeend->GetbVertex();
+ if(nextVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
+ return OWXFaceLayer(0,true);
+ bool found = false;
+ WVertex::face_iterator f=nextVertex->faces_begin();
+ WVertex::face_iterator fend=nextVertex->faces_end();
+ while((!found) && (f!=fend)){
+ nextFace = dynamic_cast<WXFace*>(*f);
+ if((0 != nextFace) && (nextFace!=iFaceLayer.fl->getFace())){
+ vector<WXFaceLayer*> sameNatureLayers;
+ nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
+ if(sameNatureLayers.size() == 1) {// don't know
+ // maybe should test whether this face has
+ // also a vertex_edge configuration
+ WXFaceLayer * winner = sameNatureLayers[0];
+ // check face mark continuity
+ if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
+ return OWXFaceLayer(0,true);
+ if(woeend == winner->getSmoothEdge()->woea()->twin())
+ return OWXFaceLayer(winner,true);
+ else
+ return OWXFaceLayer(winner,false);
+ }
+ }
+ ++f;
+ }
+ }else{
+ nextFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woeend));
+ if(0 == nextFace)
+ return OWXFaceLayer(0,true);
+ // if the next face layer has either no smooth edge or
+ // no smooth edge of same nature, no next face
+ if(!nextFace->hasSmoothEdges())
+ return OWXFaceLayer(0,true);
+ vector<WXFaceLayer*> sameNatureLayers;
+ nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
+ if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face
+ return OWXFaceLayer(0,true);
+ else{
+ WXFaceLayer * winner = sameNatureLayers[0];
+ // check face mark continuity
+ if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
+ return OWXFaceLayer(0,true);
+ if(woeend == winner->getSmoothEdge()->woea()->twin())
+ return OWXFaceLayer(winner,true);
+ else
+ return OWXFaceLayer(winner,false);
+ }
+ }
+ return OWXFaceLayer(0,true);
+}
+
+OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer) {
+ WXFace *previousFace = 0;
+ WOEdge * woebegin;
+ real tend;
+ if(iFaceLayer.order){
+ woebegin = iFaceLayer.fl->getSmoothEdge()->woea();
+ tend = iFaceLayer.fl->getSmoothEdge()->ta();
+ }else{
+ woebegin = iFaceLayer.fl->getSmoothEdge()->woeb();
+ tend = iFaceLayer.fl->getSmoothEdge()->tb();
+ }
+
+ // special case of EDGE_VERTEX config:
+ if((tend == 0.0) || (tend == 1.0)){
+ WVertex *previousVertex;
+ if(tend == 0.0)
+ previousVertex = woebegin->GetaVertex();
+ else
+ previousVertex = woebegin->GetbVertex();
+ if(previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore
+ return OWXFaceLayer(0,true);
+ bool found = false;
+ WVertex::face_iterator f=previousVertex->faces_begin();
+ WVertex::face_iterator fend=previousVertex->faces_end();
+ while((!found) && (f!=fend)){
+ previousFace = dynamic_cast<WXFace*>(*f);
+ if((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())){
+ vector<WXFaceLayer*> sameNatureLayers;
+ previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
+ if(sameNatureLayers.size() == 1) {// don't know
+ // maybe should test whether this face has
+ // also a vertex_edge configuration
+ WXFaceLayer * winner = sameNatureLayers[0];
+ // check face mark continuity
+ if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
+ return OWXFaceLayer(0,true);
+ if(woebegin == winner->getSmoothEdge()->woeb()->twin())
+ return OWXFaceLayer(winner,true);
+ else
+ return OWXFaceLayer(winner,false);
+ }
+ }
+ ++f;
+ }
+ }else{
+ previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin));
+ if(0 == previousFace)
+ return OWXFaceLayer(0,true);
+
+ // if the next face layer has either no smooth edge or
+ // no smooth edge of same nature, no next face
+ if(!previousFace->hasSmoothEdges())
+ return OWXFaceLayer(0,true);
+ vector<WXFaceLayer*> sameNatureLayers;
+ previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers);
+ if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face
+ return OWXFaceLayer(0,true);
+ else{
+ WXFaceLayer * winner = sameNatureLayers[0];
+ // check face mark continuity
+ if(winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark())
+ return OWXFaceLayer(0,true);
+ if(woebegin == winner->getSmoothEdge()->woeb()->twin())
+ return OWXFaceLayer(winner,true);
+ else
+ return OWXFaceLayer(winner,false);
+ }
+ }
+ return OWXFaceLayer(0,true);
+}
+
+FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl){
+ WOEdge *woea, *woeb;
+ real ta, tb;
+ SVertex *va, *vb;
+ FEdgeSmooth *fe;
+ // retrieve exact silhouette data
+ WXSmoothEdge *se = ifl.fl->getSmoothEdge();
+
+ if (ifl.order) {
+ woea = se->woea();
+ woeb = se->woeb();
+ ta = se->ta();
+ tb = se->tb();
+ } else {
+ woea = se->woeb();
+ woeb = se->woea();
+ ta = se->tb();
+ tb = se->ta();
+ }
+
+ Vec3r normal;
+ // Make the 2 Svertices
+ if(feprevious == 0){ // that means that we don't have any vertex already built for that face
+ Vec3r A1(woea->GetaVertex()->GetVertex());
+ Vec3r A2(woea->GetbVertex()->GetVertex());
+ Vec3r A(A1+ta*(A2-A1));
+
+ va = MakeSVertex(A, false);
+ // Set normal:
+ Vec3r NA1(ifl.fl->getFace()->GetVertexNormal(woea->GetaVertex()));
+ Vec3r NA2(ifl.fl->getFace()->GetVertexNormal(woea->GetbVertex()));
+ Vec3r na((1 - ta) * NA1 + ta * NA2);
+ na.normalize();
+ va->AddNormal(na);
+ normal = na;
+
+ // Set CurvatureInfo
+ CurvatureInfo* curvature_info_a = new CurvatureInfo(
+ *(dynamic_cast<WXVertex*>(woea->GetaVertex())->curvatures()),
+ *(dynamic_cast<WXVertex*>(woea->GetbVertex())->curvatures()),
+ ta);
+ va->setCurvatureInfo(curvature_info_a);
+ }
+ else
+ va = feprevious->vertexB();
+
+ Vec3r B1(woeb->GetaVertex()->GetVertex());
+ Vec3r B2(woeb->GetbVertex()->GetVertex());
+ Vec3r B(B1+tb*(B2-B1));
+
+ vb = MakeSVertex(B, false);
+ // Set normal:
+ Vec3r NB1(ifl.fl->getFace()->GetVertexNormal(woeb->GetaVertex()));
+ Vec3r NB2(ifl.fl->getFace()->GetVertexNormal(woeb->GetbVertex()));
+ Vec3r nb((1 - tb) * NB1 + tb * NB2);
+ nb.normalize();
+ normal += nb;
+ vb->AddNormal(nb);
+
+ // Set CurvatureInfo
+ CurvatureInfo* curvature_info_b = new CurvatureInfo(
+ *(dynamic_cast<WXVertex*>(woeb->GetaVertex())->curvatures()),
+ *(dynamic_cast<WXVertex*>(woeb->GetbVertex())->curvatures()),
+ tb);
+ vb->setCurvatureInfo(curvature_info_b);
+
+ // Creates the corresponding feature edge
+ fe = new FEdgeSmooth(va, vb);
+ fe->setNature(ifl.fl->nature());
+ fe->setId(_currentFId);
+ fe->setFrsMaterialIndex(ifl.fl->getFace()->frs_materialIndex());
+ fe->setFace(ifl.fl->getFace());
+ fe->setFaceMark(ifl.fl->getFace()->GetMark());
+ if(feprevious == 0)
+ normal.normalize();
+ fe->setNormal(normal);
+ fe->setPreviousEdge(feprevious);
+ if(feprevious)
+ feprevious->setNextEdge(fe);
+ _pCurrentSShape->AddEdge(fe);
+ va->AddFEdge(fe);
+ vb->AddFEdge(fe);
+
+ ++_currentFId;
+ ifl.fl->userdata = fe;
+ return fe;
+}
+
+bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer){
+ if(0 == iFaceLayer)
+ return true;
+ if(iFaceLayer->userdata == 0)
+ return false;
+ return true;
+}
+
+int ViewEdgeXBuilder::retrieveFaceMarks(WXEdge *iEdge)
+{
+ WFace *aFace = iEdge->GetaFace();
+ WFace *bFace = iEdge->GetbFace();
+ int result = 0;
+ if (aFace && aFace->GetMark())
+ result += 1;
+ if (bFace && bFace->GetMark())
+ result += 2;
+ return result;
+}
+
+OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge){
+ if(Nature::NO_FEATURE == iEdge.e->nature())
+ return OWXEdge(0, true);
+
+ WVertex *v;
+ if(true == iEdge.order)
+ v = iEdge.e->GetbVertex();
+ else
+ v = iEdge.e->GetaVertex();
+
+ if(((WXVertex*)v)->isFeature())
+ return 0;
+
+
+ int faceMarks = retrieveFaceMarks(iEdge.e);
+ vector<WEdge*>& vEdges = (v)->GetEdges();
+ for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end();
+ ve!=veend;
+ ve++){
+ WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
+ if(wxe == iEdge.e)
+ continue; // same edge as the one processed
+
+ if(wxe->nature() != iEdge.e->nature())
+ continue;
+
+ // check face mark continuity
+ if(retrieveFaceMarks(wxe) != faceMarks)
+ continue;
+
+ if(wxe->GetaVertex() == v){
+ // That means that the face necesarily lies on the edge left.
+ // So the vertex order is OK.
+ return OWXEdge(wxe, true);
+ }else{
+ // That means that the face necesarily lies on the edge left.
+ // So the vertex order is OK.
+ return OWXEdge(wxe, false);
+ }
+ }
+ // we did not find:
+ return OWXEdge(0, true);
+}
+
+OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge){
+ if(Nature::NO_FEATURE == iEdge.e->nature())
+ return OWXEdge(0, true);
+
+ WVertex *v;
+ if(true == iEdge.order)
+ v = iEdge.e->GetaVertex();
+ else
+ v = iEdge.e->GetbVertex();
+
+ if(((WXVertex*)v)->isFeature())
+ return 0;
+
+
+ int faceMarks = retrieveFaceMarks(iEdge.e);
+ vector<WEdge*>& vEdges = (v)->GetEdges();
+ for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end();
+ ve!=veend;
+ ve++){
+ WXEdge *wxe = dynamic_cast<WXEdge*>(*ve);
+ if(wxe == iEdge.e)
+ continue; // same edge as the one processed
+
+ if(wxe->nature() != iEdge.e->nature())
+ continue;
+
+ // check face mark continuity
+ if(retrieveFaceMarks(wxe) != faceMarks)
+ continue;
+
+ if(wxe->GetbVertex() == v){
+ return OWXEdge(wxe, true);
+ }else{
+ return OWXEdge(wxe, false);
+ }
+ }
+ // we did not find:
+ return OWXEdge(0, true);
+}
+
+FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe){
+ SVertex *va, *vb;
+ FEdgeSharp *fe;
+ WXVertex *wxVA, *wxVB;
+ if(iwe.order){
+ wxVA = (WXVertex*)iwe.e->GetaVertex();
+ wxVB = (WXVertex*)iwe.e->GetbVertex();
+ }else{
+ wxVA = (WXVertex*)iwe.e->GetbVertex();
+ wxVB = (WXVertex*)iwe.e->GetaVertex();
+ }
+ // Make the 2 SVertex
+ va = MakeSVertex(wxVA->GetVertex(), true);
+ vb = MakeSVertex(wxVB->GetVertex(), true);
+
+ // get the faces normals and the material indices
+ Vec3r normalA, normalB;
+ unsigned matA(0), matB(0);
+ bool faceMarkA = false, faceMarkB = false;
+ if(iwe.order){
+ normalB = (iwe.e->GetbFace()->GetNormal());
+ matB = (iwe.e->GetbFace()->frs_materialIndex());
+ faceMarkB = (iwe.e->GetbFace()->GetMark());
+ if(!(iwe.e->nature() & Nature::BORDER)) {
+ normalA = (iwe.e->GetaFace()->GetNormal());
+ matA = (iwe.e->GetaFace()->frs_materialIndex());
+ faceMarkA = (iwe.e->GetaFace()->GetMark());
+ }
+ }else{
+ normalA = (iwe.e->GetbFace()->GetNormal());
+ matA = (iwe.e->GetbFace()->frs_materialIndex());
+ faceMarkA = (iwe.e->GetbFace()->GetMark());
+ if(!(iwe.e->nature() & Nature::BORDER)) {
+ normalB = (iwe.e->GetaFace()->GetNormal());
+ matB = (iwe.e->GetaFace()->frs_materialIndex());
+ faceMarkB = (iwe.e->GetaFace()->GetMark());
+ }
+ }
+ // Creates the corresponding feature edge
+ // Creates the corresponding feature edge
+ fe = new FEdgeSharp(va, vb);
+ fe->setNature(iwe.e->nature());
+ fe->setId(_currentFId);
+ fe->setaFrsMaterialIndex(matA);
+ fe->setbFrsMaterialIndex(matB);
+ fe->setaFaceMark(faceMarkA);
+ fe->setbFaceMark(faceMarkB);
+ fe->setNormalA(normalA);
+ fe->setNormalB(normalB);
+ fe->setPreviousEdge(feprevious);
+ if(feprevious)
+ feprevious->setNextEdge(fe);
+ _pCurrentSShape->AddEdge(fe);
+ va->AddFEdge(fe);
+ vb->AddFEdge(fe);
+ //Add normals:
+ va->AddNormal(normalA);
+ va->AddNormal(normalB);
+ vb->AddNormal(normalA);
+ vb->AddNormal(normalB);
+
+ ++_currentFId;
+ iwe.e->userdata = fe;
+ return fe;
+}
+
+bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge){
+ if(0 == iEdge)
+ return true;
+ if(iEdge->userdata == 0)
+ return false;
+ return true;
+}
+
+SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint){
+ SVertex *va = new SVertex(iPoint, _currentSVertexId);
+ SilhouetteGeomEngine::ProjectSilhouette(va);
+ ++_currentSVertexId;
+ // Add the svertex to the SShape svertex list:
+ _pCurrentSShape->AddNewVertex(va);
+ return va;
+}
+
+SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared){
+ SVertex *va;
+ if (!shared) {
+ va = MakeSVertex(iPoint);
+ } else {
+ // Check whether the iPoint is already in the table
+ SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
+ if (shared && found != _SVertexMap.end()) {
+ va = (*found).second;
+ }else{
+ va = MakeSVertex(iPoint);
+ // Add the svertex into the table using iPoint as the key
+ _SVertexMap[iPoint] = va;
+ }
+ }
+ return va;
+}
+
+ViewVertex * ViewEdgeXBuilder::MakeViewVertex(SVertex *iSVertex){
+ ViewVertex *vva = iSVertex->viewvertex();
+ if(vva != 0)
+ return vva;
+ vva = new NonTVertex(iSVertex);
+ // Add the view vertex to the ViewShape svertex list:
+ _pCurrentVShape->AddVertex(vva);
+ return vva;
+}
+