diff options
Diffstat (limited to 'source/blender/freestyle/intern/winged_edge/WXEdge.cpp')
-rwxr-xr-x | source/blender/freestyle/intern/winged_edge/WXEdge.cpp | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp new file mode 100755 index 00000000000..115a4f61789 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp @@ -0,0 +1,296 @@ +// +// 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 "WXEdge.h" + + /**********************************/ + /* */ + /* */ + /* WXFace */ + /* */ + /* */ + /**********************************/ + +unsigned int WXFaceLayer::Get0VertexIndex() const { + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for(i=0; i<nEdges; ++i){ + if(_DotP[i] == 0){ + return i; + } + } + return -1; +} +unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{ + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for(i=0; i<nEdges; ++i){ + if((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)){ + return i; + } + } + return -1; +} + +void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){ + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for(i=0; i<nEdges; ++i){ + if(_DotP[i]*_DotP[(i+1)%nEdges] < 0){ + // we got one + oCuspEdges.push_back(i); + } + } +} + +WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){ + // if the smooth edge has already been + // built: exit + if(0 != _pSmoothEdge) + return _pSmoothEdge; + real ta, tb; + WOEdge *woea(0), *woeb(0); + bool ok = false; + vector<int> cuspEdgesIndices; + int indexStart, indexEnd; + unsigned nedges = _pWXFace->numberOfEdges(); + if(_nNullDotP == nedges){ + _pSmoothEdge = 0; + return _pSmoothEdge; + } + if((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)){ + // that means that we have a smooth edge that starts from + // an edge and ends at an edge + //----------------------------- + // We retrieve the 2 edges for which we have + // opposite signs for each extremity + RetrieveCuspEdgesIndices(cuspEdgesIndices); + if(cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges + return 0; + + // let us determine which cusp edge corresponds to the starting: + // We can do that because we defined that + // a silhouette edge had the back facing part on its right. + // So if the WOEdge woea is such that woea[0].dotp > 0 and + // woea[1].dotp < 0, it is the starting edge. + //------------------------------------------- + + if(_DotP[cuspEdgesIndices[0]] > 0){ + woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]); + indexStart = cuspEdgesIndices[0]; + indexEnd = cuspEdgesIndices[1]; + }else{ + woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + indexStart = cuspEdgesIndices[1]; + indexEnd = cuspEdgesIndices[0]; + } + + // Compute the interpolation: + ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]); + tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]); + ok = true; + }else if(_nNullDotP == 1){ + // that means that we have exactly one of the + // 2 extremities of our silhouette edge is + // a vertex of the mesh + if((_nPosDotP == 2) || (_nPosDotP == 0)){ + _pSmoothEdge = 0; + return _pSmoothEdge; + } + RetrieveCuspEdgesIndices(cuspEdgesIndices); + // We should have only one EdgeCusp: + if(cuspEdgesIndices.size() != 1){ + cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl; + _pSmoothEdge = 0; + return 0; + } + unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index + unsigned nedges = _pWXFace->numberOfEdges(); + if(_DotP[cuspEdgesIndices[0]] > 0){ + woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + woeb = _pWXFace->GetOEdge(index0); + indexStart = cuspEdgesIndices[0]; + ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]); + tb = 0.0; + }else{ + woea = _pWXFace->GetOEdge(index0); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + indexEnd = cuspEdgesIndices[0]; + ta = 0.0; + tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]); + } + ok = true; + }else if(_nNullDotP == 2){ + // that means that the silhouette edge + // is an edge of the mesh + int index = GetSmoothEdgeIndex(); + if(!_pWXFace->front()) {// is it in the right order ? + // the order of the WOEdge index is wrong + woea = _pWXFace->GetOEdge((index+1)%nedges); + woeb = _pWXFace->GetOEdge((index-1)%nedges); + ta = 0; + tb = 1; + ok = true; + }else{ + // here it's not good, our edge is a single point -> skip that face + ok = false; + // the order of the WOEdge index is good + // woea = _pWXFace->GetOEdge((index-1)%nedges); + // woeb = _pWXFace->GetOEdge((index+1)%nedges); + // ta = 1; + // tb = 0; + } + } + if(ok){ + _pSmoothEdge = new WXSmoothEdge; + _pSmoothEdge->SetWOeA(woea); + _pSmoothEdge->SetWOeB(woeb); + _pSmoothEdge->SetTa(ta); + _pSmoothEdge->SetTb(tb); + if(_Nature & Nature::SILHOUETTE){ + if(_nNullDotP != 2){ + if(_DotP[_ClosestPointIndex] + 0.01 > 0) + _pSmoothEdge->SetFront(true); + else + _pSmoothEdge->SetFront(false); + } + } + } + + // check bording edges to see if they have different dotp values + // in bording faces. + // for(int i=0; i<numberOfEdges(); i++) + // { + // WSFace * bface = (WSFace*)GetBordingFace(i); + // if(bface != 0) + // { + // if((front())^(bface->front())) // fA->front XOR fB->front (true if one is 0 and the other is 1) + // { + // // that means that the edge i of the face is + // // a silhouette edge + // // TESTER D'ABORD SI LE EXACTSILHOUETTEEDGE N'A PAS + // // ETE CONSTRUIT SUR L'AUTRE FACE.(1 suffit) + // if(0 != ((WSExactFace*)bface)->exactSilhouetteEdge()) + // { + // // that means that this silhouette edge has already been built + // return ((WSExactFace*)bface)->exactSilhouetteEdge(); + // } + // // Else we must build it + // WOEdge *woea, *woeb; + // real ta, tb; + // if(!front()) // is it in the right order ? + // { + // // the order of the WOEdge index is wrong + // woea = _OEdgeList[(i+1)%numberOfEdges()]; + // if(0 == i) + // woeb = _OEdgeList[numberOfEdges()-1]; + // else + // woeb = _OEdgeList[(i-1)]; + // ta = 0; + // tb = 1; + // } + // else + // { + // // the order of the WOEdge index is good + // if(0 == i) + // woea = _OEdgeList[numberOfEdges()-1]; + // else + // woea = _OEdgeList[(i-1)]; + // woeb = _OEdgeList[(i+1)%numberOfEdges()]; + // ta = 1; + // tb = 0; + // } + // + // _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX); + // _pSmoothEdge->SetWOeA(woea); + // _pSmoothEdge->SetWOeA(woeb); + // _pSmoothEdge->SetTa(ta); + // _pSmoothEdge->SetTb(tb); + // + // return _pSmoothEdge; + // } + // } + //} + return _pSmoothEdge; +} + + +void WXFace::ComputeCenter() +{ + vector<WVertex*> iVertexList; + RetrieveVertexList(iVertexList); + Vec3r center; + for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); + wv!=wvend; + wv++) + { + center += (*wv)->GetVertex(); + } + center /= (real)iVertexList.size(); + SetCenter(center); +} + + /**********************************/ + /* */ + /* */ + /* WXShape */ + /* */ + /* */ + /**********************************/ + + +WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex) +{ + WFace *face = WShape::MakeFace(iVertexList, iMaterialIndex); + if(0 == face) + return 0; + + Vec3r center; + for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); + wv!=wvend; + wv++) + { + center += (*wv)->GetVertex(); + } + center /= (real)iVertexList.size(); + ((WXFace*)face)->SetCenter(center); + + return face; +} + +WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterialIndex) +{ + WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iMaterialIndex); + + // Vec3r center; + // for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); + // wv!=wvend; + // wv++) + // { + // center += (*wv)->GetVertex(); + // } + // center /= (real)iVertexList.size(); + // ((WSFace*)face)->SetCenter(center); + + return face; +} + |