From 83a8f5efa358d15ae93ddb6f2aeb00e6e1c5967f Mon Sep 17 00:00:00 2001 From: cignoni Date: Sun, 21 May 2006 06:40:31 +0000 Subject: [PATCH] Added DoubleFace management --- .../trimesh_clustering/trimesh_clustering.cpp | 9 ++++- vcg/complex/trimesh/clustering.h | 38 +++++++++++++++---- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/apps/sample/trimesh_clustering/trimesh_clustering.cpp b/apps/sample/trimesh_clustering/trimesh_clustering.cpp index 3d07d112..c796dbec 100644 --- a/apps/sample/trimesh_clustering/trimesh_clustering.cpp +++ b/apps/sample/trimesh_clustering/trimesh_clustering.cpp @@ -46,11 +46,15 @@ int main(int argc, char **argv) "options: \n" "-k cellnum approx number of cluster that should be defined; (default 10e5)\n" "-s size in absolute units the size of the clustering cell\n" + "-d enable the duplication of faces for double surfaces\n" ); exit(0); } - int i=3; int CellNum=100000; float CellSize=0; + int i=3; + int CellNum=100000; + float CellSize=0; + bool DupFace=false; while(i::PerFace(m); printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn); vcg::tri::Clustering > Grid; + Grid.DuplicateFaceParam=DupFace; Grid.Init(m.bbox,CellNum,CellSize); printf("Clustering to %i cells\n",Grid.Grid.siz[0]*Grid.Grid.siz[1]*Grid.Grid.siz[2] ); diff --git a/vcg/complex/trimesh/clustering.h b/vcg/complex/trimesh/clustering.h index b51b9cf7..4a45c2a0 100644 --- a/vcg/complex/trimesh/clustering.h +++ b/vcg/complex/trimesh/clustering.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.4 2006/05/19 20:49:03 m_di_benedetto +Added check for empty generated mesh (prevent call to mesh allocator with zero vertices or faces). + Revision 1.3 2006/05/18 22:20:53 m_di_benedetto added check for deleted faces and modified/added std namespace qualifier. @@ -129,6 +132,14 @@ class Clustering typedef typename MeshType::VertexIterator VertexIterator; typedef typename MeshType::FaceIterator FaceIterator; + // DuplicateFace == bool means that during the clustering doublesided surface (like a thin shell) that would be clustered to a single surface + // will be merged into two identical but opposite faces. + // So in practice: + // DuplicateFace=true a model with looks ok if you enable backface culling + // DuplicateFace=false a model with looks ok if you enable doublesided lighting and disable backfaceculling + + bool DuplicateFaceParam; + class SimpleTri { public: @@ -140,12 +151,18 @@ class Clustering (v[0] v[1] ) std::swap(v[0],v[1]); // now v0 < v1 - if(v[0] > v[2] ) std::swap(v[0],v[2]); // now v0 is the minimum - if(v[1] > v[2] ) std::swap(v[1],v[2]); // sorted! + if(v[0] > v[1] ) swap(v[0],v[1]); // now v0 < v1 + if(v[0] > v[2] ) swap(v[0],v[2]); // now v0 is the minimum + if(v[1] > v[2] ) swap(v[1],v[2]); // sorted! } // Hashing Function; operator size_t () const @@ -198,8 +215,9 @@ class Clustering st.v[i]->Add(m,*(fi),i); } if( (st.v[0]!=st.v[1]) && (st.v[0]!=st.v[2]) && (st.v[1]!=st.v[2]) ) - { - st.sort(); + { // if we allow the duplication of faces we sort the vertex only partially (to maintain the original face orientation) + if(DuplicateFaceParam) st.sortOrient(); + else st.sort(); TriSet.insert(st); } // printf("Inserted %8i triangles, clustered to %8i tri and %i cells\n",distance(m.face.begin(),fi),TriSet.size(),GridCell.size()); @@ -232,14 +250,18 @@ class Clustering m.face[i].V(0)=&(m.vert[(*ti).v[0]->id]); m.face[i].V(1)=&(m.vert[(*ti).v[1]->id]); m.face[i].V(2)=&(m.vert[(*ti).v[2]->id]); + // if we are merging faces even when opposite we choose + // the best orientation according to the averaged normal + if(!DuplicateFaceParam) + { CoordType N=Normal(m.face[i]); int badOrient=0; if( N*(*ti).v[0]->n <0) ++badOrient; if( N*(*ti).v[1]->n <0) ++badOrient; if( N*(*ti).v[2]->n <0) ++badOrient; if(badOrient>2) - std::swap(m.face[i].V(0),m.face[i].V(1)); - + swap(m.face[i].V(0),m.face[i].V(1)); + } i++; }