Added DoubleFace management
This commit is contained in:
parent
f001cdf2e2
commit
83a8f5efa3
|
@ -46,11 +46,15 @@ int main(int argc, char **argv)
|
||||||
"options: \n"
|
"options: \n"
|
||||||
"-k cellnum approx number of cluster that should be defined; (default 10e5)\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"
|
"-s size in absolute units the size of the clustering cell\n"
|
||||||
|
"-d enable the duplication of faces for double surfaces\n"
|
||||||
);
|
);
|
||||||
exit(0);
|
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<argc)
|
while(i<argc)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +64,8 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
case 'k' : CellNum=atoi(argv[i+1]); ++i; printf("Using %i clustering cells\n",CellNum); break;
|
case 'k' : CellNum=atoi(argv[i+1]); ++i; printf("Using %i clustering cells\n",CellNum); break;
|
||||||
case 's' : CellSize=atof(argv[i+1]); ++i; printf("Using %5f as clustering cell size\n",CellSize); break;
|
case 's' : CellSize=atof(argv[i+1]); ++i; printf("Using %5f as clustering cell size\n",CellSize); break;
|
||||||
|
case 'd' : DupFace=true; printf("Enabling the duplication of faces for double surfaces\n"); break;
|
||||||
|
|
||||||
default : {printf("Error unable to parse option '%s'\n",argv[i]); exit(0);}
|
default : {printf("Error unable to parse option '%s'\n",argv[i]); exit(0);}
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
|
@ -77,6 +83,7 @@ int main(int argc, char **argv)
|
||||||
vcg::tri::UpdateNormals<MyMesh>::PerFace(m);
|
vcg::tri::UpdateNormals<MyMesh>::PerFace(m);
|
||||||
printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn);
|
printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn);
|
||||||
vcg::tri::Clustering<MyMesh, vcg::tri::AverageCell<MyMesh> > Grid;
|
vcg::tri::Clustering<MyMesh, vcg::tri::AverageCell<MyMesh> > Grid;
|
||||||
|
Grid.DuplicateFaceParam=DupFace;
|
||||||
Grid.Init(m.bbox,CellNum,CellSize);
|
Grid.Init(m.bbox,CellNum,CellSize);
|
||||||
|
|
||||||
printf("Clustering to %i cells\n",Grid.Grid.siz[0]*Grid.Grid.siz[1]*Grid.Grid.siz[2] );
|
printf("Clustering to %i cells\n",Grid.Grid.siz[0]*Grid.Grid.siz[1]*Grid.Grid.siz[2] );
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.3 2006/05/18 22:20:53 m_di_benedetto
|
||||||
added check for deleted faces and modified/added std namespace qualifier.
|
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::VertexIterator VertexIterator;
|
||||||
typedef typename MeshType::FaceIterator FaceIterator;
|
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
|
class SimpleTri
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -140,12 +151,18 @@ class Clustering
|
||||||
(v[0]<p.v[0]);
|
(v[0]<p.v[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort the vertex of the face maintaining the original face orientation (it only ensure that v0 is the minimum)
|
||||||
|
void sortOrient()
|
||||||
|
{
|
||||||
|
if(v[1] < v[0] && v[1] < v[2] ) { swap(v[0],v[1]); swap(v[1],v[2]); return; } // v1 was the minimum
|
||||||
|
if(v[2] < v[0] && v[2] < v[1] ) { swap(v[0],v[2]); swap(v[1],v[2]); return; } // v2 was the minimum
|
||||||
|
return; // v0 was the minimum;
|
||||||
|
}
|
||||||
void sort()
|
void sort()
|
||||||
{
|
{
|
||||||
//std::sort(&(v[0]),&(v[3]));
|
if(v[0] > v[1] ) swap(v[0],v[1]); // now v0 < v1
|
||||||
if(v[0] > v[1] ) std::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[0] > v[2] ) std::swap(v[0],v[2]); // now v0 is the minimum
|
if(v[1] > v[2] ) swap(v[1],v[2]); // sorted!
|
||||||
if(v[1] > v[2] ) std::swap(v[1],v[2]); // sorted!
|
|
||||||
}
|
}
|
||||||
// Hashing Function;
|
// Hashing Function;
|
||||||
operator size_t () const
|
operator size_t () const
|
||||||
|
@ -198,8 +215,9 @@ class Clustering
|
||||||
st.v[i]->Add(m,*(fi),i);
|
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]) )
|
if( (st.v[0]!=st.v[1]) && (st.v[0]!=st.v[2]) && (st.v[1]!=st.v[2]) )
|
||||||
{
|
{ // if we allow the duplication of faces we sort the vertex only partially (to maintain the original face orientation)
|
||||||
st.sort();
|
if(DuplicateFaceParam) st.sortOrient();
|
||||||
|
else st.sort();
|
||||||
TriSet.insert(st);
|
TriSet.insert(st);
|
||||||
}
|
}
|
||||||
// printf("Inserted %8i triangles, clustered to %8i tri and %i cells\n",distance(m.face.begin(),fi),TriSet.size(),GridCell.size());
|
// 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(0)=&(m.vert[(*ti).v[0]->id]);
|
||||||
m.face[i].V(1)=&(m.vert[(*ti).v[1]->id]);
|
m.face[i].V(1)=&(m.vert[(*ti).v[1]->id]);
|
||||||
m.face[i].V(2)=&(m.vert[(*ti).v[2]->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]);
|
CoordType N=Normal(m.face[i]);
|
||||||
int badOrient=0;
|
int badOrient=0;
|
||||||
if( N*(*ti).v[0]->n <0) ++badOrient;
|
if( N*(*ti).v[0]->n <0) ++badOrient;
|
||||||
if( N*(*ti).v[1]->n <0) ++badOrient;
|
if( N*(*ti).v[1]->n <0) ++badOrient;
|
||||||
if( N*(*ti).v[2]->n <0) ++badOrient;
|
if( N*(*ti).v[2]->n <0) ++badOrient;
|
||||||
if(badOrient>2)
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue