00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_POLYGON_SUPPORT
00025 #define __VCGLIB_POLYGON_SUPPORT
00026
00027 #include <vector>
00028 #include <vcg/complex/trimesh/subset.h>
00029 #include <vcg/simplex/face/jumping_pos.h>
00030 #include <vcg/space/planar_polygon_tessellation.h>
00031
00032 namespace vcg
00033 {
00034 namespace tri{
00036
00038
00040
00047 template <class TriMeshType,class PolyMeshType >
00048 struct PolygonSupport{
00049
00053 static void ImportFromPolyMesh(TriMeshType & tm, PolyMeshType & pm){
00054 std::vector<typename PolyMeshType::CoordType> points;
00055 std::vector<int> faces;
00056
00057
00058 typename PolyMeshType::VertexIterator vi;
00059 typename TriMeshType::FaceIterator tfi,tfib ;
00060 typename TriMeshType ::VertexIterator tvi = Allocator<TriMeshType>::AddVertices(tm,pm.vert.size());
00061 int cnt = 0;
00062 for(tvi = tm.vert.begin(),vi = pm.vert.begin(); tvi != tm.vert.end(); ++tvi,++vi,++cnt)
00063 if(!(*vi).IsD()) (*tvi).ImportLocal(*vi); else vcg::tri::Allocator<TriMeshType>::DeleteVertex(tm,(*tvi));
00064
00065 typename PolyMeshType::FaceIterator fi;
00066 for(fi = pm.face.begin(); fi != pm.face.end(); ++fi)
00067 if(!((*fi).IsD())){
00068 points.clear();
00069 for(int i = 0; i < (*fi).VN(); ++i) {
00070 typename PolyMeshType::VertexType * v = (*fi).V(i);
00071 points.push_back(v->P());
00072 }
00073 faces.clear();
00074 TessellatePlanarPolygon3(points,faces);
00075 tfib = tfi = Allocator<TriMeshType>::AddFaces(tm,faces.size()/3);
00076 for(int i = 0; tfi != tm.face.end();++tfi){
00077 (*tfi).V(0) = &tm.vert[ (*fi).V( faces[i] ) - &(*pm.vert.begin())];
00078 (*tfi).V(1) = &tm.vert[ (*fi).V( faces[i+1]) - &(*pm.vert.begin())];
00079 (*tfi).V(2) = &tm.vert[ (*fi).V( faces[i+2]) - &(*pm.vert.begin())];
00080
00081 if( (faces[i]+1)%points.size() != faces[i+1]) (*tfi).SetF(0);
00082 if( (faces[i+1]+1)%points.size() != faces[i+2]) (*tfi).SetF(1);
00083 if( (faces[i+2]+1)%points.size() != faces[i]) (*tfi).SetF(2);
00084 i+=3;
00085 }
00086
00087 }
00088 }
00089
00090
00094 static void ImportFromTriMesh( PolyMeshType & pm, TriMeshType & tm){
00095
00096
00097 int cnt = 0;
00098 typename TriMeshType ::ConstVertexIterator tvi;
00099 typename PolyMeshType::VertexIterator vi = vcg::tri::Allocator<PolyMeshType>::AddVertices(pm,tm.vert.size());
00100 for(tvi = tm.vert.begin(); tvi != tm.vert.end(); ++tvi,++vi,++cnt)
00101 if(!(*tvi).IsD())(*vi).ImportLocal(*tvi); else vcg::tri::Allocator<PolyMeshType> ::DeleteVertex(pm,(*vi));
00102
00103
00104 typename TriMeshType::FaceIterator tfi;
00105 vcg::face::JumpingPos<typename TriMeshType::FaceType> p;
00106
00107 for( tfi = tm.face.begin(); tfi != tm.face.end(); ++tfi) if(!(*tfi).IsD() && !(*tfi).IsV())
00108 {
00109 std::vector<typename TriMeshType::VertexPointer> vs;
00110 std::vector<typename TriMeshType::FacePointer> fs;
00111
00112
00113
00114 int se = 0;
00115 for(;se < 3;++se) if (!(*tfi).IsF(se)) break;
00116
00117
00118 typename TriMeshType::VertexPointer v0 = (*tfi).V(se);
00119 p.F() = &(*tfi);
00120 p.E() = se;
00121 p.V() = p.F()->V(p.F()->Next(se));
00122 p.FlipE();
00123
00124 vs.push_back(p.F()->V(se));
00125
00126 do{
00127 while(p.F()->IsF(p.E())) { fs.push_back(p.F()); p.FlipF(); p.FlipE(); p.F()->SetV();}
00128 vs.push_back(p.F()->V(p.E()));
00129 p.FlipV();
00130 p.FlipE();
00131 } while( p.V() != v0 );
00132
00133
00134 typename PolyMeshType::FaceIterator pfi = vcg::tri::Allocator<PolyMeshType>::AddFaces(pm,1);
00135 (*pfi).Alloc(vs.size());
00136 for( int i = 0 ; i < vs.size(); ++i)
00137 (*pfi).V(i) = ( typename PolyMeshType::VertexType*) & pm.vert[vs[i]-&(*tm.vert.begin())];
00138
00139
00140
00141
00142 }
00143 }
00144
00145 static void ExtractPolygon(typename TriMeshType::FacePointer tfi, std::vector<typename TriMeshType::VertexPointer> &vs){
00146 vs.clear();
00147
00148 int se = -1;
00149 for(int i=0; i<3; i++) if (!( tfi->IsF(i))) { se = i; break;}
00150
00151 assert(se!=-1);
00152
00153
00154 typename TriMeshType::VertexPointer v0 = tfi->V(se);
00155
00156 vcg::face::JumpingPos<typename TriMeshType::FaceType> p;
00157
00158 p.F() = tfi;
00159 p.E() = se;
00160 p.V() = p.F()->V(p.F()->Next(se));
00161 p.FlipE();
00162
00163 vs.push_back(p.F()->V(se));
00164
00165 int guard = 0;
00166 do{
00167 while(p.F()->IsF(p.E())) { p.FlipF(); p.FlipE(); p.F()->SetV(); if (guard++>10) break;}
00168 if (guard++>10) break;
00169 vs.push_back(p.F()->V(p.E()));
00170 p.FlipV();
00171 p.FlipE();
00172 } while( p.V() != v0 );
00173 }
00174
00175 };
00176 }}
00177
00178 #endif // __VCGLIB_TRI_CLIP