Optimized version of "EAR HOLE FILLING", the Ear is selected according to its dihedral angle.
This commit is contained in:
parent
c2fb20c70b
commit
d644daee6b
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.5 2006/10/06 15:28:14 giec
|
||||||
|
first working implementationof "EAR HOLE FILLING".
|
||||||
|
|
||||||
Revision 1.4 2006/10/02 12:06:40 giec
|
Revision 1.4 2006/10/02 12:06:40 giec
|
||||||
BugFix
|
BugFix
|
||||||
|
|
||||||
|
|
@ -296,34 +299,39 @@ namespace vcg {
|
||||||
//void ComputeQuality(){ quality = Distance(e0.VFlip()->P(),e1.v->P());}; //metodo vecchio per il calcolo della qualita
|
//void ComputeQuality(){ quality = Distance(e0.VFlip()->P(),e1.v->P());}; //metodo vecchio per il calcolo della qualita
|
||||||
void ComputeQuality()
|
void ComputeQuality()
|
||||||
{
|
{
|
||||||
|
//comute quality by max(dihedral ancgle)
|
||||||
|
Point3f n1 = (e0.v->N() + e1.v->N() + e0.VFlip()->N() ) / 3;
|
||||||
|
face::Pos<typename MSH_TYPE::FaceType> tmp = e1;
|
||||||
|
tmp.FlipE();tmp.FlipV();
|
||||||
|
Point3f n2= ( e1.VFlip()->N(), e1.v->N(), tmp.v->N());
|
||||||
MSH_TYPE::ScalarType qt;
|
MSH_TYPE::ScalarType qt;
|
||||||
MSH_TYPE::ScalarType k0 = e0.VFlip()->P().X()*e1.v->P().X();
|
qt = Angle(n1,n2);
|
||||||
MSH_TYPE::ScalarType k1 = e0.VFlip()->P().Y()*e1.v->P().Y();
|
quality = qt * -1000;
|
||||||
MSH_TYPE::ScalarType k2 = e0.VFlip()->P().Z()*e1.v->P().Z();
|
|
||||||
|
|
||||||
int exp0,exp1,exp2;
|
|
||||||
|
|
||||||
frexp( double(k0), &exp0 );
|
|
||||||
frexp( double(k1), &exp1 );
|
|
||||||
frexp( double(k2), &exp2 );
|
|
||||||
|
|
||||||
if( exp0<exp1 )
|
|
||||||
{
|
|
||||||
if(exp0<exp2)
|
|
||||||
qt = (MSH_TYPE::ScalarType) (k1+k2)+k0;
|
|
||||||
else
|
|
||||||
qt = (MSH_TYPE::ScalarType) (k0+k1)+k2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(exp1<exp2)
|
|
||||||
qt = (MSH_TYPE::ScalarType)(k0+k2)+k1;
|
|
||||||
else
|
|
||||||
qt = (MSH_TYPE::ScalarType) (k0+k1)+k2;
|
|
||||||
}
|
|
||||||
quality = qt * Distance(e0.VFlip()->P(),e1.v->P());
|
|
||||||
|
|
||||||
|
////calcolo della qualita' come angolo dell'orecchio per il lato opposto
|
||||||
|
//MSH_TYPE::ScalarType qt;
|
||||||
|
//MSH_TYPE::ScalarType k0 = e0.VFlip()->P().X()*e1.v->P().X();
|
||||||
|
//MSH_TYPE::ScalarType k1 = e0.VFlip()->P().Y()*e1.v->P().Y();
|
||||||
|
//MSH_TYPE::ScalarType k2 = e0.VFlip()->P().Z()*e1.v->P().Z();
|
||||||
|
//int exp0,exp1,exp2;
|
||||||
|
//frexp( double(k0), &exp0 );
|
||||||
|
//frexp( double(k1), &exp1 );
|
||||||
|
//frexp( double(k2), &exp2 );
|
||||||
|
//if( exp0<exp1 )
|
||||||
|
//{
|
||||||
|
// if(exp0<exp2)
|
||||||
|
// qt = (MSH_TYPE::ScalarType) (k1+k2)+k0;
|
||||||
|
// else
|
||||||
|
// qt = (MSH_TYPE::ScalarType) (k0+k1)+k2;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// if(exp1<exp2)
|
||||||
|
// qt = (MSH_TYPE::ScalarType)(k0+k2)+k1;
|
||||||
|
// else
|
||||||
|
// qt = (MSH_TYPE::ScalarType) (k0+k1)+k2;
|
||||||
|
//}
|
||||||
|
//quality = qt * Distance(e0.VFlip()->P(),e1.v->P());
|
||||||
|
|
||||||
};//dovrebbe
|
};//dovrebbe
|
||||||
bool IsUpToDate() {return (e0.IsBorder() && e1.IsBorder());};
|
bool IsUpToDate() {return (e0.IsBorder() && e1.IsBorder());};
|
||||||
|
|
@ -347,7 +355,6 @@ namespace vcg {
|
||||||
{
|
{
|
||||||
// simple topological check
|
// simple topological check
|
||||||
if(e0.f==e1.f) {
|
if(e0.f==e1.f) {
|
||||||
//TRACE("Avoided bad ear");
|
|
||||||
printf("Avoided bad ear");
|
printf("Avoided bad ear");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -479,7 +486,6 @@ namespace vcg {
|
||||||
std::vector<MESH::FacePointer *> app;
|
std::vector<MESH::FacePointer *> app;
|
||||||
app.push_back( &h.p.f );
|
app.push_back( &h.p.f );
|
||||||
|
|
||||||
assert(h.p.IsBorder());
|
|
||||||
MESH::FaceIterator f = tri::Allocator<MESH>::AddFaces(m, h.size-2, app);
|
MESH::FaceIterator f = tri::Allocator<MESH>::AddFaces(m, h.size-2, app);
|
||||||
|
|
||||||
h.Refresh(m); //rinfresco il puntatore tramite l'indice precedentemente salvato.
|
h.Refresh(m); //rinfresco il puntatore tramite l'indice precedentemente salvato.
|
||||||
|
|
@ -499,25 +505,21 @@ namespace vcg {
|
||||||
int cnt=h.size;
|
int cnt=h.size;
|
||||||
MESH::FaceIterator tmp;
|
MESH::FaceIterator tmp;
|
||||||
|
|
||||||
|
|
||||||
|
make_heap(H.begin(), H.end());
|
||||||
|
|
||||||
while( cnt > 2 && !H.empty() ) //finche' il buco non e' chiuso o non ci sono piu' orecchie da analizzare
|
while( cnt > 2 && !H.empty() ) //finche' il buco non e' chiuso o non ci sono piu' orecchie da analizzare
|
||||||
{
|
{
|
||||||
//ordino il vettore di orecchie
|
|
||||||
//sort(H.begin(), H.end(), greater<EAR>() );//descending
|
pop_heap(H.begin(), H.end());
|
||||||
sort(H.begin(), H.end(), less<EAR>() ); //ascending
|
|
||||||
|
|
||||||
EAR en0,en1;
|
EAR en0,en1;
|
||||||
|
|
||||||
MESH::VertexType vfit = *H.back().e0.v;
|
|
||||||
std::vector<MESH::VertexType >::iterator it;
|
|
||||||
it = vv.begin();
|
|
||||||
while( it != vv.end() && (vfit.P() != ((MESH::VertexType )(*it)).P() ) )
|
|
||||||
{it++; }
|
|
||||||
|
|
||||||
MESH::FaceIterator Fadd = f;
|
MESH::FaceIterator Fadd = f;
|
||||||
|
|
||||||
if(H.back().IsUpToDate())
|
if(H.back().IsUpToDate())
|
||||||
{
|
{
|
||||||
if(H.back().Degen() && it != vv.end()){
|
if(H.back().Degen()){
|
||||||
// Nota che nel caso di ear degeneri si DEVE permettere la creazione di un edge che gia'esiste
|
// Nota che nel caso di ear degeneri si DEVE permettere la creazione di un edge che gia'esiste
|
||||||
printf("\n -> Evitata orecchia brutta!");
|
printf("\n -> Evitata orecchia brutta!");
|
||||||
}
|
}
|
||||||
|
|
@ -525,49 +527,34 @@ namespace vcg {
|
||||||
{
|
{
|
||||||
if(H.back().Close(en0,en1,&*f))
|
if(H.back().Close(en0,en1,&*f))
|
||||||
{
|
{
|
||||||
//ES.insert(se);
|
|
||||||
/* ES.push_back(se);
|
|
||||||
if(!en0.IsNull()){
|
if(!en0.IsNull()){
|
||||||
H.push_back(en0);
|
H.push_back(en0);
|
||||||
push_heap( H.begin(), H.end());
|
push_heap( H.begin(), H.end());
|
||||||
}
|
}
|
||||||
if(!en1.IsNull()){
|
if(!en1.IsNull()){
|
||||||
H.push_back(en1);
|
H.push_back(en1);
|
||||||
push_heap( H.begin(), H.end());
|
push_heap( H.begin(), H.end());
|
||||||
}*/
|
}
|
||||||
--cnt;
|
--cnt;
|
||||||
tmp = f;
|
f->SetUserBit(UBIT);
|
||||||
++f;
|
++f;
|
||||||
fitted = true;
|
fitted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(cnt == 3 && !fitted)
|
if(cnt == 3 && !fitted)
|
||||||
{//ultimo buco o unico buco
|
{//ultimo buco o unico buco
|
||||||
if(H.back().Close(en0,en1,&*f))
|
if(H.back().Close(en0,en1,&*f))
|
||||||
{
|
{
|
||||||
--cnt;
|
--cnt;
|
||||||
tmp = f;
|
tmp = f;
|
||||||
++f;
|
++f;
|
||||||
fitted = true;
|
}
|
||||||
}
|
}
|
||||||
}
|
}//is update()
|
||||||
if(fitted && cnt >2)
|
fitted = false;
|
||||||
{
|
//non ho messo il triangolo quindi tolgo l'orecchio e continuo
|
||||||
face::Pos<typename MESH::FaceType> ff( &(*tmp) ,2);
|
H.pop_back();
|
||||||
//ho inserito il triangolo e devo aggiornare le strutture dati
|
|
||||||
H.clear();
|
|
||||||
vv.clear();
|
|
||||||
tmp->SetUserBit(UBIT);
|
|
||||||
//ri-prendo le informazioni sul buco
|
|
||||||
refreshHole<MESH,EAR, std::vector<EAR> >(m,H,ff,vv);
|
|
||||||
fitted = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//non ho messo il triangolo quindi tolgo l'orecchio e continuo
|
|
||||||
H.pop_back();
|
|
||||||
}
|
|
||||||
}//fine del while principale
|
}//fine del while principale
|
||||||
|
|
||||||
while(f!=m.face.end())
|
while(f!=m.face.end())
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue