compilation fixes with Eigen
This commit is contained in:
parent
1608800d69
commit
9608ec798b
|
|
@ -8,7 +8,7 @@
|
||||||
* \ *
|
* \ *
|
||||||
* All rights reserved. *
|
* All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU General Public License as published by *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
|
|
@ -108,17 +108,17 @@ namespace vcg
|
||||||
{
|
{
|
||||||
namespace tri
|
namespace tri
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
/** \addtogroup trimesh */
|
/** \addtogroup trimesh */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
/// Class of static functions to smooth and fair meshes and their attributes.
|
/// Class of static functions to smooth and fair meshes and their attributes.
|
||||||
|
|
||||||
template <class SmoothMeshType>
|
template <class SmoothMeshType>
|
||||||
class Smooth
|
class Smooth
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef SmoothMeshType MeshType;
|
typedef SmoothMeshType MeshType;
|
||||||
typedef typename MeshType::VertexType VertexType;
|
typedef typename MeshType::VertexType VertexType;
|
||||||
typedef typename MeshType::VertexType::CoordType CoordType;
|
typedef typename MeshType::VertexType::CoordType CoordType;
|
||||||
typedef typename MeshType::VertexPointer VertexPointer;
|
typedef typename MeshType::VertexPointer VertexPointer;
|
||||||
|
|
@ -130,8 +130,8 @@ public:
|
||||||
typedef typename MeshType::FaceContainer FaceContainer;
|
typedef typename MeshType::FaceContainer FaceContainer;
|
||||||
typedef typename vcg::Box3<ScalarType> Box3Type;
|
typedef typename vcg::Box3<ScalarType> Box3Type;
|
||||||
typedef typename vcg::face::VFIterator<FaceType> VFLocalIterator;
|
typedef typename vcg::face::VFIterator<FaceType> VFLocalIterator;
|
||||||
|
|
||||||
class ScaleLaplacianInfo
|
class ScaleLaplacianInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CoordType PntSum;
|
CoordType PntSum;
|
||||||
|
|
@ -143,11 +143,11 @@ public:
|
||||||
// normal n with a speed equal to the mean curvature
|
// normal n with a speed equal to the mean curvature
|
||||||
void VertexCoordLaplacianCurvatureFlow(MeshType &m, int step, ScalarType delta)
|
void VertexCoordLaplacianCurvatureFlow(MeshType &m, int step, ScalarType delta)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Another Laplacian smoothing variant,
|
}
|
||||||
// here we sum the baricenter of the faces incidents on each vertex weighting them with the angle
|
|
||||||
|
// Another Laplacian smoothing variant,
|
||||||
|
// here we sum the baricenter of the faces incidents on each vertex weighting them with the angle
|
||||||
|
|
||||||
static void VertexCoordLaplacianAngleWeighted(MeshType &m, int step, ScalarType delta)
|
static void VertexCoordLaplacianAngleWeighted(MeshType &m, int step, ScalarType delta)
|
||||||
{
|
{
|
||||||
|
|
@ -165,7 +165,7 @@ static void VertexCoordLaplacianAngleWeighted(MeshType &m, int step, ScalarType
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD())
|
||||||
{
|
{
|
||||||
CoordType mp=((*fi).V(0)->P() + (*fi).V(1)->P() + (*fi).V(2)->P())/3.0;
|
CoordType mp=((*fi).V(0)->P() + (*fi).V(1)->P() + (*fi).V(2)->P())/3.0;
|
||||||
CoordType e0=((*fi).V(0)->P() - (*fi).V(1)->P()).Normalize();
|
CoordType e0=((*fi).V(0)->P() - (*fi).V(1)->P()).Normalize();
|
||||||
CoordType e1=((*fi).V(1)->P() - (*fi).V(2)->P()).Normalize();
|
CoordType e1=((*fi).V(1)->P() - (*fi).V(2)->P()).Normalize();
|
||||||
CoordType e2=((*fi).V(2)->P() - (*fi).V(0)->P()).Normalize();
|
CoordType e2=((*fi).V(2)->P() - (*fi).V(0)->P()).Normalize();
|
||||||
|
|
||||||
|
|
@ -179,12 +179,12 @@ static void VertexCoordLaplacianAngleWeighted(MeshType &m, int step, ScalarType
|
||||||
TD[(*fi).V(j)].PntSum+=dir*a[j];
|
TD[(*fi).V(j)].PntSum+=dir*a[j];
|
||||||
TD[(*fi).V(j)].LenSum+=a[j]; // well, it should be named angleSum
|
TD[(*fi).V(j)].LenSum+=a[j]; // well, it should be named angleSum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD() && TD[*vi].LenSum>0 )
|
if(!(*vi).IsD() && TD[*vi].LenSum>0 )
|
||||||
(*vi).P() = (*vi).P() + (TD[*vi].PntSum/TD[*vi].LenSum ) * delta;
|
(*vi).P() = (*vi).P() + (TD[*vi].PntSum/TD[*vi].LenSum ) * delta;
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Scale dependent laplacian smoothing [Fujiwara 95]
|
// Scale dependent laplacian smoothing [Fujiwara 95]
|
||||||
|
|
@ -193,7 +193,7 @@ static void VertexCoordLaplacianAngleWeighted(MeshType &m, int step, ScalarType
|
||||||
// Mathieu Desbrun, Mark Meyer, Peter Schroeder, Alan H. Barr
|
// Mathieu Desbrun, Mark Meyer, Peter Schroeder, Alan H. Barr
|
||||||
// SIGGRAPH 99
|
// SIGGRAPH 99
|
||||||
// REQUIREMENTS: Border Flags.
|
// REQUIREMENTS: Border Flags.
|
||||||
//
|
//
|
||||||
// Note the delta parameter is in a absolute unit
|
// Note the delta parameter is in a absolute unit
|
||||||
// to get stability it should be a small percentage of the shortest edge.
|
// to get stability it should be a small percentage of the shortest edge.
|
||||||
|
|
||||||
|
|
@ -221,7 +221,7 @@ static void VertexCoordScaleDependentLaplacian_Fujiwara(MeshType &m, int step, S
|
||||||
TD[(*fi).V(j)].LenSum+=len;
|
TD[(*fi).V(j)].LenSum+=len;
|
||||||
TD[(*fi).V1(j)].LenSum+=len;
|
TD[(*fi).V1(j)].LenSum+=len;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
// se l'edge j e' di bordo si riazzera tutto e si riparte
|
// se l'edge j e' di bordo si riazzera tutto e si riparte
|
||||||
|
|
@ -231,12 +231,12 @@ static void VertexCoordScaleDependentLaplacian_Fujiwara(MeshType &m, int step, S
|
||||||
TD[(*fi).V(j)].LenSum=0;
|
TD[(*fi).V(j)].LenSum=0;
|
||||||
TD[(*fi).V1(j)].LenSum=0;
|
TD[(*fi).V1(j)].LenSum=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
CoordType edge= (*fi).V1(j)->P() -(*fi).V(j)->P();
|
CoordType edge= (*fi).V1(j)->P() -(*fi).V(j)->P();
|
||||||
ScalarType len=Norm(edge);
|
ScalarType len=Norm(edge);
|
||||||
edge/=len;
|
edge/=len;
|
||||||
|
|
@ -246,19 +246,19 @@ static void VertexCoordScaleDependentLaplacian_Fujiwara(MeshType &m, int step, S
|
||||||
TD[(*fi).V1(j)].LenSum+=len;
|
TD[(*fi).V1(j)].LenSum+=len;
|
||||||
}
|
}
|
||||||
// The fundamental part:
|
// The fundamental part:
|
||||||
// We move the new point of a quantity
|
// We move the new point of a quantity
|
||||||
//
|
//
|
||||||
// L(M) = 1/Sum(edgelen) * Sum(Normalized edges)
|
// L(M) = 1/Sum(edgelen) * Sum(Normalized edges)
|
||||||
//
|
//
|
||||||
|
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD() && TD[*vi].LenSum>0 )
|
if(!(*vi).IsD() && TD[*vi].LenSum>0 )
|
||||||
(*vi).P() = (*vi).P() + (TD[*vi].PntSum/TD[*vi].LenSum)*delta;
|
(*vi).P() = (*vi).P() + (TD[*vi].PntSum/TD[*vi].LenSum)*delta;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class LaplacianInfo
|
class LaplacianInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LaplacianInfo(const CoordType &_p, const int _n):sum(_p),cnt(_n) {}
|
LaplacianInfo(const CoordType &_p, const int _n):sum(_p),cnt(_n) {}
|
||||||
|
|
@ -268,35 +268,35 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Classical Laplacian Smoothing. Each vertex can be moved onto the average of the adjacent vertices.
|
// Classical Laplacian Smoothing. Each vertex can be moved onto the average of the adjacent vertices.
|
||||||
// Can smooth only the selected vertices and weight the smoothing according to the quality
|
// Can smooth only the selected vertices and weight the smoothing according to the quality
|
||||||
// In the latter case 0 means that the vertex is not moved and 1 means that the vertex is moved onto the computed position.
|
// In the latter case 0 means that the vertex is not moved and 1 means that the vertex is moved onto the computed position.
|
||||||
//
|
//
|
||||||
// From the Taubin definition "A signal proc approach to fair surface design"
|
// From the Taubin definition "A signal proc approach to fair surface design"
|
||||||
// We define the discrete Laplacian of a discrete surface signal by weighted averages over the neighborhoods
|
// We define the discrete Laplacian of a discrete surface signal by weighted averages over the neighborhoods
|
||||||
// \delta xi = \Sum wij (xj - xi) ;
|
// \delta xi = \Sum wij (xj - xi) ;
|
||||||
// where xj are the adjacent vertices of xi and wij is usually 1/n_adj
|
// where xj are the adjacent vertices of xi and wij is usually 1/n_adj
|
||||||
//
|
//
|
||||||
// This function simply accumulate over a TempData all the positions of the ajacent vertices
|
// This function simply accumulate over a TempData all the positions of the ajacent vertices
|
||||||
//
|
//
|
||||||
static void AccumulateLaplacianInfo(MeshType &m, SimpleTempData<typename MeshType::VertContainer,LaplacianInfo > &TD)
|
static void AccumulateLaplacianInfo(MeshType &m, SimpleTempData<typename MeshType::VertContainer,LaplacianInfo > &TD)
|
||||||
{
|
{
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
{
|
{
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if(!(*fi).IsB(j))
|
if(!(*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->P();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->P();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->P();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->P();
|
||||||
++TD[(*fi).V(j)].cnt;
|
++TD[(*fi).V(j)].cnt;
|
||||||
++TD[(*fi).V1(j)].cnt;
|
++TD[(*fi).V1(j)].cnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// si azzaera i dati per i vertici di bordo
|
// si azzaera i dati per i vertici di bordo
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
{
|
{
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
|
|
@ -306,13 +306,13 @@ static void AccumulateLaplacianInfo(MeshType &m, SimpleTempData<typename MeshTyp
|
||||||
TD[(*fi).V1(j)].cnt=1;
|
TD[(*fi).V1(j)].cnt=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
{
|
{
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->P();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->P();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->P();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->P();
|
||||||
|
|
@ -359,11 +359,11 @@ static void VertexCoordPlanarLaplacian(MeshType &m, int step, float AngleThrRad
|
||||||
if(!SmoothSelected || (*vi).IsS())
|
if(!SmoothSelected || (*vi).IsS())
|
||||||
TD[*vi].sum = ( (*vi).P() + TD[*vi].sum)/(TD[*vi].cnt+1);
|
TD[*vi].sum = ( (*vi).P() + TD[*vi].sum)/(TD[*vi].cnt+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi){
|
for(fi=m.face.begin();fi!=m.face.end();++fi){
|
||||||
if(!(*fi).IsD()){
|
if(!(*fi).IsD()){
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
if(Angle( NormalizedNormal(TD[(*fi).V0(j)].sum, (*fi).P1(j), (*fi).P2(j) ),
|
if(Angle( NormalizedNormal(TD[(*fi).V0(j)].sum, (*fi).P1(j), (*fi).P2(j) ),
|
||||||
NormalizedNormal( (*fi).P0(j) , (*fi).P1(j), (*fi).P2(j) ) ) > AngleThrRad )
|
NormalizedNormal( (*fi).P0(j) , (*fi).P1(j), (*fi).P2(j) ) ) > AngleThrRad )
|
||||||
TD[(*fi).V0(j)].sum = (*fi).P0(j);
|
TD[(*fi).V0(j)].sum = (*fi).P0(j);
|
||||||
}
|
}
|
||||||
|
|
@ -371,8 +371,8 @@ static void VertexCoordPlanarLaplacian(MeshType &m, int step, float AngleThrRad
|
||||||
}
|
}
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi){
|
for(fi=m.face.begin();fi!=m.face.end();++fi){
|
||||||
if(!(*fi).IsD()){
|
if(!(*fi).IsD()){
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
if(Angle( NormalizedNormal(TD[(*fi).V0(j)].sum, TD[(*fi).V1(j)].sum, (*fi).P2(j) ),
|
if(Angle( NormalizedNormal(TD[(*fi).V0(j)].sum, TD[(*fi).V1(j)].sum, (*fi).P2(j) ),
|
||||||
NormalizedNormal( (*fi).P0(j) , (*fi).P1(j), (*fi).P2(j) ) ) > AngleThrRad )
|
NormalizedNormal( (*fi).P0(j) , (*fi).P1(j), (*fi).P2(j) ) ) > AngleThrRad )
|
||||||
{
|
{
|
||||||
TD[(*fi).V0(j)].sum = (*fi).P0(j);
|
TD[(*fi).V0(j)].sum = (*fi).P0(j);
|
||||||
|
|
@ -381,16 +381,16 @@ static void VertexCoordPlanarLaplacian(MeshType &m, int step, float AngleThrRad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
||||||
(*vi).P()= TD[*vi].sum;
|
(*vi).P()= TD[*vi].sum;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}// end step
|
}// end step
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VertexCoordLaplacianBlend(MeshType &m, int step, float alpha, bool SmoothSelected=false)
|
static void VertexCoordLaplacianBlend(MeshType &m, int step, float alpha, bool SmoothSelected=false)
|
||||||
|
|
@ -408,7 +408,7 @@ static void VertexCoordLaplacianBlend(MeshType &m, int step, float alpha, bool S
|
||||||
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
||||||
{
|
{
|
||||||
if(!SmoothSelected || (*vi).IsS())
|
if(!SmoothSelected || (*vi).IsS())
|
||||||
{
|
{
|
||||||
CoordType Delta = TD[*vi].sum/TD[*vi].cnt - (*vi).P();
|
CoordType Delta = TD[*vi].sum/TD[*vi].cnt - (*vi).P();
|
||||||
(*vi).P() = (*vi).P() + Delta*alpha;
|
(*vi).P() = (*vi).P() + Delta*alpha;
|
||||||
}
|
}
|
||||||
|
|
@ -417,20 +417,20 @@ static void VertexCoordLaplacianBlend(MeshType &m, int step, float alpha, bool S
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a couple of notes about the lambda mu values
|
/* a couple of notes about the lambda mu values
|
||||||
We assume that 0 < lambda , and mu is a negative scale factor such that mu < - lambda.
|
We assume that 0 < lambda , and mu is a negative scale factor such that mu < - lambda.
|
||||||
Holds mu+lambda < 0 (e.g in absolute value mu is greater)
|
Holds mu+lambda < 0 (e.g in absolute value mu is greater)
|
||||||
|
|
||||||
let kpb be the pass-band frequency, taubin says that:
|
let kpb be the pass-band frequency, taubin says that:
|
||||||
kpb = 1/lambda + 1/mu >0
|
kpb = 1/lambda + 1/mu >0
|
||||||
|
|
||||||
Values of kpb from 0.01 to 0.1 produce good results according to the original paper.
|
Values of kpb from 0.01 to 0.1 produce good results according to the original paper.
|
||||||
|
|
||||||
kpb * mu - mu/lambda = 1
|
kpb * mu - mu/lambda = 1
|
||||||
mu = 1/(kpb-1/lambda )
|
mu = 1/(kpb-1/lambda )
|
||||||
|
|
||||||
So if
|
So if
|
||||||
* lambda == 0.5, kpb==0.1 -> mu = 1/(0.1 - 2) = -0.526
|
* lambda == 0.5, kpb==0.1 -> mu = 1/(0.1 - 2) = -0.526
|
||||||
* lambda == 0.5, kpb==0.01 -> mu = 1/(0.01 - 2) = -0.502
|
* lambda == 0.5, kpb==0.01 -> mu = 1/(0.01 - 2) = -0.502
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -448,7 +448,7 @@ static void VertexCoordTaubin(MeshType &m, int step, float lambda, float mu, boo
|
||||||
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
||||||
{
|
{
|
||||||
if(!SmoothSelected || (*vi).IsS())
|
if(!SmoothSelected || (*vi).IsS())
|
||||||
{
|
{
|
||||||
CoordType Delta = TD[*vi].sum/TD[*vi].cnt - (*vi).P();
|
CoordType Delta = TD[*vi].sum/TD[*vi].cnt - (*vi).P();
|
||||||
(*vi).P() = (*vi).P() + Delta*lambda ;
|
(*vi).P() = (*vi).P() + Delta*lambda ;
|
||||||
}
|
}
|
||||||
|
|
@ -459,12 +459,12 @@ static void VertexCoordTaubin(MeshType &m, int step, float lambda, float mu, boo
|
||||||
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
||||||
{
|
{
|
||||||
if(!SmoothSelected || (*vi).IsS())
|
if(!SmoothSelected || (*vi).IsS())
|
||||||
{
|
{
|
||||||
CoordType Delta = TD[*vi].sum/TD[*vi].cnt - (*vi).P();
|
CoordType Delta = TD[*vi].sum/TD[*vi].cnt - (*vi).P();
|
||||||
(*vi).P() = (*vi).P() + Delta*mu ;
|
(*vi).P() = (*vi).P() + Delta*mu ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end for step
|
} // end for step
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -492,7 +492,7 @@ static void VertexCoordLaplacianQuality(MeshType &m, int step, bool SmoothSelect
|
||||||
EUROGRAPHICS Volume 18 (1999), Number 3
|
EUROGRAPHICS Volume 18 (1999), Number 3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class HCSmoothInfo
|
class HCSmoothInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CoordType dif;
|
CoordType dif;
|
||||||
|
|
@ -521,10 +521,10 @@ static void VertexCoordLaplacianHC(MeshType &m, int step, bool SmoothSelected=fa
|
||||||
++TD[(*fi).V(j)].cnt;
|
++TD[(*fi).V(j)].cnt;
|
||||||
++TD[(*fi).V1(j)].cnt;
|
++TD[(*fi).V1(j)].cnt;
|
||||||
// se l'edge j e' di bordo si deve sommare due volte
|
// se l'edge j e' di bordo si deve sommare due volte
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->P();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->P();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->P();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->P();
|
||||||
++TD[(*fi).V(j)].cnt;
|
++TD[(*fi).V(j)].cnt;
|
||||||
++TD[(*fi).V1(j)].cnt;
|
++TD[(*fi).V1(j)].cnt;
|
||||||
}
|
}
|
||||||
|
|
@ -533,7 +533,7 @@ static void VertexCoordLaplacianHC(MeshType &m, int step, bool SmoothSelected=fa
|
||||||
VertexIterator vi;
|
VertexIterator vi;
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
|
||||||
TD[*vi].sum/=(float)TD[*vi].cnt;
|
TD[*vi].sum/=(float)TD[*vi].cnt;
|
||||||
|
|
||||||
// Second Loop compute average difference
|
// Second Loop compute average difference
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
{
|
{
|
||||||
|
|
@ -542,8 +542,8 @@ static void VertexCoordLaplacianHC(MeshType &m, int step, bool SmoothSelected=fa
|
||||||
TD[(*fi).V(j)].dif +=TD[(*fi).V1(j)].sum-(*fi).V1(j)->P();
|
TD[(*fi).V(j)].dif +=TD[(*fi).V1(j)].sum-(*fi).V1(j)->P();
|
||||||
TD[(*fi).V1(j)].dif+=TD[(*fi).V(j)].sum-(*fi).V(j)->P();
|
TD[(*fi).V1(j)].dif+=TD[(*fi).V(j)].sum-(*fi).V(j)->P();
|
||||||
// se l'edge j e' di bordo si deve sommare due volte
|
// se l'edge j e' di bordo si deve sommare due volte
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].dif +=TD[(*fi).V1(j)].sum-(*fi).V1(j)->P();
|
TD[(*fi).V(j)].dif +=TD[(*fi).V1(j)].sum-(*fi).V1(j)->P();
|
||||||
TD[(*fi).V1(j)].dif+=TD[(*fi).V(j)].sum-(*fi).V(j)->P();
|
TD[(*fi).V1(j)].dif+=TD[(*fi).V(j)].sum-(*fi).V(j)->P();
|
||||||
}
|
}
|
||||||
|
|
@ -559,10 +559,10 @@ static void VertexCoordLaplacianHC(MeshType &m, int step, bool SmoothSelected=fa
|
||||||
} // end for step
|
} // end for step
|
||||||
};
|
};
|
||||||
|
|
||||||
// Laplacian smooth of the quality.
|
// Laplacian smooth of the quality.
|
||||||
|
|
||||||
|
|
||||||
class ColorSmoothInfo
|
class ColorSmoothInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
|
|
@ -573,7 +573,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=false, vcg::CallBackPos * cb=0)
|
static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=false, vcg::CallBackPos * cb=0)
|
||||||
{
|
{
|
||||||
ColorSmoothInfo csi;
|
ColorSmoothInfo csi;
|
||||||
csi.r=0; csi.g=0; csi.b=0; csi.cnt=0;
|
csi.r=0; csi.g=0; csi.b=0; csi.cnt=0;
|
||||||
SimpleTempData<typename MeshType::VertContainer, ColorSmoothInfo> TD(m.vert,csi);
|
SimpleTempData<typename MeshType::VertContainer, ColorSmoothInfo> TD(m.vert,csi);
|
||||||
|
|
@ -587,9 +587,9 @@ static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=fals
|
||||||
|
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if(!(*fi).IsB(j))
|
if(!(*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].r+=(*fi).V1(j)->C()[0];
|
TD[(*fi).V(j)].r+=(*fi).V1(j)->C()[0];
|
||||||
TD[(*fi).V(j)].g+=(*fi).V1(j)->C()[1];
|
TD[(*fi).V(j)].g+=(*fi).V1(j)->C()[1];
|
||||||
|
|
@ -598,8 +598,8 @@ static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=fals
|
||||||
|
|
||||||
TD[(*fi).V1(j)].r+=(*fi).V(j)->C()[0];
|
TD[(*fi).V1(j)].r+=(*fi).V(j)->C()[0];
|
||||||
TD[(*fi).V1(j)].g+=(*fi).V(j)->C()[1];
|
TD[(*fi).V1(j)].g+=(*fi).V(j)->C()[1];
|
||||||
TD[(*fi).V1(j)].b+=(*fi).V(j)->C()[2];
|
TD[(*fi).V1(j)].b+=(*fi).V(j)->C()[2];
|
||||||
TD[(*fi).V1(j)].a+=(*fi).V(j)->C()[3];
|
TD[(*fi).V1(j)].a+=(*fi).V(j)->C()[3];
|
||||||
|
|
||||||
++TD[(*fi).V(j)].cnt;
|
++TD[(*fi).V(j)].cnt;
|
||||||
++TD[(*fi).V1(j)].cnt;
|
++TD[(*fi).V1(j)].cnt;
|
||||||
|
|
@ -607,7 +607,7 @@ static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=fals
|
||||||
|
|
||||||
// si azzaera i dati per i vertici di bordo
|
// si azzaera i dati per i vertici di bordo
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
|
|
@ -617,9 +617,9 @@ static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=fals
|
||||||
|
|
||||||
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].r+=(*fi).V1(j)->C()[0];
|
TD[(*fi).V(j)].r+=(*fi).V1(j)->C()[0];
|
||||||
TD[(*fi).V(j)].g+=(*fi).V1(j)->C()[1];
|
TD[(*fi).V(j)].g+=(*fi).V1(j)->C()[1];
|
||||||
|
|
@ -628,7 +628,7 @@ static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=fals
|
||||||
|
|
||||||
TD[(*fi).V1(j)].r+=(*fi).V(j)->C()[0];
|
TD[(*fi).V1(j)].r+=(*fi).V(j)->C()[0];
|
||||||
TD[(*fi).V1(j)].g+=(*fi).V(j)->C()[1];
|
TD[(*fi).V1(j)].g+=(*fi).V(j)->C()[1];
|
||||||
TD[(*fi).V1(j)].b+=(*fi).V(j)->C()[2];
|
TD[(*fi).V1(j)].b+=(*fi).V(j)->C()[2];
|
||||||
TD[(*fi).V1(j)].a+=(*fi).V(j)->C()[3];
|
TD[(*fi).V1(j)].a+=(*fi).V(j)->C()[3];
|
||||||
|
|
||||||
++TD[(*fi).V(j)].cnt;
|
++TD[(*fi).V(j)].cnt;
|
||||||
|
|
@ -648,23 +648,23 @@ static void VertexColorLaplacian(MeshType &m, int step, bool SmoothSelected=fals
|
||||||
};
|
};
|
||||||
|
|
||||||
static void FaceColorLaplacian(MeshType &m, int step, bool SmoothSelected=false, vcg::CallBackPos * cb=0)
|
static void FaceColorLaplacian(MeshType &m, int step, bool SmoothSelected=false, vcg::CallBackPos * cb=0)
|
||||||
{
|
{
|
||||||
ColorSmoothInfo csi;
|
ColorSmoothInfo csi;
|
||||||
csi.r=0; csi.g=0; csi.b=0; csi.cnt=0;
|
csi.r=0; csi.g=0; csi.b=0; csi.cnt=0;
|
||||||
SimpleTempData<typename MeshType::FaceContainer, ColorSmoothInfo> TD(m.face,csi);
|
SimpleTempData<typename MeshType::FaceContainer, ColorSmoothInfo> TD(m.face,csi);
|
||||||
|
|
||||||
for(int i=0;i<step;++i)
|
for(int i=0;i<step;++i)
|
||||||
{
|
{
|
||||||
if(cb) cb(100*i/step, "Face Color Laplacian Smoothing");
|
if(cb) cb(100*i/step, "Face Color Laplacian Smoothing");
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
TD[*fi]=csi;
|
TD[*fi]=csi;
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
{
|
{
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if(!(*fi).IsB(j))
|
if(!(*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[*fi].r+=(*fi).FFp(j)->C()[0];
|
TD[*fi].r+=(*fi).FFp(j)->C()[0];
|
||||||
TD[*fi].g+=(*fi).FFp(j)->C()[1];
|
TD[*fi].g+=(*fi).FFp(j)->C()[1];
|
||||||
|
|
@ -685,9 +685,9 @@ static void FaceColorLaplacian(MeshType &m, int step, bool SmoothSelected=false,
|
||||||
} // end for step
|
} // end for step
|
||||||
};
|
};
|
||||||
|
|
||||||
// Laplacian smooth of the quality.
|
// Laplacian smooth of the quality.
|
||||||
|
|
||||||
class QualitySmoothInfo
|
class QualitySmoothInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScalarType sum;
|
ScalarType sum;
|
||||||
|
|
@ -696,7 +696,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
static void VertexQualityLaplacian(MeshType &m, int step=1, bool SmoothSelected=false)
|
static void VertexQualityLaplacian(MeshType &m, int step=1, bool SmoothSelected=false)
|
||||||
{
|
{
|
||||||
QualitySmoothInfo lpz;
|
QualitySmoothInfo lpz;
|
||||||
lpz.sum=0;
|
lpz.sum=0;
|
||||||
lpz.cnt=0;
|
lpz.cnt=0;
|
||||||
|
|
@ -710,9 +710,9 @@ static void VertexQualityLaplacian(MeshType &m, int step=1, bool SmoothSelected=
|
||||||
|
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if(!(*fi).IsB(j))
|
if(!(*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->Q();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->Q();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->Q();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->Q();
|
||||||
|
|
@ -722,7 +722,7 @@ static void VertexQualityLaplacian(MeshType &m, int step=1, bool SmoothSelected=
|
||||||
|
|
||||||
// si azzaera i dati per i vertici di bordo
|
// si azzaera i dati per i vertici di bordo
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
|
|
@ -732,9 +732,9 @@ static void VertexQualityLaplacian(MeshType &m, int step=1, bool SmoothSelected=
|
||||||
|
|
||||||
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->Q();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->Q();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->Q();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->Q();
|
||||||
|
|
@ -748,7 +748,7 @@ static void VertexQualityLaplacian(MeshType &m, int step=1, bool SmoothSelected=
|
||||||
if(!SmoothSelected || (*vi).IsS())
|
if(!SmoothSelected || (*vi).IsS())
|
||||||
(*vi).Q()=TD[*vi].sum/TD[*vi].cnt;
|
(*vi).Q()=TD[*vi].sum/TD[*vi].cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TD.Stop();
|
//TD.Stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -767,9 +767,9 @@ static void VertexNormalLaplacian(MeshType &m, int step,bool SmoothSelected=fals
|
||||||
|
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if(!(*fi).IsB(j))
|
if(!(*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->N();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->N();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->N();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->N();
|
||||||
|
|
@ -779,7 +779,7 @@ static void VertexNormalLaplacian(MeshType &m, int step,bool SmoothSelected=fals
|
||||||
|
|
||||||
// si azzaera i dati per i vertici di bordo
|
// si azzaera i dati per i vertici di bordo
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
|
|
@ -789,9 +789,9 @@ static void VertexNormalLaplacian(MeshType &m, int step,bool SmoothSelected=fals
|
||||||
|
|
||||||
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->N();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->N();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->N();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->N();
|
||||||
|
|
@ -805,7 +805,7 @@ static void VertexNormalLaplacian(MeshType &m, int step,bool SmoothSelected=fals
|
||||||
if(!SmoothSelected || (*vi).IsS())
|
if(!SmoothSelected || (*vi).IsS())
|
||||||
(*vi).N()=TD[*vi].sum/TD[*vi].cnt;
|
(*vi).N()=TD[*vi].sum/TD[*vi].cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
TD.Stop();
|
TD.Stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -829,9 +829,9 @@ static void VertexCoordViewDepth(MeshType &m,
|
||||||
|
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if(!(*fi).IsB(j))
|
if(!(*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->cP();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->cP();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->cP();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->cP();
|
||||||
|
|
@ -841,7 +841,7 @@ static void VertexCoordViewDepth(MeshType &m,
|
||||||
|
|
||||||
// si azzaera i dati per i vertici di bordo
|
// si azzaera i dati per i vertici di bordo
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
|
|
@ -852,22 +852,22 @@ static void VertexCoordViewDepth(MeshType &m,
|
||||||
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
// se l'edge j e' di bordo si deve mediare solo con gli adiacenti
|
||||||
if(SmoothBorder)
|
if(SmoothBorder)
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsB(j))
|
if((*fi).IsB(j))
|
||||||
{
|
{
|
||||||
TD[(*fi).V(j)].sum+=(*fi).V1(j)->cP();
|
TD[(*fi).V(j)].sum+=(*fi).V1(j)->cP();
|
||||||
TD[(*fi).V1(j)].sum+=(*fi).V(j)->cP();
|
TD[(*fi).V1(j)].sum+=(*fi).V(j)->cP();
|
||||||
++TD[(*fi).V(j)].cnt;
|
++TD[(*fi).V(j)].cnt;
|
||||||
++TD[(*fi).V1(j)].cnt;
|
++TD[(*fi).V1(j)].cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
if(!(*vi).IsD() && TD[*vi].cnt>0 )
|
||||||
{
|
{
|
||||||
CoordType np = TD[*vi].sum/TD[*vi].cnt;
|
CoordType np = TD[*vi].sum/TD[*vi].cnt;
|
||||||
CoordType d = (*vi).cP() - viewpoint; d.Normalize();
|
CoordType d = (*vi).cP() - viewpoint; d.Normalize();
|
||||||
ScalarType s = d * ( np - (*vi).cP() );
|
ScalarType s = d .dot ( np - (*vi).cP() );
|
||||||
(*vi).P() += d * (s*alpha);
|
(*vi).P() += d * (s*alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -885,14 +885,14 @@ static void VertexCoordViewDepth(MeshType &m,
|
||||||
/****************************************************************************************************************/
|
/****************************************************************************************************************/
|
||||||
// Classi di info
|
// Classi di info
|
||||||
|
|
||||||
class PDVertInfo
|
class PDVertInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CoordType np;
|
CoordType np;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PDFaceInfo
|
class PDFaceInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CoordType m;
|
CoordType m;
|
||||||
|
|
@ -903,17 +903,17 @@ public:
|
||||||
// Requirements:
|
// Requirements:
|
||||||
// VF Topology
|
// VF Topology
|
||||||
// Normalized Face Normals
|
// Normalized Face Normals
|
||||||
//
|
//
|
||||||
// This is the Normal Smoothing approach of Shen and Berner
|
// This is the Normal Smoothing approach of Shen and Berner
|
||||||
// Fuzzy Vector Median-Based Surface Smoothing TVCG 2004
|
// Fuzzy Vector Median-Based Surface Smoothing TVCG 2004
|
||||||
|
|
||||||
|
|
||||||
void FaceNormalFuzzyVectorSB(MeshType &m,
|
void FaceNormalFuzzyVectorSB(MeshType &m,
|
||||||
SimpleTempData<typename MeshType::FaceContainer,PDFaceInfo > &TD,
|
SimpleTempData<typename MeshType::FaceContainer,PDFaceInfo > &TD,
|
||||||
ScalarType sigma)
|
ScalarType sigma)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
|
|
@ -930,7 +930,7 @@ void FaceNormalFuzzyVectorSB(MeshType &m,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1) Effectively average the normals weighting them with
|
// 1) Effectively average the normals weighting them with
|
||||||
(*fi).SetV();
|
(*fi).SetV();
|
||||||
CoordType mm=CoordType(0,0,0);
|
CoordType mm=CoordType(0,0,0);
|
||||||
for(i=0;i<3;++i)
|
for(i=0;i<3;++i)
|
||||||
|
|
@ -940,7 +940,7 @@ void FaceNormalFuzzyVectorSB(MeshType &m,
|
||||||
{
|
{
|
||||||
if(! (*ep.f).IsV() )
|
if(! (*ep.f).IsV() )
|
||||||
{
|
{
|
||||||
if(sigma>0)
|
if(sigma>0)
|
||||||
{
|
{
|
||||||
ScalarType dd=SquaredDistance(ep.f->Barycenter(),bc);
|
ScalarType dd=SquaredDistance(ep.f->Barycenter(),bc);
|
||||||
ScalarType ang=AngleN(ep.f->N(),(*fi).N());
|
ScalarType ang=AngleN(ep.f->N(),(*fi).N());
|
||||||
|
|
@ -957,7 +957,7 @@ void FaceNormalFuzzyVectorSB(MeshType &m,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the normal of the face with the average of normals of the vertex adijacent faces.
|
// Replace the normal of the face with the average of normals of the vertex adijacent faces.
|
||||||
// Normals are weighted with face area.
|
// Normals are weighted with face area.
|
||||||
// It assumes that:
|
// It assumes that:
|
||||||
// Normals are normalized:
|
// Normals are normalized:
|
||||||
|
|
@ -966,16 +966,16 @@ void FaceNormalFuzzyVectorSB(MeshType &m,
|
||||||
static void FaceNormalLaplacianVF(MeshType &m)
|
static void FaceNormalLaplacianVF(MeshType &m)
|
||||||
{
|
{
|
||||||
SimpleTempData<typename MeshType::FaceContainer, PDFaceInfo> TDF(m.face);
|
SimpleTempData<typename MeshType::FaceContainer, PDFaceInfo> TDF(m.face);
|
||||||
|
|
||||||
PDFaceInfo lpzf;
|
PDFaceInfo lpzf;
|
||||||
lpzf.m=CoordType(0,0,0);
|
lpzf.m=CoordType(0,0,0);
|
||||||
|
|
||||||
assert(tri::HasVFAdjacency(m));
|
assert(tri::HasVFAdjacency(m));
|
||||||
TDF.Start(lpzf);
|
TDF.Start(lpzf);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
|
|
||||||
tri::UpdateNormals<MeshType>::AreaNormalizeFace(m);
|
tri::UpdateNormals<MeshType>::AreaNormalizeFace(m);
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
|
|
@ -991,7 +991,7 @@ static void FaceNormalLaplacianVF(MeshType &m)
|
||||||
|
|
||||||
// 2) Effectively average the normals
|
// 2) Effectively average the normals
|
||||||
CoordType normalSum=(*fi).N();
|
CoordType normalSum=(*fi).N();
|
||||||
|
|
||||||
for(i=0;i<3;++i)
|
for(i=0;i<3;++i)
|
||||||
{
|
{
|
||||||
VFLocalIterator ep(&*fi,i);
|
VFLocalIterator ep(&*fi,i);
|
||||||
|
|
@ -999,7 +999,7 @@ static void FaceNormalLaplacianVF(MeshType &m)
|
||||||
{
|
{
|
||||||
if(! (*ep.f).IsV() )
|
if(! (*ep.f).IsV() )
|
||||||
{
|
{
|
||||||
normalSum += ep.f->N();
|
normalSum += ep.f->N();
|
||||||
(*ep.f).SetV();
|
(*ep.f).SetV();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1007,7 +1007,7 @@ static void FaceNormalLaplacianVF(MeshType &m)
|
||||||
normalSum.Normalize();
|
normalSum.Normalize();
|
||||||
TDF[*fi].m=normalSum;
|
TDF[*fi].m=normalSum;
|
||||||
}
|
}
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
(*fi).N()=TDF[*fi].m;
|
(*fi).N()=TDF[*fi].m;
|
||||||
|
|
||||||
tri::UpdateNormals<MeshType>::NormalizeFace(m);
|
tri::UpdateNormals<MeshType>::NormalizeFace(m);
|
||||||
|
|
@ -1015,7 +1015,7 @@ static void FaceNormalLaplacianVF(MeshType &m)
|
||||||
TDF.Stop();
|
TDF.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the normal of the face with the average of normals of the face adijacent faces.
|
// Replace the normal of the face with the average of normals of the face adijacent faces.
|
||||||
// Normals are weighted with face area.
|
// Normals are weighted with face area.
|
||||||
// It assumes that:
|
// It assumes that:
|
||||||
// Normals are normalized:
|
// Normals are normalized:
|
||||||
|
|
@ -1026,7 +1026,7 @@ static void FaceNormalLaplacianFF(MeshType &m, int step=1, bool SmoothSelected=f
|
||||||
{
|
{
|
||||||
PDFaceInfo lpzf;
|
PDFaceInfo lpzf;
|
||||||
lpzf.m=CoordType(0,0,0);
|
lpzf.m=CoordType(0,0,0);
|
||||||
SimpleTempData<typename MeshType::FaceContainer, PDFaceInfo> TDF(m.face,lpzf);
|
SimpleTempData<typename MeshType::FaceContainer, PDFaceInfo> TDF(m.face,lpzf);
|
||||||
assert(tri::HasFFAdjacency(m));
|
assert(tri::HasFFAdjacency(m));
|
||||||
|
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
|
|
@ -1042,7 +1042,7 @@ static void FaceNormalLaplacianFF(MeshType &m, int step=1, bool SmoothSelected=f
|
||||||
|
|
||||||
TDF[*fi].m=normalSum;
|
TDF[*fi].m=normalSum;
|
||||||
}
|
}
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!SmoothSelected || (*fi).IsS())
|
if(!SmoothSelected || (*fi).IsS())
|
||||||
(*fi).N()=TDF[*fi].m;
|
(*fi).N()=TDF[*fi].m;
|
||||||
|
|
||||||
|
|
@ -1057,23 +1057,23 @@ static void FaceNormalLaplacianFF(MeshType &m, int step=1, bool SmoothSelected=f
|
||||||
// Requirements:
|
// Requirements:
|
||||||
// VF Topology
|
// VF Topology
|
||||||
// Normalized Face Normals
|
// Normalized Face Normals
|
||||||
//
|
//
|
||||||
// This is the Normal Smoothing approach bsased on a angle thresholded weighting
|
// This is the Normal Smoothing approach bsased on a angle thresholded weighting
|
||||||
// sigma is in the 0 .. 1 range, it represent the cosine of a threshold angle.
|
// sigma is in the 0 .. 1 range, it represent the cosine of a threshold angle.
|
||||||
// sigma == 0 All the normals are averaged
|
// sigma == 0 All the normals are averaged
|
||||||
// sigma == 1 Nothing is averaged.
|
// sigma == 1 Nothing is averaged.
|
||||||
// Only within the specified range are averaged toghether. The averagin is weighted with the
|
// Only within the specified range are averaged toghether. The averagin is weighted with the
|
||||||
|
|
||||||
|
|
||||||
static void FaceNormalAngleThreshold(MeshType &m,
|
static void FaceNormalAngleThreshold(MeshType &m,
|
||||||
SimpleTempData<typename MeshType::FaceContainer,PDFaceInfo> &TD,
|
SimpleTempData<typename MeshType::FaceContainer,PDFaceInfo> &TD,
|
||||||
ScalarType sigma)
|
ScalarType sigma)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
{
|
{
|
||||||
CoordType bc=Barycenter<FaceType>(*fi);
|
CoordType bc=Barycenter<FaceType>(*fi);
|
||||||
|
|
@ -1086,10 +1086,10 @@ static void FaceNormalAngleThreshold(MeshType &m,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1) Effectively average the normals weighting them with the squared difference of the angle similarity
|
// 1) Effectively average the normals weighting them with the squared difference of the angle similarity
|
||||||
// sigma is the cosine of a threshold angle. sigma \in 0..1
|
// sigma is the cosine of a threshold angle. sigma \in 0..1
|
||||||
// sigma == 0 All the normals are averaged
|
// sigma == 0 All the normals are averaged
|
||||||
// sigma == 1 Nothing is averaged.
|
// sigma == 1 Nothing is averaged.
|
||||||
// The averaging is weighted with the difference between normals. more similar the normal more important they are.
|
// The averaging is weighted with the difference between normals. more similar the normal more important they are.
|
||||||
|
|
||||||
CoordType normalSum=CoordType(0,0,0);
|
CoordType normalSum=CoordType(0,0,0);
|
||||||
for(i=0;i<3;++i)
|
for(i=0;i<3;++i)
|
||||||
|
|
@ -1098,12 +1098,12 @@ static void FaceNormalAngleThreshold(MeshType &m,
|
||||||
for (;!ep.End();++ep)
|
for (;!ep.End();++ep)
|
||||||
{
|
{
|
||||||
if(! (*ep.f).IsV() )
|
if(! (*ep.f).IsV() )
|
||||||
{
|
{
|
||||||
ScalarType cosang=ep.f->N().dot((*fi).N());
|
ScalarType cosang=ep.f->N().dot((*fi).N());
|
||||||
// Note that if two faces form an angle larger than 90 deg, their contribution should be very very small.
|
// Note that if two faces form an angle larger than 90 deg, their contribution should be very very small.
|
||||||
// Without this clamping
|
// Without this clamping
|
||||||
cosang = math::Clamp(cosang,0.0001f,1.f);
|
cosang = math::Clamp(cosang,0.0001f,1.f);
|
||||||
if(cosang >= sigma)
|
if(cosang >= sigma)
|
||||||
{
|
{
|
||||||
ScalarType w = cosang-sigma;
|
ScalarType w = cosang-sigma;
|
||||||
normalSum += ep.f->N()*(w*w); // similar normals have a cosang very close to 1 so cosang - sigma is maximized
|
normalSum += ep.f->N()*(w*w); // similar normals have a cosang very close to 1 so cosang - sigma is maximized
|
||||||
|
|
@ -1115,8 +1115,8 @@ static void FaceNormalAngleThreshold(MeshType &m,
|
||||||
normalSum.Normalize();
|
normalSum.Normalize();
|
||||||
TD[*fi].m=normalSum;
|
TD[*fi].m=normalSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
(*fi).N()=TD[*fi].m;
|
(*fi).N()=TD[*fi].m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1159,10 +1159,10 @@ CoordType CrossProdGradient(CoordType &p, CoordType &p0, CoordType &p1, CoordTyp
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Deve Calcolare il gradiente di
|
Deve Calcolare il gradiente di
|
||||||
E(p) = A(p,p0,p1) (n - m)^2 =
|
E(p) = A(p,p0,p1) (n - m)^2 =
|
||||||
A(...) (2-2nm) =
|
A(...) (2-2nm) =
|
||||||
(p0-p)^(p1-p)
|
(p0-p)^(p1-p)
|
||||||
2A - 2A * ------------- m =
|
2A - 2A * ------------- m =
|
||||||
2A
|
2A
|
||||||
|
|
||||||
|
|
@ -1179,7 +1179,7 @@ CoordType FaceErrorGrad(CoordType &p,CoordType &p0,CoordType &p1, CoordType &m)
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
void FitMesh(MeshType &m,
|
void FitMesh(MeshType &m,
|
||||||
SimpleTempData<typename MeshType::VertContainer, PDVertInfo> &TDV,
|
SimpleTempData<typename MeshType::VertContainer, PDVertInfo> &TDV,
|
||||||
SimpleTempData<typename MeshType::FaceContainer, PDFaceInfo> &TDF,
|
SimpleTempData<typename MeshType::FaceContainer, PDFaceInfo> &TDF,
|
||||||
float lambda)
|
float lambda)
|
||||||
|
|
@ -1198,7 +1198,7 @@ void FitMesh(MeshType &m,
|
||||||
ErrGrad+=FaceErrorGrad(ep.f->V(ep.z)->P(),ep.f->V1(ep.z)->P(),ep.f->V2(ep.z)->P(),TDF[ep.f].m);
|
ErrGrad+=FaceErrorGrad(ep.f->V(ep.z)->P(),ep.f->V1(ep.z)->P(),ep.f->V2(ep.z)->P(),TDF[ep.f].m);
|
||||||
++ep;
|
++ep;
|
||||||
}
|
}
|
||||||
TDV[*vi].np=(*vi).P()-ErrGrad*(ScalarType)lambda;
|
TDV[*vi].np=(*vi).P()-ErrGrad*(ScalarType)lambda;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
|
|
@ -1209,7 +1209,7 @@ void FitMesh(MeshType &m,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void FastFitMesh(MeshType &m,
|
static void FastFitMesh(MeshType &m,
|
||||||
SimpleTempData<typename MeshType::VertContainer, PDVertInfo> &TDV,
|
SimpleTempData<typename MeshType::VertContainer, PDVertInfo> &TDV,
|
||||||
SimpleTempData<typename MeshType::FaceContainer, PDFaceInfo> &TDF,
|
SimpleTempData<typename MeshType::FaceContainer, PDFaceInfo> &TDF,
|
||||||
bool OnlySelected=false)
|
bool OnlySelected=false)
|
||||||
|
|
@ -1229,13 +1229,13 @@ static void FastFitMesh(MeshType &m,
|
||||||
Sum += ep.F()->N()*(ep.F()->N().dot(bc - (*vi).P()));
|
Sum += ep.F()->N()*(ep.F()->N().dot(bc - (*vi).P()));
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
TDV[*vi].np=(*vi).P()+ Sum*(1.0/cnt);
|
TDV[*vi].np=(*vi).P()+ Sum*(1.0/cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(OnlySelected)
|
if(OnlySelected)
|
||||||
{
|
{
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if((*vi).IsS()) (*vi).P()=TDV[*vi].np;
|
if((*vi).IsS()) (*vi).P()=TDV[*vi].np;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1285,10 +1285,10 @@ static void VertexCoordPasoDobleFast(MeshType &m, int NormalSmoothStep, typename
|
||||||
assert(HasVFAdjacency(m));
|
assert(HasVFAdjacency(m));
|
||||||
SimpleTempData< typename MeshType::VertContainer, PDVertInfo> TDV(m.vert,lpzv);
|
SimpleTempData< typename MeshType::VertContainer, PDVertInfo> TDV(m.vert,lpzv);
|
||||||
SimpleTempData< typename MeshType::FaceContainer, PDFaceInfo> TDF(m.face,lpzf);
|
SimpleTempData< typename MeshType::FaceContainer, PDFaceInfo> TDF(m.face,lpzf);
|
||||||
|
|
||||||
for(int j=0;j<NormalSmoothStep;++j)
|
for(int j=0;j<NormalSmoothStep;++j)
|
||||||
FaceNormalAngleThreshold(m,TDF,Sigma);
|
FaceNormalAngleThreshold(m,TDF,Sigma);
|
||||||
|
|
||||||
for(int j=0;j<FitStep;++j)
|
for(int j=0;j<FitStep;++j)
|
||||||
FastFitMesh(m,TDV,TDF,SmoothSelected);
|
FastFitMesh(m,TDV,TDF,SmoothSelected);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
#define EIGEN_VCGLIB
|
#define EIGEN_VCGLIB
|
||||||
|
|
||||||
// TODO enable the vectorization
|
// TODO enable the vectorization
|
||||||
#define EIGEN_DONT_VECTORIZE
|
// #define EIGEN_DONT_VECTORIZE
|
||||||
#define EIGEN_MATRIXBASE_PLUGIN <vcg/math/eigen_matrixbase_addons.h>
|
#define EIGEN_MATRIXBASE_PLUGIN <vcg/math/eigen_matrixbase_addons.h>
|
||||||
#define EIGEN_MATRIX_PLUGIN <vcg/math/eigen_matrix_addons.h>
|
#define EIGEN_MATRIX_PLUGIN <vcg/math/eigen_matrix_addons.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,37 +138,37 @@ Trackball::~Trackball()
|
||||||
|
|
||||||
void Trackball::ClearModes()
|
void Trackball::ClearModes()
|
||||||
{
|
{
|
||||||
// Note: people ofter maps different keys to the same modes.
|
// Note: people ofter maps different keys to the same modes.
|
||||||
// so we should avoid double deletion of these double referenced modes.
|
// so we should avoid double deletion of these double referenced modes.
|
||||||
std::set<TrackMode *> goodModes;
|
std::set<TrackMode *> goodModes;
|
||||||
std::map<int, TrackMode *>::iterator it;
|
std::map<int, TrackMode *>::iterator it;
|
||||||
for(it = modes.begin(); it != modes.end(); it++)
|
for(it = modes.begin(); it != modes.end(); it++)
|
||||||
if ((*it).second) goodModes.insert( (*it).second);
|
if ((*it).second) goodModes.insert( (*it).second);
|
||||||
|
|
||||||
std::set<TrackMode *>::iterator its;
|
std::set<TrackMode *>::iterator its;
|
||||||
for(its = goodModes.begin(); its != goodModes.end(); its++)
|
for(its = goodModes.begin(); its != goodModes.end(); its++)
|
||||||
delete *its;
|
delete *its;
|
||||||
|
|
||||||
modes.clear();
|
modes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trackball::setDefaultMapping () {
|
void Trackball::setDefaultMapping () {
|
||||||
idle_and_keys_mode = NULL;
|
idle_and_keys_mode = NULL;
|
||||||
|
|
||||||
inactive_mode = new InactiveMode ();
|
inactive_mode = new InactiveMode ();
|
||||||
ClearModes();
|
ClearModes();
|
||||||
modes[0] = NULL;
|
modes[0] = NULL;
|
||||||
|
|
||||||
modes[BUTTON_MIDDLE | KEY_ALT] =
|
modes[BUTTON_MIDDLE | KEY_ALT] =
|
||||||
modes[BUTTON_LEFT] = new SphereMode ();
|
modes[BUTTON_LEFT] = new SphereMode ();
|
||||||
|
|
||||||
modes[BUTTON_LEFT | KEY_CTRL] = new PanMode ();
|
modes[BUTTON_LEFT | KEY_CTRL] = new PanMode ();
|
||||||
|
|
||||||
modes[BUTTON_MIDDLE] = new PanMode ();
|
modes[BUTTON_MIDDLE] = new PanMode ();
|
||||||
|
|
||||||
modes[WHEEL] =
|
modes[WHEEL] =
|
||||||
modes[BUTTON_LEFT | KEY_SHIFT] = new ScaleMode ();
|
modes[BUTTON_LEFT | KEY_SHIFT] = new ScaleMode ();
|
||||||
|
|
||||||
modes[BUTTON_LEFT | KEY_ALT] = new ZMode ();
|
modes[BUTTON_LEFT | KEY_ALT] = new ZMode ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -216,12 +216,18 @@ void Trackball::ApplyInverse() {
|
||||||
|
|
||||||
// T(c) S R T(t) T(-c) => S R T(S^(-1) R^(-1)(c) + t - c)
|
// T(c) S R T(t) T(-c) => S R T(S^(-1) R^(-1)(c) + t - c)
|
||||||
Matrix44f Trackball::Matrix() const{
|
Matrix44f Trackball::Matrix() const{
|
||||||
|
#ifndef VCG_USE_EIGEN
|
||||||
Matrix44f r; track.rot.ToMatrix(r);
|
Matrix44f r; track.rot.ToMatrix(r);
|
||||||
Matrix44f sr = Matrix44f().SetScale(track.sca, track.sca, track.sca) * r;
|
Matrix44f sr = Matrix44f().SetScale(track.sca, track.sca, track.sca) * r;
|
||||||
Matrix44f s_inv = Matrix44f().SetScale(1/track.sca, 1/track.sca, 1/track.sca);
|
Matrix44f s_inv = Matrix44f().SetScale(1/track.sca, 1/track.sca, 1/track.sca);
|
||||||
Matrix44f t = Matrix44f().SetTranslate(s_inv*r.transpose()*center + track.tra - center);
|
Matrix44f t = Matrix44f().SetTranslate(s_inv*r.transpose()*center + track.tra - center);
|
||||||
|
|
||||||
return Matrix44f(sr*t);
|
return Matrix44f(sr*t);
|
||||||
|
#else
|
||||||
|
Eigen::Quaternionf rot(track.rot);
|
||||||
|
Eigen::Translation3f tr( (1/track.sca) * (rot.inverse() * center) + track.tra - center );
|
||||||
|
return ( Eigen::Scaling3f(track.sca) * (rot * tr) ).matrix();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix44f Trackball::InverseMatrix() const{
|
Matrix44f Trackball::InverseMatrix() const{
|
||||||
|
|
@ -466,11 +472,11 @@ void Trackball::ButtonDown(Trackball::Button button, unsigned int msec) {
|
||||||
|
|
||||||
Button b=Button(current_button & MODIFIER_MASK);
|
Button b=Button(current_button & MODIFIER_MASK);
|
||||||
if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) old_sticky = modes[b]->isSticky();
|
if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) old_sticky = modes[b]->isSticky();
|
||||||
|
|
||||||
current_button |= button;
|
current_button |= button;
|
||||||
b=Button(current_button & MODIFIER_MASK);
|
b=Button(current_button & MODIFIER_MASK);
|
||||||
if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) new_sticky = modes[b]->isSticky();
|
if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) new_sticky = modes[b]->isSticky();
|
||||||
|
|
||||||
if ( !old_sticky && !new_sticky) SetCurrentAction();
|
if ( !old_sticky && !new_sticky) SetCurrentAction();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -481,11 +487,11 @@ void Trackball::ButtonUp(Trackball::Button button) {
|
||||||
|
|
||||||
Button b=Button(current_button & MODIFIER_MASK);
|
Button b=Button(current_button & MODIFIER_MASK);
|
||||||
if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) old_sticky = modes[b]->isSticky();
|
if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) old_sticky = modes[b]->isSticky();
|
||||||
|
|
||||||
current_button &= (~button);
|
current_button &= (~button);
|
||||||
b=Button(current_button & MODIFIER_MASK);
|
b=Button(current_button & MODIFIER_MASK);
|
||||||
if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) new_sticky = modes[b]->isSticky();
|
if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) new_sticky = modes[b]->isSticky();
|
||||||
|
|
||||||
if ( !old_sticky && !new_sticky) SetCurrentAction();
|
if ( !old_sticky && !new_sticky) SetCurrentAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue