added parameter theta (from conformal to equiareal) to AreaPresTextureOptimizer.
Improved feature lists (comments).
This commit is contained in:
parent
436c9ae56c
commit
28eb5780f0
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.5 2007/02/02 01:39:58 tarini
|
||||||
|
added three general-utility global functions for texture coordinates: SmoothTextureCoords, IsFoldFree, MarkFolds (see descriptions)
|
||||||
|
|
||||||
Revision 1.4 2007/02/02 01:23:47 tarini
|
Revision 1.4 2007/02/02 01:23:47 tarini
|
||||||
added a few general comments on AreaPreserving optimizer, recapping optimizer features.
|
added a few general comments on AreaPreserving optimizer, recapping optimizer features.
|
||||||
|
|
||||||
|
@ -141,20 +144,24 @@ public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AREA PRESERVING TEXTURE OPTIMIZATION
|
AREA PRESERVING TEXTURE OPTIMIZATION
|
||||||
as in DEGENER, P., MESETH, J., AND KLEIN, R. An adaptable surface
|
|
||||||
parameterization method. [2003] In Proc. of the 12th International Meshing
|
as in: Degener, P., Meseth, J., Klein, R.
|
||||||
Roundtable, 201–213.
|
"An adaptable surface parameterization method."
|
||||||
|
Proc. of the 12th International Meshing oundtable, 201–213 [2003].
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
:) - Balances angle and area distortions (best results!).
|
:) - Balances angle and area distortions (best results!).
|
||||||
|
:) - Can choose how to balance area and angle preservation (see SetTheta)
|
||||||
|
theta=0 -> pure conformal (use MIPS instead!)
|
||||||
|
theta=3 -> good balance between area and angle preservation
|
||||||
|
theta>3 -> care more about area than about angles
|
||||||
:( - Slowest method.
|
:( - Slowest method.
|
||||||
:( - Requires a fixed boundary, else expands forever in texture space.
|
:( - Requires a fixed boundary, else expands forever in texture space (unless theta=0).
|
||||||
:( - Diverges in presence of flipped faces.
|
:( - Diverges in presence of flipped faces (unless theta=0).
|
||||||
:( - Requires a speed parameter to be set.
|
:( - Requires a speed parameter to be set.
|
||||||
Speed too large => bounces back and forth around minima, w/o getting closer.
|
Speed too large => when close, bounces back and forth around minimum, w/o getting any closer.
|
||||||
Lower speed => longest convercence times
|
Lower speed => longer convercence times
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<class MESH_TYPE>
|
template<class MESH_TYPE>
|
||||||
|
@ -179,12 +186,14 @@ private:
|
||||||
ScalarType totArea;
|
ScalarType totArea;
|
||||||
ScalarType speed;
|
ScalarType speed;
|
||||||
|
|
||||||
public:
|
int theta;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
// constructor and destructor
|
// constructor and destructor
|
||||||
AreaPreservingTextureOptimizer(MeshType &_m):Super(_m),data(_m.face),sum(_m.vert){
|
AreaPreservingTextureOptimizer(MeshType &_m):Super(_m),data(_m.face),sum(_m.vert){
|
||||||
speed=0.001;
|
speed=0.001;
|
||||||
|
theta=3;
|
||||||
}
|
}
|
||||||
|
|
||||||
~AreaPreservingTextureOptimizer(){
|
~AreaPreservingTextureOptimizer(){
|
||||||
|
@ -197,10 +206,23 @@ public:
|
||||||
speed=_speed;
|
speed=_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScalarType GetSpeed(ScalarType _speed){
|
ScalarType GetSpeed(){
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sets the parameter theta:
|
||||||
|
// good parameters are in 1..3
|
||||||
|
// 0 = converge to pure conformal, ignore area preservation
|
||||||
|
// 3 = good balance between area and conformal
|
||||||
|
// >3 = area more important, angle preservation less important
|
||||||
|
void SetTheta(int _theta){
|
||||||
|
theta=_theta;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetTheta(){
|
||||||
|
return theta;
|
||||||
|
}
|
||||||
|
|
||||||
void IterateBlind(){
|
void IterateBlind(){
|
||||||
/* todo: do as iterate, but without */
|
/* todo: do as iterate, but without */
|
||||||
Iterate();
|
Iterate();
|
||||||
|
@ -213,7 +235,6 @@ public:
|
||||||
#define v0 (f->V0(i)->T().P())
|
#define v0 (f->V0(i)->T().P())
|
||||||
#define v1 (f->V1(i)->T().P())
|
#define v1 (f->V1(i)->T().P())
|
||||||
#define v2 (f->V2(i)->T().P())
|
#define v2 (f->V2(i)->T().P())
|
||||||
#define THETA 3
|
|
||||||
for (VertexIterator v=Super::m.vert.begin(); v!=Super::m.vert.end(); v++) {
|
for (VertexIterator v=Super::m.vert.begin(); v!=Super::m.vert.end(); v++) {
|
||||||
sum[v].Zero();
|
sum[v].Zero();
|
||||||
}
|
}
|
||||||
|
@ -260,24 +281,24 @@ public:
|
||||||
// exponential weighting
|
// exponential weighting
|
||||||
// 2d gradient
|
// 2d gradient
|
||||||
|
|
||||||
dx=M1*M1
|
dx=// M1
|
||||||
*(px*(M1+ THETA*M2) - 2.0*qx*M1),
|
//*M1 // ^ theta-1
|
||||||
dy=M1*M1
|
pow(M1,theta-1)
|
||||||
*(py*(M1+ THETA*M2) - 2.0*qy*M1),
|
*(px*(M1+ theta*M2) - 2.0*qx*M1),
|
||||||
|
dy=// M1
|
||||||
|
//*M1 // ^ theta-1
|
||||||
|
pow(M1,theta-1)
|
||||||
|
*(py*(M1+ theta*M2) - 2.0*qy*M1),
|
||||||
|
|
||||||
gy= dy/c,
|
gy= dy/c,
|
||||||
gx= (dx - gy*b) / a;
|
gx= (dx - gy*b) / a;
|
||||||
|
|
||||||
// 3d gradient
|
// 3d gradient
|
||||||
|
|
||||||
sum[f->V(i)]
|
sum[f->V(i)]+= ( (v1-v0) * gx + (v2-v0) * gy ) * data[f][3];
|
||||||
//f->V(i)->sum
|
|
||||||
+= ( (v1-v0) * gx + (v2-v0) * gy ) * data[f][3];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
max=0; // max displacement
|
max=0; // max displacement
|
||||||
|
|
||||||
speed=0.001;
|
speed=0.001;
|
||||||
for (VertexIterator v=Super::m.vert.begin(); v!=Super::m.vert.end(); v++)
|
for (VertexIterator v=Super::m.vert.begin(); v!=Super::m.vert.end(); v++)
|
||||||
if ( !Super::isFixed[v] ) //if (!v->IsB())
|
if ( !Super::isFixed[v] ) //if (!v->IsB())
|
||||||
|
@ -294,7 +315,6 @@ public:
|
||||||
#undef v0
|
#undef v0
|
||||||
#undef v1
|
#undef v1
|
||||||
#undef v2
|
#undef v2
|
||||||
#undef THETA
|
|
||||||
//printf("rejected %d\n",rejected);
|
//printf("rejected %d\n",rejected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue