A vcg.::Pos was used to implement the collapse type. CHanged

to vcg::Edge
This commit is contained in:
ganovelli 2004-10-25 07:07:56 +00:00
parent 4d02036998
commit 4359486afc
2 changed files with 40 additions and 31 deletions

View File

@ -27,7 +27,6 @@
#ifndef __VCG_DECIMATION_COLLAPSE #ifndef __VCG_DECIMATION_COLLAPSE
#define __VCG_DECIMATION_COLLAPSE #define __VCG_DECIMATION_COLLAPSE
#include<vcg\complex\tetramesh\edge_collapse.h>
#include<vcg\complex\local_optimization.h> #include<vcg\complex\local_optimization.h>
struct FAIL{ struct FAIL{
@ -75,7 +74,7 @@ class TetraEdgeCollapse: public LocalOptimization<TETRA_MESH_TYPE>::LocModType
private: private:
///the new point that substitute the edge ///the new point that substitute the edge
Point3<ScalarType> _NewPoint; Point<3,ScalarType> _NewPoint;
///the pointer to edge collapser method ///the pointer to edge collapser method
vcg::tetra::EdgeCollapse<TETRA_MESH_TYPE> _EC; vcg::tetra::EdgeCollapse<TETRA_MESH_TYPE> _EC;
///mark for up_dating ///mark for up_dating
@ -140,7 +139,13 @@ ScalarType _VolumePreservingError(PosType &pos,CoordType &new_point,int nsteps)
new_point=ve1->P(); new_point=ve1->P();
else else
if ((!ext_v0)&&(!ext_v1)) if ((!ext_v0)&&(!ext_v1))
new_point=(ve0->P()+ve1->P())/2.f; {/*CoordType g;
g.Zero();
g+=ve0->cP();
g+=ve1->cP();
g/=2;*/
new_point=(ve0->cP()+ve1->cP())/2.f;
}
else else
if ((ext_v0)&&(ext_v1))//both are external vertex if ((ext_v0)&&(ext_v1))//both are external vertex
{ {
@ -150,7 +155,12 @@ ScalarType _VolumePreservingError(PosType &pos,CoordType &new_point,int nsteps)
{ {
best_error=1000000.f; best_error=1000000.f;
ScalarType alfatemp=step*((double)i); ScalarType alfatemp=step*((double)i);
CoordType newPTemp=(ve0->P()*alfatemp) +(ve1->P()*(1.f-alfatemp)); //CoordType g;
// g.Zero();
//g+=ve0->cP()*alfatemp;
//g+=ve1->cP()*(1-alfatemp);
//CoordType newPTemp=g;
CoordType newPTemp=(ve0->cP()*alfatemp) +(ve1->cP()*(1.f-alfatemp));
//the error is the absolute value of difference of volumes //the error is the absolute value of difference of volumes
ScalarType error=fabs(Vol_Original-_EC.VolumeSimulateCollapse(pos,newPTemp)); ScalarType error=fabs(Vol_Original-_EC.VolumeSimulateCollapse(pos,newPTemp));
if(error<best_error) if(error<best_error)

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.2 2004/09/29 17:08:16 ganovelli
corrected error in -error (see localoptimization)
****************************************************************************/ ****************************************************************************/
@ -101,12 +104,12 @@ class TriEdgeCollapseQuadric: public TriEdgeCollapse< TriMeshType,MYTYPE>
{ {
public: public:
typedef typename vcg::tri::TriEdgeCollapse< TriMeshType, MYTYPE > TEC; typedef typename vcg::tri::TriEdgeCollapse< TriMeshType, MYTYPE > TEC;
typedef typename TEC::PosType PosType; typedef typename TEC::EdgeType EdgeType;
typedef typename TriEdgeCollapse<TriMeshType, MYTYPE>::HeapType HeapType; typedef typename TriEdgeCollapse<TriMeshType, MYTYPE>::HeapType HeapType;
typedef typename TriEdgeCollapse<TriMeshType, MYTYPE>::HeapElem HeapElem; typedef typename TriEdgeCollapse<TriMeshType, MYTYPE>::HeapElem HeapElem;
typedef typename TriMeshType::CoordType CoordType; typedef typename TriMeshType::CoordType CoordType;
typedef typename TriMeshType::ScalarType ScalarType; typedef typename TriMeshType::ScalarType ScalarType;
typedef math::Quadric< Plane3<ScalarType, false> > QuadricType; typedef math::Quadric< double > QuadricType;
typedef typename TriMeshType::FaceType FaceType; typedef typename TriMeshType::FaceType FaceType;
static QCollapseParameter & Params(){static QCollapseParameter p; return p;} static QCollapseParameter & Params(){static QCollapseParameter p; return p;}
@ -125,23 +128,26 @@ public:
// puntatori ai vertici che sono stati messi non-w per preservare il boundary // puntatori ai vertici che sono stati messi non-w per preservare il boundary
static std::vector<typename TriMeshType::VertexPointer> & WV(){static std::vector<typename TriMeshType::VertexPointer> _WV; return _WV;}; static std::vector<typename TriMeshType::VertexPointer> & WV(){static std::vector<typename TriMeshType::VertexPointer> _WV; return _WV;};
TriEdgeCollapseQuadric(PosType p, int i) inline TriEdgeCollapseQuadric(EdgeType p, int i)
//:TEC(p,i){} //:TEC(p,i){}
{ {
_Imark() = i; localMark = i;
pos=p; pos=p;
_priority = ComputePriority(); _priority = ComputePriority();
} }
bool IsFeasible(){ inline bool IsFeasible(){
return LinkConditions(pos); bool res = (!Params().PreserveTopology || LinkConditions(pos) );
if(!res)
++FailStat::LinkConditionEdge();
return res;
} }
void Execute(TriMeshType &m) void Execute(TriMeshType &m)
{ {
CoordType newPos = ComputeMinimal(); CoordType newPos = ComputeMinimal();
pos.V(1)->q+=pos.V()->q; pos.V(1)->q+=pos.V(0)->q;
int FaceDel=DoCollapse(pos, newPos); int FaceDel=DoCollapse(pos, newPos);
m.fn-=FaceDel; m.fn-=FaceDel;
--m.vn; --m.vn;
@ -152,7 +158,8 @@ public:
typename TriMeshType::VertexIterator vi; typename TriMeshType::VertexIterator vi;
typename TriMeshType::FaceIterator pf; typename TriMeshType::FaceIterator pf;
PosType av0,av1,av01; EdgeType av0,av1,av01;
Params().CosineThr=cos(Params().NormalThr);
if(!IsSetHint(HNHasVFTopology) ) vcg::tri::UpdateTopology<TriMeshType>::VertexFace(m); if(!IsSetHint(HNHasVFTopology) ) vcg::tri::UpdateTopology<TriMeshType>::VertexFace(m);
@ -205,11 +212,12 @@ public:
assert(x.F()->V(x.I())==&(*vi)); assert(x.F()->V(x.I())==&(*vi));
if((x.F()->V(x.I())<x.F()->V1(x.I())) && x.F()->V1(x.I())->IsRW() && !x.F()->V1(x.I())->IsV()){ if((x.F()->V(x.I())<x.F()->V1(x.I())) && x.F()->V1(x.I())->IsRW() && !x.F()->V1(x.I())->IsV()){
x.F()->V1(x.I())->SetV(); x.F()->V1(x.I())->SetV();
h_ret.push_back(HeapElem(new MYTYPE(PosType(x.F(),x.I()),_Imark())));
h_ret.push_back(HeapElem(new MYTYPE(EdgeType(x.F()->V(x.I()),x.F()->V1(x.I())),GlobalMark())));
} }
if((x.F()->V(x.I())<x.F()->V2(x.I())) && x.F()->V2(x.I())->IsRW()&& !x.F()->V2(x.I())->IsV()){ if((x.F()->V(x.I())<x.F()->V2(x.I())) && x.F()->V2(x.I())->IsRW()&& !x.F()->V2(x.I())->IsV()){
x.F()->V2(x.I())->SetV(); x.F()->V2(x.I())->SetV();
h_ret.push_back(HeapElem(new MYTYPE(PosType(x.F(),(x.I()+2)%3),_Imark()))); h_ret.push_back(HeapElem(new MYTYPE(EdgeType(x.F()->V(x.I()),x.F()->V2(x.I())),GlobalMark() )));
} }
} }
} }
@ -223,23 +231,16 @@ public:
assert(x.F()->V(x.I())==&(*vi)); assert(x.F()->V(x.I())==&(*vi));
if(x.F()->V(x.I())->IsRW() && x.F()->V1(x.I())->IsRW() && !m.IsMarked(x.F()->V1(x.I()))){ if(x.F()->V(x.I())->IsRW() && x.F()->V1(x.I())->IsRW() && !m.IsMarked(x.F()->V1(x.I()))){
m.Mark( x.F()->V1(x.I()) ); m.Mark( x.F()->V1(x.I()) );
h_ret.push_back( HeapElem( new MYTYPE( PosType (x.F(),x.I()), m.imark))); h_ret.push_back( HeapElem( new MYTYPE( EdgeType (x.F()->V(x.I()),x.F()->V1(x.I())), m.imark)));
} }
if(x.F()->V(x.I())->IsRW() && x.F()->V2(x.I())->IsRW()&& !m.IsMarked(x.F()->V2(x.I()))){ if(x.F()->V(x.I())->IsRW() && x.F()->V2(x.I())->IsRW()&& !m.IsMarked(x.F()->V2(x.I()))){
m.Mark( x.F()->V2(x.I()) ); m.Mark( x.F()->V2(x.I()) );
h_ret.push_back( HeapElem( new MYTYPE( PosType (x.F(),(x.I()+2)%3), m.imark))); h_ret.push_back( HeapElem( new MYTYPE( EdgeType (x.F()->V(x.I()),x.F()->V2(x.I())), m.imark)));
} }
} }
} }
} }
typename std::vector<HeapElem>::iterator ph;
for(ph=h_ret.begin();ph!=h_ret.end();++ph)
(*ph).locModPtr->ComputePriority();
make_heap(h_ret.begin(),h_ret.end()); make_heap(h_ret.begin(),h_ret.end());
m.InitVertexIMark();
} }
static bool IsSymmetric() {return Params().OptimalPlacement;} static bool IsSymmetric() {return Params().OptimalPlacement;}
@ -247,8 +248,8 @@ public:
static void SetDefaultParams(){ static void SetDefaultParams(){
Params().UseArea=true; Params().UseArea=true;
Params().UseVertexWeight=false; Params().UseVertexWeight=false;
Params().NormalCheck=true; Params().NormalCheck=false;
Params().CosineThr=M_PI/2; Params().NormalThr=M_PI/2;
Params().QualityCheck=true; Params().QualityCheck=true;
Params().QualityThr=.1; Params().QualityThr=.1;
Params().BoundaryWeight=.5; Params().BoundaryWeight=.5;
@ -257,6 +258,8 @@ public:
Params().ComplexCheck=false; Params().ComplexCheck=false;
Params().QuadricEpsilon =1e-15; Params().QuadricEpsilon =1e-15;
Params().ScaleFactor=1.0; Params().ScaleFactor=1.0;
Params().PreserveTopology = false;
} }
///* ///*
@ -270,7 +273,7 @@ public:
typename vcg::face::VFIterator<FaceType> x; typename vcg::face::VFIterator<FaceType> x;
std::vector<CoordType> on; // original normals std::vector<CoordType> on; // original normals
typename TriMeshType::VertexType * v[2]; typename TriMeshType::VertexType * v[2];
v[0] = pos.V(); v[0] = pos.V(0);
v[1] = pos.V(1); v[1] = pos.V(1);
if(Params().NormalCheck){ // Compute maximal normal variation if(Params().NormalCheck){ // Compute maximal normal variation
@ -458,9 +461,8 @@ static void InitQuadric(TriMeshType &m)
CoordType ComputeMinimal() CoordType ComputeMinimal()
{ {
typename TriMeshType::VertexType * v[2]; typename TriMeshType::VertexType * v[2];
v[0] = pos.V(); v[0] = pos.V(0);
v[1] = pos.V(1); v[1] = pos.V(1);
QuadricType q=v[0]->q; QuadricType q=v[0]->q;
q+=v[1]->q; q+=v[1]->q;
@ -475,9 +477,6 @@ static void InitQuadric(TriMeshType &m)
if(qv1<qvx && qv1<qv0) x=v[1]->P(); if(qv1<qvx && qv1<qv0) x=v[1]->P();
} }
// TRACE("-- %lf %lf %lf ---\n ",q.Apply(v[0]->P()),q.Apply(v[1]->P()),q.Apply(x));
// assert(q.Apply(v[1]->P())>=q.Apply(x));
// assert(q.Apply(v[0]->P())>=q.Apply(x));
return x; return x;
} }
// //