make point2 derived Eigen's Matrix, and a set of minimal fixes to make meshlab compile
with both old and new version. The fixes include: - dot product: vec0 * vec1 => vec0.dot(vec1) (I added .dot() to the old Point classes too) - Transpose: Transpose is an Eigen type, so we cannot keep it if Eigen is used. Therefore I added a .tranpose() to old matrix classes, and modified most of the Transpose() to transpose() both in vcg and meshlab. In fact, transpose() are free with Eigen, it simply returns a transpose expression without copies. On the other be carefull: m = m.transpose() won't work as expected, here me must evaluate to a temporary: m = m.transpose().eval(); However, this operation in very rarely needed: you transpose at the same sime you set m, or you use m.transpose() directly. - the last issue is Normalize which both modifies *this and return a ref to it. This behavior don't make sense anymore when using expression template, e.g., in (a+b).Normalize(), the type of a+b if not a Point (or whatever Vector types), it an expression of the addition of 2 points, so we cannot modify the value of *this, since there is no value. Therefore I've already changed all those .Normalize() of expressions to the Eigen's version .normalized(). - Finally I've changed the Zero to SetZero in the old Point classes too.
This commit is contained in:
parent
393ec38d54
commit
7befff7bec
|
@ -403,7 +403,7 @@ public:
|
||||||
{
|
{
|
||||||
if(Params().NormalCheck){
|
if(Params().NormalCheck){
|
||||||
nn=NormalizedNormal(*x.F());
|
nn=NormalizedNormal(*x.F());
|
||||||
ndiff=nn*on[i++];
|
ndiff=nn.dot(on[i++]);
|
||||||
if(ndiff<MinCos) MinCos=ndiff;
|
if(ndiff<MinCos) MinCos=ndiff;
|
||||||
}
|
}
|
||||||
if(Params().QualityCheck){
|
if(Params().QualityCheck){
|
||||||
|
@ -416,7 +416,7 @@ public:
|
||||||
{
|
{
|
||||||
if(Params().NormalCheck){
|
if(Params().NormalCheck){
|
||||||
nn=NormalizedNormal(*x.F());
|
nn=NormalizedNormal(*x.F());
|
||||||
ndiff=nn*on[i++];
|
ndiff=nn.dot(on[i++]);
|
||||||
if(ndiff<MinCos) MinCos=ndiff;
|
if(ndiff<MinCos) MinCos=ndiff;
|
||||||
}
|
}
|
||||||
if(Params().QualityCheck){
|
if(Params().QualityCheck){
|
||||||
|
@ -542,7 +542,7 @@ static void InitQuadric(TriMeshType &m)
|
||||||
if(!Params().UseArea)
|
if(!Params().UseArea)
|
||||||
p.Normalize();
|
p.Normalize();
|
||||||
|
|
||||||
p.SetOffset( p.Direction() * (*pf).V(0)->cP());
|
p.SetOffset( p.Direction().dot((*pf).V(0)->cP()));
|
||||||
|
|
||||||
// Calcolo quadrica delle facce
|
// Calcolo quadrica delle facce
|
||||||
q.ByPlane(p);
|
q.ByPlane(p);
|
||||||
|
@ -559,10 +559,10 @@ static void InitQuadric(TriMeshType &m)
|
||||||
// Nota che la lunghezza dell'edge DEVE essere Normalizzata
|
// Nota che la lunghezza dell'edge DEVE essere Normalizzata
|
||||||
// poiche' la pesatura in funzione dell'area e'gia fatta in p.Direction()
|
// poiche' la pesatura in funzione dell'area e'gia fatta in p.Direction()
|
||||||
// Senza la normalize il bordo e' pesato in funzione della grandezza della mesh (mesh grandi non decimano sul bordo)
|
// Senza la normalize il bordo e' pesato in funzione della grandezza della mesh (mesh grandi non decimano sul bordo)
|
||||||
pb.SetDirection(p.Direction() ^ ( (*pf).V1(j)->cP() - (*pf).V(j)->cP() ).Normalize());
|
pb.SetDirection(p.Direction() ^ ( (*pf).V1(j)->cP() - (*pf).V(j)->cP() ).normalized());
|
||||||
if( (*pf).IsB(j) ) pb.SetDirection(pb.Direction()* (ScalarType)Params().BoundaryWeight); // amplify border planes
|
if( (*pf).IsB(j) ) pb.SetDirection(pb.Direction()* (ScalarType)Params().BoundaryWeight); // amplify border planes
|
||||||
else pb.SetDirection(pb.Direction()* (ScalarType)(Params().BoundaryWeight/100.0)); // and consider much less quadric for quality
|
else pb.SetDirection(pb.Direction()* (ScalarType)(Params().BoundaryWeight/100.0)); // and consider much less quadric for quality
|
||||||
pb.SetOffset(pb.Direction() * (*pf).V(j)->cP());
|
pb.SetOffset(pb.Direction().dot((*pf).V(j)->cP()));
|
||||||
q.ByPlane(pb);
|
q.ByPlane(pb);
|
||||||
|
|
||||||
if( (*pf).V (j)->IsW() ) QH::Qd((*pf).V (j)) += q; // Sommo le quadriche
|
if( (*pf).V (j)->IsW() ) QH::Qd((*pf).V (j)) += q; // Sommo le quadriche
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
typedef typename MeshType::CoordType CoordType;
|
typedef typename MeshType::CoordType CoordType;
|
||||||
typedef typename MeshType::VertexIterator VertexIterator;
|
typedef typename MeshType::VertexIterator VertexIterator;
|
||||||
typedef typename MeshType::VertexType VertexType;
|
typedef typename MeshType::VertexType VertexType;
|
||||||
typedef vcg::Point4< vcg::Point3<ScalarType> > FourPoints ;
|
typedef vcg::Point4< vcg::Point3<ScalarType> > FourPoints;
|
||||||
typedef vcg::GridStaticPtr<typename PMesh::VertexType, ScalarType > GridType;
|
typedef vcg::GridStaticPtr<typename PMesh::VertexType, ScalarType > GridType;
|
||||||
|
|
||||||
/* class for Parameters */
|
/* class for Parameters */
|
||||||
|
@ -110,11 +110,11 @@ private:
|
||||||
|
|
||||||
|
|
||||||
/* returns the closest point between to segments x1-x2 and x3-x4. */
|
/* returns the closest point between to segments x1-x2 and x3-x4. */
|
||||||
void IntersectionLineLine( const CoordType & x1,const CoordType & x2,const CoordType & x3,const CoordType & x4,
|
void IntersectionLineLine(const CoordType & x1,const CoordType & x2,const CoordType & x3,const CoordType & x4, CoordType&x)
|
||||||
CoordType&x){
|
{
|
||||||
CoordType a = x2-x1, b = x4-x3, c = x3-x1;
|
CoordType a = x2-x1, b = x4-x3, c = x3-x1;
|
||||||
x = x1 + a * ( (c^b)*(a^b)) / (a^b).SquaredNorm();
|
x = x1 + a * ((c^b).dot(a^b)) / (a^b).SquaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ FourPCS<MeshType>::SelectCoplanarBase(){
|
||||||
int id = rand()/(float)RAND_MAX * (P->vert.size()-1);
|
int id = rand()/(float)RAND_MAX * (P->vert.size()-1);
|
||||||
ScalarType dd = (P->vert[id].P() - B[1]).Norm();
|
ScalarType dd = (P->vert[id].P() - B[1]).Norm();
|
||||||
if( ( dd < side + dtol) && (dd > side - dtol)){
|
if( ( dd < side + dtol) && (dd > side - dtol)){
|
||||||
ScalarType angle = fabs( ( P->vert[id].P()-B[1]).Normalize() * (B[1]-B[0]).Normalize());
|
ScalarType angle = fabs( ( P->vert[id].P()-B[1]).normalized().dot((B[1]-B[0]).normalized()));
|
||||||
if( angle < bestv){
|
if( angle < bestv){
|
||||||
bestv = angle;
|
bestv = angle;
|
||||||
best = id;
|
best = id;
|
||||||
|
@ -301,7 +301,7 @@ FourPCS<MeshType>::SelectCoplanarBase(){
|
||||||
B[2] = P->vert[best].P();
|
B[2] = P->vert[best].P();
|
||||||
//printf("B[2] %d\n",best);
|
//printf("B[2] %d\n",best);
|
||||||
|
|
||||||
CoordType n = ((B[0]-B[1]).Normalize() ^ (B[2]-B[1]).Normalize()).Normalize();
|
CoordType n = ((B[0]-B[1]).normalized() ^ (B[2]-B[1]).normalized()).normalized();
|
||||||
CoordType B4 = B[1] + (B[0]-B[1]) + (B[2]-B[1]);
|
CoordType B4 = B[1] + (B[0]-B[1]) + (B[2]-B[1]);
|
||||||
VertexType * v =0;
|
VertexType * v =0;
|
||||||
ScalarType dist,radius = dtol*4.0;
|
ScalarType dist,radius = dtol*4.0;
|
||||||
|
@ -322,7 +322,7 @@ FourPCS<MeshType>::SelectCoplanarBase(){
|
||||||
return false;
|
return false;
|
||||||
best = -1; bestv=std::numeric_limits<float>::max();
|
best = -1; bestv=std::numeric_limits<float>::max();
|
||||||
for(i = 0; i <closests.size(); ++i){
|
for(i = 0; i <closests.size(); ++i){
|
||||||
ScalarType angle = fabs((closests[i]->P() - B[1]).Normalize() * n);
|
ScalarType angle = fabs((closests[i]->P() - B[1]).normalized().dot(n));
|
||||||
if( angle < bestv){
|
if( angle < bestv){
|
||||||
bestv = angle;
|
bestv = angle;
|
||||||
best = i;
|
best = i;
|
||||||
|
@ -337,8 +337,8 @@ FourPCS<MeshType>::SelectCoplanarBase(){
|
||||||
std::swap(B[1],B[2]);
|
std::swap(B[1],B[2]);
|
||||||
IntersectionLineLine(B[0],B[1],B[2],B[3],x);
|
IntersectionLineLine(B[0],B[1],B[2],B[3],x);
|
||||||
|
|
||||||
r1 = (x - B[0])*(B[1]-B[0]) / (B[1]-B[0]).SquaredNorm();
|
r1 = (x - B[0]).dot(B[1]-B[0]) / (B[1]-B[0]).SquaredNorm();
|
||||||
r2 = (x - B[2])*(B[3]-B[2]) / (B[3]-B[2]).SquaredNorm();
|
r2 = (x - B[2]).dot(B[3]-B[2]) / (B[3]-B[2]).SquaredNorm();
|
||||||
|
|
||||||
if( ((B[0]+(B[1]-B[0])*r1)-(B[2]+(B[3]-B[2])*r2)).Norm() > prs.delta )
|
if( ((B[0]+(B[1]-B[0])*r1)-(B[2]+(B[3]-B[2])*r2)).Norm() > prs.delta )
|
||||||
return false;
|
return false;
|
||||||
|
@ -374,10 +374,10 @@ FourPCS<MeshType>::IsTransfCongruent(FourPoints fp,vcg::Matrix44<ScalarType> & m
|
||||||
for(int i = 0 ; i < 4; ++i) fix.push_back(fp[i]);
|
for(int i = 0 ; i < 4; ++i) fix.push_back(fp[i]);
|
||||||
|
|
||||||
vcg::Point3<ScalarType> n,p;
|
vcg::Point3<ScalarType> n,p;
|
||||||
n = (( B[1]-B[0]).Normalize() ^ ( B[2]- B[0]).Normalize())*( B[1]- B[0]).Norm();
|
n = (( B[1]-B[0]).normalized() ^ ( B[2]- B[0]).normalized())*( B[1]- B[0]).Norm();
|
||||||
p = B[0] + n;
|
p = B[0] + n;
|
||||||
mov.push_back(p);
|
mov.push_back(p);
|
||||||
n = (( fp[1]-fp[0]).Normalize() ^ (fp[2]- fp[0]).Normalize())*( fp[1]- fp[0]).Norm();
|
n = (( fp[1]-fp[0]).normalized() ^ (fp[2]- fp[0]).normalized())*( fp[1]- fp[0]).Norm();
|
||||||
p = fp[0] + n;
|
p = fp[0] + n;
|
||||||
fix.push_back(p);
|
fix.push_back(p);
|
||||||
|
|
||||||
|
@ -565,7 +565,7 @@ int FourPCS<MeshType>::EvaluateSample(CandiType & fp, CoordType & tp, CoordType
|
||||||
>(*Q,ugridQ,vq,radius, dist );
|
>(*Q,ugridQ,vq,radius, dist );
|
||||||
|
|
||||||
if(v!=0)
|
if(v!=0)
|
||||||
if( v->N() * np -angle >0) return 1; else return -1;
|
if( v->N().dot(np) -angle >0) return 1; else return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1152,7 +1152,7 @@ static bool TestIntersection(FaceType *f0,FaceType *f1)
|
||||||
//no adiacent faces
|
//no adiacent faces
|
||||||
if ( (f0!=f1) && (!ShareEdge(f0,f1))
|
if ( (f0!=f1) && (!ShareEdge(f0,f1))
|
||||||
&& (!ShareVertex(f0,f1)) )
|
&& (!ShareVertex(f0,f1)) )
|
||||||
return (vcg::Intersection<FaceType>((*f0),(*f1)));
|
return (vcg::Intersection_<FaceType>((*f0),(*f1)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -101,7 +101,7 @@ class HashedPoint3i : public Point3i
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const size_t Hash() const
|
const size_t Hash() const
|
||||||
{
|
{
|
||||||
return (V(0)*HASH_P0 ^ V(1)*HASH_P1 ^ V(2)*HASH_P2);
|
return (V(0)*HASH_P0 ^ V(1)*HASH_P1 ^ V(2)*HASH_P2);
|
||||||
}
|
}
|
||||||
|
@ -129,9 +129,9 @@ class AverageCell
|
||||||
inline void Add(MeshType &m, FaceType &f, int i)
|
inline void Add(MeshType &m, FaceType &f, int i)
|
||||||
{
|
{
|
||||||
p+=f.cV(i)->cP();
|
p+=f.cV(i)->cP();
|
||||||
// we prefer to use the un-normalized face normal so small faces facing away are dropped out
|
// we prefer to use the un-normalized face normal so small faces facing away are dropped out
|
||||||
// and the resulting average is weighed with the size of the faces falling here.
|
// and the resulting average is weighed with the size of the faces falling here.
|
||||||
n+=f.cN();
|
n+=f.cN();
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
AverageCell(): p(0,0,0), n(0,0,0),cnt(0){}
|
AverageCell(): p(0,0,0), n(0,0,0),cnt(0){}
|
||||||
|
@ -139,7 +139,7 @@ class AverageCell
|
||||||
CoordType n;
|
CoordType n;
|
||||||
int cnt;
|
int cnt;
|
||||||
int id;
|
int id;
|
||||||
CoordType Pos() const
|
CoordType Pos() const
|
||||||
{
|
{
|
||||||
return p/cnt;
|
return p/cnt;
|
||||||
}
|
}
|
||||||
|
@ -159,9 +159,9 @@ class AverageColorCell
|
||||||
p+=f.cV(i)->cP();
|
p+=f.cV(i)->cP();
|
||||||
c+=CoordType(f.cV(i)->C()[0],f.cV(i)->C()[1],f.cV(i)->C()[2]);
|
c+=CoordType(f.cV(i)->C()[0],f.cV(i)->C()[1],f.cV(i)->C()[2]);
|
||||||
|
|
||||||
// we prefer to use the un-normalized face normal so small faces facing away are dropped out
|
// we prefer to use the un-normalized face normal so small faces facing away are dropped out
|
||||||
// and the resulting average is weighed with the size of the faces falling here.
|
// and the resulting average is weighed with the size of the faces falling here.
|
||||||
n+=f.cN();
|
n+=f.cN();
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
AverageColorCell(): p(0,0,0), n(0,0,0), c(0,0,0),cnt(0){}
|
AverageColorCell(): p(0,0,0), n(0,0,0), c(0,0,0),cnt(0){}
|
||||||
|
@ -170,12 +170,12 @@ class AverageColorCell
|
||||||
CoordType c;
|
CoordType c;
|
||||||
int cnt;
|
int cnt;
|
||||||
int id;
|
int id;
|
||||||
Color4b Col() const
|
Color4b Col() const
|
||||||
{
|
{
|
||||||
return Color4b(c[0]/cnt,c[1]/cnt,c[2]/cnt,255);
|
return Color4b(c[0]/cnt,c[1]/cnt,c[2]/cnt,255);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoordType Pos() const
|
CoordType Pos() const
|
||||||
{
|
{
|
||||||
return p/cnt;
|
return p/cnt;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ class AverageColorCell
|
||||||
*/
|
*/
|
||||||
template<class MeshType, class CellType, bool Selected=true>
|
template<class MeshType, class CellType, bool Selected=true>
|
||||||
class Clustering
|
class Clustering
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename MeshType::ScalarType ScalarType;
|
typedef typename MeshType::ScalarType ScalarType;
|
||||||
typedef typename MeshType::CoordType CoordType;
|
typedef typename MeshType::CoordType CoordType;
|
||||||
|
@ -198,7 +198,7 @@ class Clustering
|
||||||
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
|
// 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.
|
// will be merged into two identical but opposite faces.
|
||||||
// So in practice:
|
// So in practice:
|
||||||
// DuplicateFace=true a model with looks ok if you enable backface culling
|
// 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
|
// DuplicateFace=false a model with looks ok if you enable doublesided lighting and disable backfaceculling
|
||||||
|
@ -207,7 +207,7 @@ class Clustering
|
||||||
|
|
||||||
class SimpleTri
|
class SimpleTri
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CellType *v[3];
|
CellType *v[3];
|
||||||
const int ii(int i) const {return *((int *)(&(v[i])));}
|
const int ii(int i) const {return *((int *)(&(v[i])));}
|
||||||
bool operator < ( const SimpleTri &p) const {
|
bool operator < ( const SimpleTri &p) const {
|
||||||
|
@ -218,7 +218,7 @@ class Clustering
|
||||||
|
|
||||||
// Sort the vertex of the face maintaining the original face orientation (it only ensure that v0 is the minimum)
|
// Sort the vertex of the face maintaining the original face orientation (it only ensure that v0 is the minimum)
|
||||||
void sortOrient()
|
void sortOrient()
|
||||||
{
|
{
|
||||||
if(v[1] < v[0] && v[1] < v[2] ) { std::swap(v[0],v[1]); std::swap(v[1],v[2]); return; } // v1 was the minimum
|
if(v[1] < v[0] && v[1] < v[2] ) { std::swap(v[0],v[1]); std::swap(v[1],v[2]); return; } // v1 was the minimum
|
||||||
if(v[2] < v[0] && v[2] < v[1] ) { std::swap(v[0],v[2]); std::swap(v[1],v[2]); return; } // v2 was the minimum
|
if(v[2] < v[0] && v[2] < v[1] ) { std::swap(v[0],v[2]); std::swap(v[1],v[2]); return; } // v2 was the minimum
|
||||||
return; // v0 was the minimum;
|
return; // v0 was the minimum;
|
||||||
|
@ -238,13 +238,13 @@ class Clustering
|
||||||
|
|
||||||
|
|
||||||
// The init function Take two parameters
|
// The init function Take two parameters
|
||||||
// _size is the approximate total number of cells composing the grid surrounding the objects (usually a large number)
|
// _size is the approximate total number of cells composing the grid surrounding the objects (usually a large number)
|
||||||
// eg _size==1.000.000 means a 100x100x100 grid
|
// eg _size==1.000.000 means a 100x100x100 grid
|
||||||
// _cellsize is the absolute lenght of the edge of the grid cell.
|
// _cellsize is the absolute lenght of the edge of the grid cell.
|
||||||
// eg _cellsize==2.0 means that all the vertexes in a 2.0x2.0x2.0 cell are clustered togheter
|
// eg _cellsize==2.0 means that all the vertexes in a 2.0x2.0x2.0 cell are clustered togheter
|
||||||
|
|
||||||
// Notes:
|
// Notes:
|
||||||
// _size is used only if the cell edge IS zero.
|
// _size is used only if the cell edge IS zero.
|
||||||
// _cellsize gives you an absolute measure of the maximum error introduced
|
// _cellsize gives you an absolute measure of the maximum error introduced
|
||||||
// during the simplification (e.g. half of the cell edge lenght)
|
// during the simplification (e.g. half of the cell edge lenght)
|
||||||
|
|
||||||
|
@ -267,8 +267,8 @@ class Clustering
|
||||||
Grid.voxel[1] = Grid.dim[1]/Grid.siz[1];
|
Grid.voxel[1] = Grid.dim[1]/Grid.siz[1];
|
||||||
Grid.voxel[2] = Grid.dim[2]/Grid.siz[2];
|
Grid.voxel[2] = Grid.dim[2]/Grid.siz[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BasicGrid<ScalarType> Grid;
|
BasicGrid<ScalarType> Grid;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -283,7 +283,7 @@ class Clustering
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STDEXT::hash_map<HashedPoint3i,CellType> GridCell;
|
STDEXT::hash_map<HashedPoint3i,CellType> GridCell;
|
||||||
|
|
||||||
void Add(MeshType &m)
|
void Add(MeshType &m)
|
||||||
{
|
{
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
|
@ -300,17 +300,17 @@ class Clustering
|
||||||
Grid.PToIP((*fi).cV(i)->cP(), pi );
|
Grid.PToIP((*fi).cV(i)->cP(), pi );
|
||||||
st.v[i]=&(GridCell[pi]);
|
st.v[i]=&(GridCell[pi]);
|
||||||
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)
|
{ // if we allow the duplication of faces we sort the vertex only partially (to maintain the original face orientation)
|
||||||
if(DuplicateFaceParam) st.sortOrient();
|
if(DuplicateFaceParam) st.sortOrient();
|
||||||
else st.sort();
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extract(MeshType &m)
|
void Extract(MeshType &m)
|
||||||
{
|
{
|
||||||
m.Clear();
|
m.Clear();
|
||||||
|
@ -339,23 +339,23 @@ 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
|
// if we are merging faces even when opposite we choose
|
||||||
// the best orientation according to the averaged normal
|
// the best orientation according to the averaged normal
|
||||||
if(!DuplicateFaceParam)
|
if(!DuplicateFaceParam)
|
||||||
{
|
{
|
||||||
CoordType N=vcg::Normal(m.face[i]);
|
CoordType N=vcg::Normal(m.face[i]);
|
||||||
int badOrient=0;
|
int badOrient=0;
|
||||||
if( N*(*ti).v[0]->n <0) ++badOrient;
|
if( N.dot((*ti).v[0]->n) <0) ++badOrient;
|
||||||
if( N*(*ti).v[1]->n <0) ++badOrient;
|
if( N.dot((*ti).v[1]->n) <0) ++badOrient;
|
||||||
if( N*(*ti).v[2]->n <0) ++badOrient;
|
if( N.dot((*ti).v[2]->n) <0) ++badOrient;
|
||||||
if(badOrient>2)
|
if(badOrient>2)
|
||||||
std::swap(m.face[i].V(0),m.face[i].V(1));
|
std::swap(m.face[i].V(0),m.face[i].V(1));
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}; //end class clustering
|
}; //end class clustering
|
||||||
} // namespace tri
|
} // namespace tri
|
||||||
} // namespace vcg
|
} // namespace vcg
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT>
|
||||||
|
|
||||||
dir.Normalize();
|
dir.Normalize();
|
||||||
//direction of normal inside the mesh
|
//direction of normal inside the mesh
|
||||||
if ((dir*closestNorm)<0)
|
if ((dir.dot(closestNorm))<0)
|
||||||
dist=-dist;
|
dist=-dist;
|
||||||
//the intersection exist
|
//the intersection exist
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -212,7 +212,7 @@ namespace vcg {
|
||||||
void ComputeAngle()
|
void ComputeAngle()
|
||||||
{
|
{
|
||||||
angle=Angle(cP(2)-cP(0), cP(1)-cP(0));
|
angle=Angle(cP(2)-cP(0), cP(1)-cP(0));
|
||||||
ScalarType flipAngle = n * e0.v->N();
|
ScalarType flipAngle = n.dot(e0.v->N());
|
||||||
if(flipAngle<0) angle = (2.0 *(float)M_PI) - angle;
|
if(flipAngle<0) angle = (2.0 *(float)M_PI) - angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -40,17 +40,17 @@ Revision 1.13 2005/11/17 00:42:03 cignoni
|
||||||
#define _VCG_INERTIA_
|
#define _VCG_INERTIA_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The algorithm is based on a three step reduction of the volume integrals
|
The algorithm is based on a three step reduction of the volume integrals
|
||||||
to successively simpler integrals. The algorithm is designed to minimize
|
to successively simpler integrals. The algorithm is designed to minimize
|
||||||
the numerical errors that can result from poorly conditioned alignment of
|
the numerical errors that can result from poorly conditioned alignment of
|
||||||
polyhedral faces. It is also designed for efficiency. All required volume
|
polyhedral faces. It is also designed for efficiency. All required volume
|
||||||
integrals of a polyhedron are computed together during a single walk over
|
integrals of a polyhedron are computed together during a single walk over
|
||||||
the boundary of the polyhedron; exploiting common subexpressions reduces
|
the boundary of the polyhedron; exploiting common subexpressions reduces
|
||||||
floating point operations.
|
floating point operations.
|
||||||
|
|
||||||
For more information, check out:
|
For more information, check out:
|
||||||
|
|
||||||
Brian Mirtich,
|
Brian Mirtich,
|
||||||
``Fast and Accurate Computation of Polyhedral Mass Properties,''
|
``Fast and Accurate Computation of Polyhedral Mass Properties,''
|
||||||
journal of graphics tools, volume 1, number 2, 1996
|
journal of graphics tools, volume 1, number 2, 1996
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ namespace vcg
|
||||||
template <class InertiaMeshType>
|
template <class InertiaMeshType>
|
||||||
class Inertia
|
class Inertia
|
||||||
{
|
{
|
||||||
typedef InertiaMeshType MeshType;
|
typedef InertiaMeshType MeshType;
|
||||||
typedef typename MeshType::VertexType VertexType;
|
typedef typename MeshType::VertexType VertexType;
|
||||||
typedef typename MeshType::VertexPointer VertexPointer;
|
typedef typename MeshType::VertexPointer VertexPointer;
|
||||||
typedef typename MeshType::VertexIterator VertexIterator;
|
typedef typename MeshType::VertexIterator VertexIterator;
|
||||||
|
@ -121,7 +121,7 @@ public:
|
||||||
db = b1 - b0;
|
db = b1 - b0;
|
||||||
a0_2 = a0 * a0; a0_3 = a0_2 * a0; a0_4 = a0_3 * a0;
|
a0_2 = a0 * a0; a0_3 = a0_2 * a0; a0_4 = a0_3 * a0;
|
||||||
b0_2 = b0 * b0; b0_3 = b0_2 * b0; b0_4 = b0_3 * b0;
|
b0_2 = b0 * b0; b0_3 = b0_2 * b0; b0_4 = b0_3 * b0;
|
||||||
a1_2 = a1 * a1; a1_3 = a1_2 * a1;
|
a1_2 = a1 * a1; a1_3 = a1_2 * a1;
|
||||||
b1_2 = b1 * b1; b1_3 = b1_2 * b1;
|
b1_2 = b1 * b1; b1_3 = b1_2 * b1;
|
||||||
|
|
||||||
C1 = a1 + a0;
|
C1 = a1 + a0;
|
||||||
|
@ -180,7 +180,7 @@ void CompFaceIntegrals(FaceType &f)
|
||||||
|
|
||||||
Faaa = k1 * Paaa;
|
Faaa = k1 * Paaa;
|
||||||
Fbbb = k1 * Pbbb;
|
Fbbb = k1 * Pbbb;
|
||||||
Fccc = -k4 * (CUBE(n[A])*Paaa + 3*SQR(n[A])*n[B]*Paab
|
Fccc = -k4 * (CUBE(n[A])*Paaa + 3*SQR(n[A])*n[B]*Paab
|
||||||
+ 3*n[A]*SQR(n[B])*Pabb + CUBE(n[B])*Pbbb
|
+ 3*n[A]*SQR(n[B])*Pabb + CUBE(n[B])*Pbbb
|
||||||
+ 3*w*(SQR(n[A])*Paa + 2*n[A]*n[B]*Pab + SQR(n[B])*Pbb)
|
+ 3*w*(SQR(n[A])*Paa + 2*n[A]*n[B]*Pab + SQR(n[B])*Pbb)
|
||||||
+ w*w*(3*(n[A]*Pa + n[B]*Pb) + w*P1));
|
+ w*w*(3*(n[A]*Pa + n[B]*Pb) + w*P1));
|
||||||
|
@ -197,13 +197,13 @@ void Compute(MeshType &m)
|
||||||
tri::UpdateNormals<MeshType>::PerFaceNormalized(m);
|
tri::UpdateNormals<MeshType>::PerFaceNormalized(m);
|
||||||
double nx, ny, nz;
|
double nx, ny, nz;
|
||||||
|
|
||||||
T0 = T1[X] = T1[Y] = T1[Z]
|
T0 = T1[X] = T1[Y] = T1[Z]
|
||||||
= T2[X] = T2[Y] = T2[Z]
|
= T2[X] = T2[Y] = T2[Z]
|
||||||
= TP[X] = TP[Y] = TP[Z] = 0;
|
= TP[X] = TP[Y] = TP[Z] = 0;
|
||||||
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()) {
|
||||||
FaceType &f=(*fi);
|
FaceType &f=(*fi);
|
||||||
|
|
||||||
nx = fabs(f.N()[0]);
|
nx = fabs(f.N()[0]);
|
||||||
ny = fabs(f.N()[1]);
|
ny = fabs(f.N()[1]);
|
||||||
nz = fabs(f.N()[2]);
|
nz = fabs(f.N()[2]);
|
||||||
|
@ -233,12 +233,12 @@ void Compute(MeshType &m)
|
||||||
}
|
}
|
||||||
|
|
||||||
ScalarType Mass()
|
ScalarType Mass()
|
||||||
{
|
{
|
||||||
return static_cast<ScalarType>(T0);
|
return static_cast<ScalarType>(T0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Point3<ScalarType> CenterOfMass()
|
Point3<ScalarType> CenterOfMass()
|
||||||
{
|
{
|
||||||
Point3<ScalarType> r;
|
Point3<ScalarType> r;
|
||||||
r[X] = T1[X] / T0;
|
r[X] = T1[X] / T0;
|
||||||
r[Y] = T1[Y] / T0;
|
r[Y] = T1[Y] / T0;
|
||||||
|
@ -261,9 +261,9 @@ void InertiaTensor(Matrix33<ScalarType> &J ){
|
||||||
J[X][X] -= T0 * (r[Y]*r[Y] + r[Z]*r[Z]);
|
J[X][X] -= T0 * (r[Y]*r[Y] + r[Z]*r[Z]);
|
||||||
J[Y][Y] -= T0 * (r[Z]*r[Z] + r[X]*r[X]);
|
J[Y][Y] -= T0 * (r[Z]*r[Z] + r[X]*r[X]);
|
||||||
J[Z][Z] -= T0 * (r[X]*r[X] + r[Y]*r[Y]);
|
J[Z][Z] -= T0 * (r[X]*r[X] + r[Y]*r[Y]);
|
||||||
J[X][Y] = J[Y][X] += T0 * r[X] * r[Y];
|
J[X][Y] = J[Y][X] += T0 * r[X] * r[Y];
|
||||||
J[Y][Z] = J[Z][Y] += T0 * r[Y] * r[Z];
|
J[Y][Z] = J[Z][Y] += T0 * r[Y] * r[Z];
|
||||||
J[Z][X] = J[X][Z] += T0 * r[Z] * r[X];
|
J[Z][X] = J[X][Z] += T0 * r[Z] * r[X];
|
||||||
}
|
}
|
||||||
|
|
||||||
void InertiaTensor(Matrix44<ScalarType> &J )
|
void InertiaTensor(Matrix44<ScalarType> &J )
|
||||||
|
@ -284,9 +284,9 @@ void InertiaTensor(Matrix44<ScalarType> &J )
|
||||||
J[X][X] -= T0 * (r[Y]*r[Y] + r[Z]*r[Z]);
|
J[X][X] -= T0 * (r[Y]*r[Y] + r[Z]*r[Z]);
|
||||||
J[Y][Y] -= T0 * (r[Z]*r[Z] + r[X]*r[X]);
|
J[Y][Y] -= T0 * (r[Z]*r[Z] + r[X]*r[X]);
|
||||||
J[Z][Z] -= T0 * (r[X]*r[X] + r[Y]*r[Y]);
|
J[Z][Z] -= T0 * (r[X]*r[X] + r[Y]*r[Y]);
|
||||||
J[X][Y] = J[Y][X] += T0 * r[X] * r[Y];
|
J[X][Y] = J[Y][X] += T0 * r[X] * r[Y];
|
||||||
J[Y][Z] = J[Z][Y] += T0 * r[Y] * r[Z];
|
J[Y][Z] = J[Z][Y] += T0 * r[Y] * r[Z];
|
||||||
J[Z][X] = J[X][Z] += T0 * r[Z] * r[X];
|
J[Z][X] = J[X][Z] += T0 * r[Z] * r[X];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -321,8 +321,8 @@ static void Covariance(const MeshType & m, vcg::Point3<ScalarType> & bary, vcg::
|
||||||
area+=vcg::DoubleArea(*fi);
|
area+=vcg::DoubleArea(*fi);
|
||||||
}
|
}
|
||||||
bary/=area;
|
bary/=area;
|
||||||
|
|
||||||
|
|
||||||
C.SetZero();
|
C.SetZero();
|
||||||
// C as covariance of triangle (0,0,0)(1,0,0)(0,1,0)
|
// C as covariance of triangle (0,0,0)(1,0,0)(0,1,0)
|
||||||
vcg::Matrix33<ScalarType> C0;
|
vcg::Matrix33<ScalarType> C0;
|
||||||
|
@ -345,9 +345,15 @@ static void Covariance(const MeshType & m, vcg::Point3<ScalarType> & bary, vcg::
|
||||||
const float da = n.Norm();
|
const float da = n.Norm();
|
||||||
n/=da*da;
|
n/=da*da;
|
||||||
|
|
||||||
A.SetColumn(0,P1-P0);
|
#ifndef VCG_USE_EIGEN
|
||||||
A.SetColumn(1,P2-P0);
|
A.SetColumn(0, P1-P0);
|
||||||
A.SetColumn(2,n);
|
A.SetColumn(1, P2-P0);
|
||||||
|
A.SetColumn(2, n);
|
||||||
|
#else
|
||||||
|
A.col(0) = P1-P0;
|
||||||
|
A.col(1) = P2-P0;
|
||||||
|
A.col(2) = n;
|
||||||
|
#endif
|
||||||
CoordType delta = P0 - bary;
|
CoordType delta = P0 - bary;
|
||||||
|
|
||||||
/* DC is calculated as integral of (A*x+delta) * (A*x+delta)^T over the triangle,
|
/* DC is calculated as integral of (A*x+delta) * (A*x+delta)^T over the triangle,
|
||||||
|
|
|
@ -118,7 +118,7 @@ struct MidPoint : public std::unary_function<face::Pos<typename MESH_TYPE::Fac
|
||||||
nv.P()= (ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
|
nv.P()= (ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
|
||||||
|
|
||||||
if( MESH_TYPE::HasPerVertexNormal())
|
if( MESH_TYPE::HasPerVertexNormal())
|
||||||
nv.N()= (ep.f->V(ep.z)->N()+ep.f->V1(ep.z)->N()).Normalize();
|
nv.N()= (ep.f->V(ep.z)->N()+ep.f->V1(ep.z)->N()).normalized();
|
||||||
|
|
||||||
if( MESH_TYPE::HasPerVertexColor())
|
if( MESH_TYPE::HasPerVertexColor())
|
||||||
nv.C().lerp(ep.f->V(ep.z)->C(),ep.f->V1(ep.z)->C(),.5f);
|
nv.C().lerp(ep.f->V(ep.z)->C(),ep.f->V1(ep.z)->C(),.5f);
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -73,12 +73,12 @@ the vertex
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace tri {
|
namespace tri {
|
||||||
|
|
||||||
/// \ingroup trimesh
|
/// \ingroup trimesh
|
||||||
|
|
||||||
/// \headerfile curvature.h vcg/complex/trimesh/update/curvature.h
|
/// \headerfile curvature.h vcg/complex/trimesh/update/curvature.h
|
||||||
|
|
||||||
/// \brief Management, updating and computation of per-vertex and per-face normals.
|
/// \brief Management, updating and computation of per-vertex and per-face normals.
|
||||||
/**
|
/**
|
||||||
This class is used to compute or update the normals that can be stored in the vertex or face component of a mesh.
|
This class is used to compute or update the normals that can be stored in the vertex or face component of a mesh.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -98,18 +98,18 @@ public:
|
||||||
typedef typename MeshType::CoordType CoordType;
|
typedef typename MeshType::CoordType CoordType;
|
||||||
typedef typename CoordType::ScalarType ScalarType;
|
typedef typename CoordType::ScalarType ScalarType;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef struct AdjVertex {
|
typedef struct AdjVertex {
|
||||||
VertexType * vert;
|
VertexType * vert;
|
||||||
float doubleArea;
|
float doubleArea;
|
||||||
bool isBorder;
|
bool isBorder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \brief Compute principal direction and magniuto of curvature.
|
/// \brief Compute principal direction and magniuto of curvature.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Compute principal direction and magniuto of curvature as describe in the paper:
|
Compute principal direction and magniuto of curvature as describe in the paper:
|
||||||
@InProceedings{bb33922,
|
@InProceedings{bb33922,
|
||||||
|
@ -144,10 +144,10 @@ public:
|
||||||
VertexType* tempV;
|
VertexType* tempV;
|
||||||
float totalDoubleAreaSize = 0.0f;
|
float totalDoubleAreaSize = 0.0f;
|
||||||
|
|
||||||
// compute the area of each triangle around the central vertex as well as their total area
|
// compute the area of each triangle around the central vertex as well as their total area
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// this bring the pos to the next triangle counterclock-wise
|
// this bring the pos to the next triangle counterclock-wise
|
||||||
pos.FlipF();
|
pos.FlipF();
|
||||||
pos.FlipE();
|
pos.FlipE();
|
||||||
|
|
||||||
|
@ -157,13 +157,13 @@ public:
|
||||||
AdjVertex v;
|
AdjVertex v;
|
||||||
|
|
||||||
v.isBorder = pos.IsBorder();
|
v.isBorder = pos.IsBorder();
|
||||||
v.vert = tempV;
|
v.vert = tempV;
|
||||||
v.doubleArea = vcg::DoubleArea(*pos.F());
|
v.doubleArea = vcg::DoubleArea(*pos.F());
|
||||||
totalDoubleAreaSize += v.doubleArea;
|
totalDoubleAreaSize += v.doubleArea;
|
||||||
|
|
||||||
vertices.push_back(v);
|
vertices.push_back(v);
|
||||||
}
|
}
|
||||||
while(tempV != firstV);
|
while(tempV != firstV);
|
||||||
|
|
||||||
// compute the weights for the formula computing matrix M
|
// compute the weights for the formula computing matrix M
|
||||||
for (int i = 0; i < vertices.size(); ++i) {
|
for (int i = 0; i < vertices.size(); ++i) {
|
||||||
|
@ -190,8 +190,8 @@ public:
|
||||||
M.SetZero();
|
M.SetZero();
|
||||||
for (int i = 0; i < vertices.size(); ++i) {
|
for (int i = 0; i < vertices.size(); ++i) {
|
||||||
CoordType edge = (central_vertex->cP() - vertices[i].vert->cP());
|
CoordType edge = (central_vertex->cP() - vertices[i].vert->cP());
|
||||||
float curvature = (2.0f * (central_vertex->cN() * edge) ) / edge.SquaredNorm();
|
float curvature = (2.0f * (central_vertex->cN().dot(edge)) ) / edge.SquaredNorm();
|
||||||
CoordType T = (Tp*edge).Normalize();
|
CoordType T = (Tp*edge).normalized();
|
||||||
tempMatrix.ExternalProduct(T,T);
|
tempMatrix.ExternalProduct(T,T);
|
||||||
M += tempMatrix * weights[i] * curvature ;
|
M += tempMatrix * weights[i] * curvature ;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ public:
|
||||||
CoordType e1(1.0f,0.0f,0.0f);
|
CoordType e1(1.0f,0.0f,0.0f);
|
||||||
if ((e1 - central_vertex->cN()).SquaredNorm() > (e1 + central_vertex->cN()).SquaredNorm())
|
if ((e1 - central_vertex->cN()).SquaredNorm() > (e1 + central_vertex->cN()).SquaredNorm())
|
||||||
W = e1 - central_vertex->cN();
|
W = e1 - central_vertex->cN();
|
||||||
else
|
else
|
||||||
W = e1 + central_vertex->cN();
|
W = e1 + central_vertex->cN();
|
||||||
W.Normalize();
|
W.Normalize();
|
||||||
|
|
||||||
|
@ -282,7 +282,7 @@ public:
|
||||||
float Principal_Curvature2 = (3.0f * StMS[1][1]) - StMS[0][0];
|
float Principal_Curvature2 = (3.0f * StMS[1][1]) - StMS[0][0];
|
||||||
|
|
||||||
CoordType Principal_Direction1 = T1 * c - T2 * s;
|
CoordType Principal_Direction1 = T1 * c - T2 * s;
|
||||||
CoordType Principal_Direction2 = T1 * s + T2 * c;
|
CoordType Principal_Direction2 = T1 * s + T2 * c;
|
||||||
|
|
||||||
(*vi).PD1() = Principal_Direction1;
|
(*vi).PD1() = Principal_Direction1;
|
||||||
(*vi).PD2() = Principal_Direction2;
|
(*vi).PD2() = Principal_Direction2;
|
||||||
|
@ -291,8 +291,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AreaData
|
class AreaData
|
||||||
|
@ -301,7 +301,7 @@ public:
|
||||||
float A;
|
float A;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Curvature meseaure as described in the paper:
|
/** Curvature meseaure as described in the paper:
|
||||||
Robust principal curvatures on Multiple Scales, Yong-Liang Yang, Yu-Kun Lai, Shi-Min Hu Helmut Pottmann
|
Robust principal curvatures on Multiple Scales, Yong-Liang Yang, Yu-Kun Lai, Shi-Min Hu Helmut Pottmann
|
||||||
SGP 2004
|
SGP 2004
|
||||||
If pointVSfaceInt==true the covariance is computed by montecarlo sampling on the mesh (faster)
|
If pointVSfaceInt==true the covariance is computed by montecarlo sampling on the mesh (faster)
|
||||||
|
@ -325,11 +325,11 @@ public:
|
||||||
PointsGridType pGrid;
|
PointsGridType pGrid;
|
||||||
|
|
||||||
// Fill the grid used
|
// Fill the grid used
|
||||||
if(pointVSfaceInt){
|
if(pointVSfaceInt){
|
||||||
area = Stat<MeshType>::ComputeMeshArea(m);
|
area = Stat<MeshType>::ComputeMeshArea(m);
|
||||||
vcg::tri::SurfaceSampling<MeshType,vcg::tri::TrivialSampler<MeshType> >::Montecarlo(m,vs,1000 * area / (2*M_PI*r*r ));
|
vcg::tri::SurfaceSampling<MeshType,vcg::tri::TrivialSampler<MeshType> >::Montecarlo(m,vs,1000 * area / (2*M_PI*r*r ));
|
||||||
vi = vcg::tri::Allocator<MeshType>::AddVertices(tmpM,m.vert.size());
|
vi = vcg::tri::Allocator<MeshType>::AddVertices(tmpM,m.vert.size());
|
||||||
for(int y = 0; y < m.vert.size(); ++y,++vi) (*vi).P() = m.vert[y].P();
|
for(int y = 0; y < m.vert.size(); ++y,++vi) (*vi).P() = m.vert[y].P();
|
||||||
pGrid.Set(tmpM.vert.begin(),tmpM.vert.end());
|
pGrid.Set(tmpM.vert.begin(),tmpM.vert.end());
|
||||||
} else{ mGrid.Set(m.face.begin(),m.face.end()); }
|
} else{ mGrid.Set(m.face.begin(),m.face.end()); }
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ public:
|
||||||
|
|
||||||
// sample the neighborhood
|
// sample the neighborhood
|
||||||
if(pointVSfaceInt)
|
if(pointVSfaceInt)
|
||||||
{
|
{
|
||||||
vcg::tri::GetInSphereVertex<
|
vcg::tri::GetInSphereVertex<
|
||||||
MeshType,
|
MeshType,
|
||||||
PointsGridType,std::vector<VertexType*>,
|
PointsGridType,std::vector<VertexType*>,
|
||||||
|
@ -356,25 +356,25 @@ public:
|
||||||
vcg::tri::Inertia<MeshType>::Covariance(tmpM,_bary,A);
|
vcg::tri::Inertia<MeshType>::Covariance(tmpM,_bary,A);
|
||||||
}
|
}
|
||||||
|
|
||||||
Jacobi(A, eigenvalues , eigenvectors, nrot);
|
Jacobi(A, eigenvalues , eigenvectors, nrot);
|
||||||
|
|
||||||
// get the estimate of curvatures from eigenvalues and eigenvectors
|
// get the estimate of curvatures from eigenvalues and eigenvectors
|
||||||
// find the 2 most tangent eigenvectors (by finding the one closest to the normal)
|
// find the 2 most tangent eigenvectors (by finding the one closest to the normal)
|
||||||
int best = 0; ScalarType bestv = fabs( (*vi).cN() * eigenvectors.GetColumn(0).Normalize());
|
int best = 0; ScalarType bestv = fabs( (*vi).cN().dot(eigenvectors.GetColumn(0).normalized()) );
|
||||||
for(int i = 1 ; i < 3; ++i){
|
for(int i = 1 ; i < 3; ++i){
|
||||||
ScalarType prod = fabs((*vi).cN() * eigenvectors.GetColumn(i).Normalize());
|
ScalarType prod = fabs((*vi).cN().dot(eigenvectors.GetColumn(i).normalized()));
|
||||||
if( prod > bestv){bestv = prod; best = i;}
|
if( prod > bestv){bestv = prod; best = i;}
|
||||||
}
|
}
|
||||||
|
|
||||||
(*vi).PD1() = eigenvectors.GetColumn( (best+1)%3).Normalize();
|
(*vi).PD1() = eigenvectors.GetColumn( (best+1)%3).normalized();
|
||||||
(*vi).PD2() = eigenvectors.GetColumn( (best+2)%3).Normalize();
|
(*vi).PD2() = eigenvectors.GetColumn( (best+2)%3).normalized();
|
||||||
|
|
||||||
// project them to the plane identified by the normal
|
// project them to the plane identified by the normal
|
||||||
vcg::Matrix33<ScalarType> rot;
|
vcg::Matrix33<ScalarType> rot;
|
||||||
ScalarType angle = acos((*vi).PD1()*(*vi).N());
|
ScalarType angle = acos((*vi).PD1().dot((*vi).N()));
|
||||||
rot.SetRotateRad( - (M_PI*0.5 - angle),(*vi).PD1()^(*vi).N());
|
rot.SetRotateRad( - (M_PI*0.5 - angle),(*vi).PD1()^(*vi).N());
|
||||||
(*vi).PD1() = rot*(*vi).PD1();
|
(*vi).PD1() = rot*(*vi).PD1();
|
||||||
angle = acos((*vi).PD2()*(*vi).N());
|
angle = acos((*vi).PD2().dot((*vi).N()));
|
||||||
rot.SetRotateRad( - (M_PI*0.5 - angle),(*vi).PD2()^(*vi).N());
|
rot.SetRotateRad( - (M_PI*0.5 - angle),(*vi).PD2()^(*vi).N());
|
||||||
(*vi).PD2() = rot*(*vi).PD2();
|
(*vi).PD2() = rot*(*vi).PD2();
|
||||||
|
|
||||||
|
@ -388,26 +388,26 @@ public:
|
||||||
std::swap((*vi).PD1(),(*vi).PD2());
|
std::swap((*vi).PD1(),(*vi).PD2());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// \brief Computes the discrete gaussian curvature.
|
/// \brief Computes the discrete gaussian curvature.
|
||||||
|
|
||||||
/** For further details, please, refer to: \n
|
/** For further details, please, refer to: \n
|
||||||
|
|
||||||
- <em> Discrete Differential-Geometry Operators for Triangulated 2-Manifolds Mark Meyer,
|
- <em> Discrete Differential-Geometry Operators for Triangulated 2-Manifolds Mark Meyer,
|
||||||
Mathieu Desbrun, Peter Schroder, Alan H. Barr VisMath '02, Berlin </em>
|
Mathieu Desbrun, Peter Schroder, Alan H. Barr VisMath '02, Berlin </em>
|
||||||
*/
|
*/
|
||||||
static void MeanAndGaussian(MeshType & m)
|
static void MeanAndGaussian(MeshType & m)
|
||||||
{
|
{
|
||||||
assert(HasFFAdjacency(m));
|
assert(HasFFAdjacency(m));
|
||||||
float area0, area1, area2, angle0, angle1, angle2, e01, e12, e20;
|
float area0, area1, area2, angle0, angle1, angle2, e01, e12, e20;
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
VertexIterator vi;
|
VertexIterator vi;
|
||||||
typename MeshType::CoordType e01v ,e12v ,e20v;
|
typename MeshType::CoordType e01v ,e12v ,e20v;
|
||||||
|
|
||||||
SimpleTempData<VertContainer, AreaData> TDAreaPtr(m.vert);
|
SimpleTempData<VertContainer, AreaData> TDAreaPtr(m.vert);
|
||||||
SimpleTempData<VertContainer, typename MeshType::CoordType> TDContr(m.vert);
|
SimpleTempData<VertContainer, typename MeshType::CoordType> TDContr(m.vert);
|
||||||
|
|
||||||
vcg::tri::UpdateNormals<MeshType>::PerVertexNormalized(m);
|
vcg::tri::UpdateNormals<MeshType>::PerVertexNormalized(m);
|
||||||
//Compute AreaMix in H (vale anche per K)
|
//Compute AreaMix in H (vale anche per K)
|
||||||
|
@ -425,49 +425,49 @@ public:
|
||||||
angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) ));
|
angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) ));
|
||||||
angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) ));
|
angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) ));
|
||||||
angle2 = M_PI-(angle0+angle1);
|
angle2 = M_PI-(angle0+angle1);
|
||||||
|
|
||||||
if((angle0 < M_PI/2) && (angle1 < M_PI/2) && (angle2 < M_PI/2)) // triangolo non ottuso
|
if((angle0 < M_PI/2) && (angle1 < M_PI/2) && (angle2 < M_PI/2)) // triangolo non ottuso
|
||||||
{
|
{
|
||||||
float e01 = SquaredDistance( (*fi).V(1)->cP() , (*fi).V(0)->cP() );
|
float e01 = SquaredDistance( (*fi).V(1)->cP() , (*fi).V(0)->cP() );
|
||||||
float e12 = SquaredDistance( (*fi).V(2)->cP() , (*fi).V(1)->cP() );
|
float e12 = SquaredDistance( (*fi).V(2)->cP() , (*fi).V(1)->cP() );
|
||||||
float e20 = SquaredDistance( (*fi).V(0)->cP() , (*fi).V(2)->cP() );
|
float e20 = SquaredDistance( (*fi).V(0)->cP() , (*fi).V(2)->cP() );
|
||||||
|
|
||||||
area0 = ( e20*(1.0/tan(angle1)) + e01*(1.0/tan(angle2)) ) / 8.0;
|
area0 = ( e20*(1.0/tan(angle1)) + e01*(1.0/tan(angle2)) ) / 8.0;
|
||||||
area1 = ( e01*(1.0/tan(angle2)) + e12*(1.0/tan(angle0)) ) / 8.0;
|
area1 = ( e01*(1.0/tan(angle2)) + e12*(1.0/tan(angle0)) ) / 8.0;
|
||||||
area2 = ( e12*(1.0/tan(angle0)) + e20*(1.0/tan(angle1)) ) / 8.0;
|
area2 = ( e12*(1.0/tan(angle0)) + e20*(1.0/tan(angle1)) ) / 8.0;
|
||||||
|
|
||||||
(TDAreaPtr)[(*fi).V(0)].A += area0;
|
(TDAreaPtr)[(*fi).V(0)].A += area0;
|
||||||
(TDAreaPtr)[(*fi).V(1)].A += area1;
|
(TDAreaPtr)[(*fi).V(1)].A += area1;
|
||||||
(TDAreaPtr)[(*fi).V(2)].A += area2;
|
(TDAreaPtr)[(*fi).V(2)].A += area2;
|
||||||
|
|
||||||
}
|
}
|
||||||
else // obtuse
|
else // obtuse
|
||||||
{
|
{
|
||||||
(TDAreaPtr)[(*fi).V(0)].A += vcg::DoubleArea<typename MeshType::FaceType>((*fi)) / 6.0;
|
(TDAreaPtr)[(*fi).V(0)].A += vcg::DoubleArea<typename MeshType::FaceType>((*fi)) / 6.0;
|
||||||
(TDAreaPtr)[(*fi).V(1)].A += vcg::DoubleArea<typename MeshType::FaceType>((*fi)) / 6.0;
|
(TDAreaPtr)[(*fi).V(1)].A += vcg::DoubleArea<typename MeshType::FaceType>((*fi)) / 6.0;
|
||||||
(TDAreaPtr)[(*fi).V(2)].A += vcg::DoubleArea<typename MeshType::FaceType>((*fi)) / 6.0;
|
(TDAreaPtr)[(*fi).V(2)].A += vcg::DoubleArea<typename MeshType::FaceType>((*fi)) / 6.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() )
|
||||||
{
|
{
|
||||||
angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) ));
|
angle0 = math::Abs(Angle( (*fi).P(1)-(*fi).P(0),(*fi).P(2)-(*fi).P(0) ));
|
||||||
angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) ));
|
angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) ));
|
||||||
angle2 = M_PI-(angle0+angle1);
|
angle2 = M_PI-(angle0+angle1);
|
||||||
|
|
||||||
e01v = ( (*fi).V(1)->cP() - (*fi).V(0)->cP() ) ;
|
e01v = ( (*fi).V(1)->cP() - (*fi).V(0)->cP() ) ;
|
||||||
e12v = ( (*fi).V(2)->cP() - (*fi).V(1)->cP() ) ;
|
e12v = ( (*fi).V(2)->cP() - (*fi).V(1)->cP() ) ;
|
||||||
e20v = ( (*fi).V(0)->cP() - (*fi).V(2)->cP() ) ;
|
e20v = ( (*fi).V(0)->cP() - (*fi).V(2)->cP() ) ;
|
||||||
|
|
||||||
TDContr[(*fi).V(0)] += ( e20v * (1.0/tan(angle1)) - e01v * (1.0/tan(angle2)) ) / 4.0;
|
TDContr[(*fi).V(0)] += ( e20v * (1.0/tan(angle1)) - e01v * (1.0/tan(angle2)) ) / 4.0;
|
||||||
TDContr[(*fi).V(1)] += ( e01v * (1.0/tan(angle2)) - e12v * (1.0/tan(angle0)) ) / 4.0;
|
TDContr[(*fi).V(1)] += ( e01v * (1.0/tan(angle2)) - e12v * (1.0/tan(angle0)) ) / 4.0;
|
||||||
TDContr[(*fi).V(2)] += ( e12v * (1.0/tan(angle0)) - e20v * (1.0/tan(angle1)) ) / 4.0;
|
TDContr[(*fi).V(2)] += ( e12v * (1.0/tan(angle0)) - e20v * (1.0/tan(angle1)) ) / 4.0;
|
||||||
|
|
||||||
(*fi).V(0)->Kg() -= angle0;
|
(*fi).V(0)->Kg() -= angle0;
|
||||||
(*fi).V(1)->Kg() -= angle1;
|
(*fi).V(1)->Kg() -= angle1;
|
||||||
(*fi).V(2)->Kg() -= angle2;
|
(*fi).V(2)->Kg() -= angle2;
|
||||||
|
|
||||||
|
|
||||||
for(int i=0;i<3;i++)
|
for(int i=0;i<3;i++)
|
||||||
{
|
{
|
||||||
if(vcg::face::IsBorder((*fi), i))
|
if(vcg::face::IsBorder((*fi), i))
|
||||||
|
@ -475,7 +475,7 @@ public:
|
||||||
CoordType e1,e2;
|
CoordType e1,e2;
|
||||||
vcg::face::Pos<FaceType> hp(&*fi, i, (*fi).V(i));
|
vcg::face::Pos<FaceType> hp(&*fi, i, (*fi).V(i));
|
||||||
vcg::face::Pos<FaceType> hp1=hp;
|
vcg::face::Pos<FaceType> hp1=hp;
|
||||||
|
|
||||||
hp1.FlipV();
|
hp1.FlipV();
|
||||||
e1=hp1.v->cP() - hp.v->cP();
|
e1=hp1.v->cP() - hp.v->cP();
|
||||||
hp1.FlipV();
|
hp1.FlipV();
|
||||||
|
@ -485,7 +485,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD() /*&& !(*vi).IsB()*/)
|
for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD() /*&& !(*vi).IsB()*/)
|
||||||
{
|
{
|
||||||
if((TDAreaPtr)[*vi].A<=std::numeric_limits<ScalarType>::epsilon())
|
if((TDAreaPtr)[*vi].A<=std::numeric_limits<ScalarType>::epsilon())
|
||||||
|
@ -495,30 +495,30 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*vi).Kh() = (((TDContr)[*vi]* (*vi).cN()>0)?1.0:-1.0)*((TDContr)[*vi] / (TDAreaPtr) [*vi].A).Norm();
|
(*vi).Kh() = (((TDContr)[*vi].dot((*vi).cN())>0)?1.0:-1.0)*((TDContr)[*vi] / (TDAreaPtr) [*vi].A).Norm();
|
||||||
(*vi).Kg() /= (TDAreaPtr)[*vi].A;
|
(*vi).Kg() /= (TDAreaPtr)[*vi].A;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// \brief Update the mean and the gaussian curvature of a vertex.
|
/// \brief Update the mean and the gaussian curvature of a vertex.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The function uses the VF adiacency to walk around the vertex.
|
The function uses the VF adiacency to walk around the vertex.
|
||||||
\return It will return the voronoi area around the vertex. If (norm == true) the mean and the gaussian curvature are normalized.
|
\return It will return the voronoi area around the vertex. If (norm == true) the mean and the gaussian curvature are normalized.
|
||||||
Based on the paper <a href="http://www2.in.tu-clausthal.de/~hormann/papers/Dyn.2001.OTU.pdf"> <em> "Optimizing 3d triangulations using discrete curvature analysis" </em> </a>
|
Based on the paper <a href="http://www2.in.tu-clausthal.de/~hormann/papers/Dyn.2001.OTU.pdf"> <em> "Optimizing 3d triangulations using discrete curvature analysis" </em> </a>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static float VertexCurvature(VertexPointer v, bool norm = true)
|
static float VertexCurvature(VertexPointer v, bool norm = true)
|
||||||
{
|
{
|
||||||
// VFAdjacency required!
|
// VFAdjacency required!
|
||||||
assert(FaceType::HasVFAdjacency());
|
assert(FaceType::HasVFAdjacency());
|
||||||
assert(VertexType::HasVFAdjacency());
|
assert(VertexType::HasVFAdjacency());
|
||||||
|
|
||||||
VFIteratorType vfi(v);
|
VFIteratorType vfi(v);
|
||||||
float A = 0;
|
float A = 0;
|
||||||
|
|
||||||
v->Kh() = 0;
|
v->Kh() = 0;
|
||||||
v->Kg() = 2 * M_PI;
|
v->Kg() = 2 * M_PI;
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ public:
|
||||||
FacePointer f = vfi.F();
|
FacePointer f = vfi.F();
|
||||||
int i = vfi.I();
|
int i = vfi.I();
|
||||||
VertexPointer v0 = f->V0(i), v1 = f->V1(i), v2 = f->V2(i);
|
VertexPointer v0 = f->V0(i), v1 = f->V1(i), v2 = f->V2(i);
|
||||||
|
|
||||||
float ang0 = math::Abs(Angle(v1->P() - v0->P(), v2->P() - v0->P() ));
|
float ang0 = math::Abs(Angle(v1->P() - v0->P(), v2->P() - v0->P() ));
|
||||||
float ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() ));
|
float ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() ));
|
||||||
float ang2 = M_PI - ang0 - ang1;
|
float ang2 = M_PI - ang0 - ang1;
|
||||||
|
@ -544,22 +544,22 @@ public:
|
||||||
A += (s02 * tan(ang0)) / 8.0;
|
A += (s02 * tan(ang0)) / 8.0;
|
||||||
else // non obctuse triangle
|
else // non obctuse triangle
|
||||||
A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0;
|
A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0;
|
||||||
|
|
||||||
// gaussian curvature update
|
// gaussian curvature update
|
||||||
v->Kg() -= ang0;
|
v->Kg() -= ang0;
|
||||||
|
|
||||||
// mean curvature update
|
// mean curvature update
|
||||||
ang1 = math::Abs(Angle(f->N(), v1->N()));
|
ang1 = math::Abs(Angle(f->N(), v1->N()));
|
||||||
ang2 = math::Abs(Angle(f->N(), v2->N()));
|
ang2 = math::Abs(Angle(f->N(), v2->N()));
|
||||||
v->Kh() += ( (math::Sqrt(s01) / 2.0) * ang1 +
|
v->Kh() += ( (math::Sqrt(s01) / 2.0) * ang1 +
|
||||||
(math::Sqrt(s02) / 2.0) * ang2 );
|
(math::Sqrt(s02) / 2.0) * ang2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
++vfi;
|
++vfi;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->Kh() /= 4.0f;
|
v->Kh() /= 4.0f;
|
||||||
|
|
||||||
if(norm) {
|
if(norm) {
|
||||||
if(A <= std::numeric_limits<float>::epsilon()) {
|
if(A <= std::numeric_limits<float>::epsilon()) {
|
||||||
v->Kh() = 0;
|
v->Kh() = 0;
|
||||||
|
@ -597,7 +597,7 @@ public:
|
||||||
assert(FaceType::HasFFAdjacency());
|
assert(FaceType::HasFFAdjacency());
|
||||||
assert(FaceType::HasFaceNormal());
|
assert(FaceType::HasFaceNormal());
|
||||||
|
|
||||||
|
|
||||||
typename MeshType::VertexIterator vi;
|
typename MeshType::VertexIterator vi;
|
||||||
|
|
||||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||||
|
@ -616,7 +616,7 @@ public:
|
||||||
normalized_edge/=edge_length;
|
normalized_edge/=edge_length;
|
||||||
Point3<ScalarType> n1 = p.F()->cN();n1.Normalize();
|
Point3<ScalarType> n1 = p.F()->cN();n1.Normalize();
|
||||||
Point3<ScalarType> n2 = p.FFlip()->cN();n2.Normalize();
|
Point3<ScalarType> n2 = p.FFlip()->cN();n2.Normalize();
|
||||||
ScalarType n1n2 = (n1 ^ n2)* normalized_edge;
|
ScalarType n1n2 = (n1 ^ n2).dot(normalized_edge);
|
||||||
n1n2 = math::Max<ScalarType >(math::Min<ScalarType> ( 1.0,n1n2),-1.0);
|
n1n2 = math::Max<ScalarType >(math::Min<ScalarType> ( 1.0,n1n2),-1.0);
|
||||||
ScalarType beta = math::Asin(n1n2);
|
ScalarType beta = math::Asin(n1n2);
|
||||||
m33[0][0] += beta*edge_length*normalized_edge[0]*normalized_edge[0];
|
m33[0][0] += beta*edge_length*normalized_edge[0]*normalized_edge[0];
|
||||||
|
@ -645,7 +645,11 @@ public:
|
||||||
ScalarType normal = std::numeric_limits<ScalarType>::min();
|
ScalarType normal = std::numeric_limits<ScalarType>::min();
|
||||||
int normI = 0;
|
int normI = 0;
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
if( fabs((*vi).N().Normalize() * vect.GetRow(i)) > normal ){normal= fabs((*vi).N().Normalize() * vect.GetRow(i)); normI = i;}
|
if( fabs((*vi).N().Normalize().dot(vect.GetRow(i))) > normal )
|
||||||
|
{
|
||||||
|
normal= fabs((*vi).N().Normalize().dot(vect.GetRow(i)));
|
||||||
|
normI = i;
|
||||||
|
}
|
||||||
int maxI = (normI+2)%3;
|
int maxI = (normI+2)%3;
|
||||||
int minI = (normI+1)%3;
|
int minI = (normI+1)%3;
|
||||||
if(fabs(lambda[maxI]) < fabs(lambda[minI])) std::swap(maxI,minI);
|
if(fabs(lambda[maxI]) < fabs(lambda[minI])) std::swap(maxI,minI);
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -109,16 +109,16 @@ namespace vcg {
|
||||||
|
|
||||||
namespace math {
|
namespace math {
|
||||||
|
|
||||||
template <class SCALAR>
|
template <class SCALAR>
|
||||||
class MagnitudoComparer
|
class MagnitudoComparer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline bool operator() ( const SCALAR a, const SCALAR b ) { return fabs(a)>fabs(b); }
|
inline bool operator() ( const SCALAR a, const SCALAR b ) { return fabs(a)>fabs(b); }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline float Sqrt(const short v) { return sqrtf(v); }
|
inline float Sqrt(const short v) { return sqrtf(v); }
|
||||||
inline float Sqrt(const int v) { return sqrtf((float)v); }
|
inline float Sqrt(const int v) { return sqrtf((float)v); }
|
||||||
|
|
||||||
inline float Sqrt(const float v) { return sqrtf(v); }
|
inline float Sqrt(const float v) { return sqrtf(v); }
|
||||||
inline float Abs(const float v) { return fabsf(v); }
|
inline float Abs(const float v) { return fabsf(v); }
|
||||||
inline float Cos(const float v) { return cosf(v); }
|
inline float Cos(const float v) { return cosf(v); }
|
||||||
|
@ -134,7 +134,9 @@ namespace math {
|
||||||
inline double Acos(const double v) { return acos(v); }
|
inline double Acos(const double v) { return acos(v); }
|
||||||
inline double Asin(const double v) { return asin(v); }
|
inline double Asin(const double v) { return asin(v); }
|
||||||
inline double Atan2(const double v0,const double v1) { return atan2(v0,v1); }
|
inline double Atan2(const double v0,const double v1) { return atan2(v0,v1); }
|
||||||
|
|
||||||
|
template <typename T> inline static T Sqr(T a) { return a*a; }
|
||||||
|
|
||||||
template<class T> inline const T & Min(const T &a, const T &b){
|
template<class T> inline const T & Min(const T &a, const T &b){
|
||||||
if (a<b) return a; else return b;
|
if (a<b) return a; else return b;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +153,7 @@ namespace math {
|
||||||
template<class T> inline void Sort(T &a, T &b, T &c){
|
template<class T> inline void Sort(T &a, T &b, T &c){
|
||||||
if (a>b) Swap(a,b);
|
if (a>b) Swap(a,b);
|
||||||
if (b>c) {Swap(b,c); if (a>b) Swap(a,b);}
|
if (b>c) {Swap(b,c); if (a>b) Swap(a,b);}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some <math.h> files do not define M_PI... */
|
/* Some <math.h> files do not define M_PI... */
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
|
@ -161,8 +163,8 @@ namespace math {
|
||||||
#ifndef SQRT_TWO
|
#ifndef SQRT_TWO
|
||||||
#define SQRT_TWO 1.4142135623730950488
|
#define SQRT_TWO 1.4142135623730950488
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class SCALAR>
|
template <class SCALAR>
|
||||||
inline SCALAR Clamp( const SCALAR & val, const SCALAR& minval, const SCALAR& maxval)
|
inline SCALAR Clamp( const SCALAR & val, const SCALAR& minval, const SCALAR& maxval)
|
||||||
{
|
{
|
||||||
if(val < minval) return minval;
|
if(val < minval) return minval;
|
||||||
|
@ -191,7 +193,7 @@ template<class T> int IsNAN(T t)
|
||||||
return t != t;
|
return t != t;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
} // End math namespace
|
} // End math namespace
|
||||||
|
|
||||||
/// a type that stands for "void". Useful for Parameter type of a point.
|
/// a type that stands for "void". Useful for Parameter type of a point.
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#ifndef EIGEN_VCGLIB
|
#ifndef EIGEN_VCGLIB
|
||||||
#define EIGEN_VCGLIB
|
#define EIGEN_VCGLIB
|
||||||
|
|
||||||
|
// TODO enable the vectorization
|
||||||
|
#define EIGEN_DONT_VECTORIZE
|
||||||
#define EIGEN_MATRIXBASE_PLUGIN <vcg/math/eigen_vcgaddons.h>
|
#define EIGEN_MATRIXBASE_PLUGIN <vcg/math/eigen_vcgaddons.h>
|
||||||
|
|
||||||
#include "../Eigen/LU"
|
#include "../Eigen/LU"
|
||||||
|
|
|
@ -197,23 +197,6 @@ EIGEN_DEPRECATED Derived& operator-=(const Scalar k)
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
/*!
|
|
||||||
* \deprecated use (*this) * vec.asDiagonal() or (*this) * mat.mark<Diagonal>()
|
|
||||||
* Matrix multiplication by a diagonal matrix
|
|
||||||
*/
|
|
||||||
// EIGEN_DEPRECATED Matrix<Scalar> operator*(const MatrixDiagBase &m) const
|
|
||||||
// {
|
|
||||||
// assert(_columns == _rows);
|
|
||||||
// assert(_columns == m.Dimension());
|
|
||||||
// int i,j;
|
|
||||||
// Matrix<Scalar> result(_rows, _columns);
|
|
||||||
//
|
|
||||||
// for (i=0; i<result._rows; i++)
|
|
||||||
// for (j=0; j<result._columns; j++)
|
|
||||||
// result[i][j]*= m[j];
|
|
||||||
//
|
|
||||||
// return result;
|
|
||||||
// };
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \deprecated use *this = a * b.transpose()
|
* \deprecated use *this = a * b.transpose()
|
||||||
|
@ -268,22 +251,36 @@ EIGEN_DEPRECATED void SetIdentity()
|
||||||
* \param j the column index
|
* \param j the column index
|
||||||
* \param v ...
|
* \param v ...
|
||||||
*/
|
*/
|
||||||
EIGEN_DEPRECATED void SetColumn(const unsigned int j, Scalar* v)
|
EIGEN_DEPRECATED void SetColumn(unsigned int j, Scalar* v)
|
||||||
{
|
{
|
||||||
col(j) = Map<Matrix<Scalar,RowsAtCompileTime,1> >(v,cols(),1);
|
col(j) = Map<Matrix<Scalar,RowsAtCompileTime,1> >(v,cols(),1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \deprecated use *this.col(i) = other */
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEPRECATED void SetColumn(unsigned int j, const MatrixBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
col(j) = other;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \deprecated use *this.row(i) = expression
|
* \deprecated use *this.row(i) = expression
|
||||||
* Set the elements of the <I>i</I>-th row to v[j]
|
* Set the elements of the <I>i</I>-th row to v[j]
|
||||||
* \param i the row index
|
* \param i the row index
|
||||||
* \param v ...
|
* \param v ...
|
||||||
*/
|
*/
|
||||||
EIGEN_DEPRECATED void SetRow(const unsigned int i, Scalar* v)
|
EIGEN_DEPRECATED void SetRow(unsigned int i, Scalar* v)
|
||||||
{
|
{
|
||||||
row(i) = Map<Matrix<Scalar,1,ColsAtCompileTime> >(v,1,rows());
|
row(i) = Map<Matrix<Scalar,1,ColsAtCompileTime> >(v,1,rows());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \deprecated use *this.row(i) = other */
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEPRECATED void SetRow(unsigned int j, const MatrixBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
row(j) = other;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \deprecated use *this.diagonal() = expression
|
* \deprecated use *this.diagonal() = expression
|
||||||
* Set the diagonal elements <I>v<SUB>i,i</SUB></I> to v[i]
|
* Set the diagonal elements <I>v<SUB>i,i</SUB></I> to v[i]
|
||||||
|
@ -333,5 +330,5 @@ EIGEN_DEPRECATED inline Scalar SquaredNorm() const { return norm2(); }
|
||||||
EIGEN_DEPRECATED inline Derived& Normalize() { normalize(); return derived(); }
|
EIGEN_DEPRECATED inline Derived& Normalize() { normalize(); return derived(); }
|
||||||
|
|
||||||
/** \deprecated use .cross(p) */
|
/** \deprecated use .cross(p) */
|
||||||
inline EvalType operator ^ (const Derived& p ) const { return this->cross(p); }
|
EIGEN_DEPRECATED inline EvalType operator ^ (const Derived& p ) const { return this->cross(p); }
|
||||||
|
|
||||||
|
|
|
@ -66,109 +66,109 @@ namespace vcg
|
||||||
typename MATRIX_TYPE::ScalarType g=A[i][j];
|
typename MATRIX_TYPE::ScalarType g=A[i][j];
|
||||||
typename MATRIX_TYPE::ScalarType h=A[k][l];
|
typename MATRIX_TYPE::ScalarType h=A[k][l];
|
||||||
A[i][j]=g-s*(h+g*tau);
|
A[i][j]=g-s*(h+g*tau);
|
||||||
A[k][l]=h+s*(g-h*tau);
|
A[k][l]=h+s*(g-h*tau);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Computes all eigenvalues and eigenvectors of a real symmetric matrix .
|
* Computes all eigenvalues and eigenvectors of a real symmetric matrix .
|
||||||
* On output, elements of the input matrix above the diagonal are destroyed.
|
* On output, elements of the input matrix above the diagonal are destroyed.
|
||||||
* \param d returns the eigenvalues of a.
|
* \param d returns the eigenvalues of a.
|
||||||
* \param v is a matrix whose columns contain, the normalized eigenvectors
|
* \param v is a matrix whose columns contain, the normalized eigenvectors
|
||||||
* \param nrot returns the number of Jacobi rotations that were required.
|
* \param nrot returns the number of Jacobi rotations that were required.
|
||||||
*/
|
*/
|
||||||
template <typename MATRIX_TYPE, typename POINT_TYPE>
|
template <typename MATRIX_TYPE, typename POINT_TYPE>
|
||||||
static void Jacobi(MATRIX_TYPE &w, POINT_TYPE &d, MATRIX_TYPE &v, int &nrot)
|
static void Jacobi(MATRIX_TYPE &w, POINT_TYPE &d, MATRIX_TYPE &v, int &nrot)
|
||||||
{
|
{
|
||||||
typedef typename MATRIX_TYPE::ScalarType ScalarType;
|
typedef typename MATRIX_TYPE::ScalarType ScalarType;
|
||||||
assert(w.RowsNumber()==w.ColumnsNumber());
|
assert(w.RowsNumber()==w.ColumnsNumber());
|
||||||
int dimension = w.RowsNumber();
|
int dimension = w.RowsNumber();
|
||||||
|
|
||||||
int j,iq,ip,i;
|
int j,iq,ip,i;
|
||||||
//assert(w.IsSymmetric());
|
//assert(w.IsSymmetric());
|
||||||
typename MATRIX_TYPE::ScalarType tresh, theta, tau, t, sm, s, h, g, c;
|
typename MATRIX_TYPE::ScalarType tresh, theta, tau, t, sm, s, h, g, c;
|
||||||
POINT_TYPE b, z;
|
POINT_TYPE b, z;
|
||||||
|
|
||||||
v.SetIdentity();
|
v.SetIdentity();
|
||||||
|
|
||||||
for (ip=0;ip<dimension;++ip) //Initialize b and d to the diagonal of a.
|
for (ip=0;ip<dimension;++ip) //Initialize b and d to the diagonal of a.
|
||||||
{
|
{
|
||||||
b[ip]=d[ip]=w[ip][ip];
|
b[ip]=d[ip]=w[ip][ip];
|
||||||
z[ip]=ScalarType(0.0); //This vector will accumulate terms of the form tapq as in equation (11.1.14).
|
z[ip]=ScalarType(0.0); //This vector will accumulate terms of the form tapq as in equation (11.1.14).
|
||||||
}
|
}
|
||||||
nrot=0;
|
nrot=0;
|
||||||
for (i=0;i<50;i++)
|
for (i=0;i<50;i++)
|
||||||
{
|
{
|
||||||
sm=ScalarType(0.0);
|
sm=ScalarType(0.0);
|
||||||
for (ip=0;ip<dimension-1;++ip) // Sum off diagonal elements
|
for (ip=0;ip<dimension-1;++ip) // Sum off diagonal elements
|
||||||
{
|
{
|
||||||
for (iq=ip+1;iq<dimension;++iq)
|
for (iq=ip+1;iq<dimension;++iq)
|
||||||
sm += fabs(w[ip][iq]);
|
sm += fabs(w[ip][iq]);
|
||||||
}
|
}
|
||||||
if (sm == ScalarType(0.0)) //The normal return, which relies on quadratic convergence to machine underflow.
|
if (sm == ScalarType(0.0)) //The normal return, which relies on quadratic convergence to machine underflow.
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (i < 4)
|
if (i < 4)
|
||||||
tresh=ScalarType(0.2)*sm/(dimension*dimension); //...on the first three sweeps.
|
tresh=ScalarType(0.2)*sm/(dimension*dimension); //...on the first three sweeps.
|
||||||
else
|
else
|
||||||
tresh=ScalarType(0.0); //...thereafter.
|
tresh=ScalarType(0.0); //...thereafter.
|
||||||
for (ip=0;ip<dimension-1;++ip)
|
for (ip=0;ip<dimension-1;++ip)
|
||||||
{
|
{
|
||||||
for (iq=ip+1;iq<dimension;iq++)
|
for (iq=ip+1;iq<dimension;iq++)
|
||||||
{
|
{
|
||||||
g=ScalarType(100.0)*fabs(w[ip][iq]);
|
g=ScalarType(100.0)*fabs(w[ip][iq]);
|
||||||
//After four sweeps, skip the rotation if the off-diagonal element is small.
|
//After four sweeps, skip the rotation if the off-diagonal element is small.
|
||||||
if(i>4 && (float)(fabs(d[ip])+g) == (float)fabs(d[ip]) && (float)(fabs(d[iq])+g) == (float)fabs(d[iq]))
|
if(i>4 && (float)(fabs(d[ip])+g) == (float)fabs(d[ip]) && (float)(fabs(d[iq])+g) == (float)fabs(d[iq]))
|
||||||
w[ip][iq]=ScalarType(0.0);
|
w[ip][iq]=ScalarType(0.0);
|
||||||
else if (fabs(w[ip][iq]) > tresh)
|
else if (fabs(w[ip][iq]) > tresh)
|
||||||
{
|
{
|
||||||
h=d[iq]-d[ip];
|
h=d[iq]-d[ip];
|
||||||
if ((float)(fabs(h)+g) == (float)fabs(h))
|
if ((float)(fabs(h)+g) == (float)fabs(h))
|
||||||
t=(w[ip][iq])/h; //t =1/(2#)
|
t=(w[ip][iq])/h; //t =1/(2#)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
theta=ScalarType(0.5)*h/(w[ip][iq]); //Equation (11.1.10).
|
theta=ScalarType(0.5)*h/(w[ip][iq]); //Equation (11.1.10).
|
||||||
t=ScalarType(1.0)/(fabs(theta)+sqrt(ScalarType(1.0)+theta*theta));
|
t=ScalarType(1.0)/(fabs(theta)+sqrt(ScalarType(1.0)+theta*theta));
|
||||||
if (theta < ScalarType(0.0)) t = -t;
|
if (theta < ScalarType(0.0)) t = -t;
|
||||||
}
|
}
|
||||||
c=ScalarType(1.0)/sqrt(ScalarType(1.0)+t*t);
|
c=ScalarType(1.0)/sqrt(ScalarType(1.0)+t*t);
|
||||||
s=t*c;
|
s=t*c;
|
||||||
tau=s/(ScalarType(1.0)+c);
|
tau=s/(ScalarType(1.0)+c);
|
||||||
h=t*w[ip][iq];
|
h=t*w[ip][iq];
|
||||||
z[ip] -= h;
|
z[ip] -= h;
|
||||||
z[iq] += h;
|
z[iq] += h;
|
||||||
d[ip] -= h;
|
d[ip] -= h;
|
||||||
d[iq] += h;
|
d[iq] += h;
|
||||||
w[ip][iq]=ScalarType(0.0);
|
w[ip][iq]=ScalarType(0.0);
|
||||||
for (j=0;j<=ip-1;j++) { //Case of rotations 1 <= j < p.
|
for (j=0;j<=ip-1;j++) { //Case of rotations 1 <= j < p.
|
||||||
JacobiRotate<MATRIX_TYPE>(w,s,tau,j,ip,j,iq) ;
|
JacobiRotate<MATRIX_TYPE>(w,s,tau,j,ip,j,iq) ;
|
||||||
}
|
}
|
||||||
for (j=ip+1;j<=iq-1;j++) { //Case of rotations p < j < q.
|
for (j=ip+1;j<=iq-1;j++) { //Case of rotations p < j < q.
|
||||||
JacobiRotate<MATRIX_TYPE>(w,s,tau,ip,j,j,iq);
|
JacobiRotate<MATRIX_TYPE>(w,s,tau,ip,j,j,iq);
|
||||||
}
|
}
|
||||||
for (j=iq+1;j<dimension;j++) { //Case of rotations q< j <= n.
|
for (j=iq+1;j<dimension;j++) { //Case of rotations q< j <= n.
|
||||||
JacobiRotate<MATRIX_TYPE>(w,s,tau,ip,j,iq,j);
|
JacobiRotate<MATRIX_TYPE>(w,s,tau,ip,j,iq,j);
|
||||||
}
|
}
|
||||||
for (j=0;j<dimension;j++) {
|
for (j=0;j<dimension;j++) {
|
||||||
JacobiRotate<MATRIX_TYPE>(v,s,tau,j,ip,j,iq);
|
JacobiRotate<MATRIX_TYPE>(v,s,tau,j,ip,j,iq);
|
||||||
}
|
}
|
||||||
++nrot;
|
++nrot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ip=0;ip<dimension;ip++)
|
for (ip=0;ip<dimension;ip++)
|
||||||
{
|
{
|
||||||
b[ip] += z[ip];
|
b[ip] += z[ip];
|
||||||
d[ip]=b[ip]; //Update d with the sum of ta_pq ,
|
d[ip]=b[ip]; //Update d with the sum of ta_pq ,
|
||||||
z[ip]=0.0; //and reinitialize z.
|
z[ip]=0.0; //and reinitialize z.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Given the eigenvectors and the eigenvalues as output from JacobiRotate, sorts the eigenvalues
|
* Given the eigenvectors and the eigenvalues as output from JacobiRotate, sorts the eigenvalues
|
||||||
* into descending order, and rearranges the columns of v correspondinlgy.
|
* into descending order, and rearranges the columns of v correspondinlgy.
|
||||||
* \param eigenvalues
|
* \param eigenvalues
|
||||||
* \param eigenvector (in columns)
|
* \param eigenvector (in columns)
|
||||||
* \param absComparison sort according to the absolute values of the eigenvalues.
|
* \param absComparison sort according to the absolute values of the eigenvalues.
|
||||||
|
@ -180,7 +180,7 @@ namespace vcg
|
||||||
int dimension = eigenvectors.ColumnsNumber();
|
int dimension = eigenvectors.ColumnsNumber();
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
float p,q;
|
float p,q;
|
||||||
for (i=0; i<dimension-1; i++)
|
for (i=0; i<dimension-1; i++)
|
||||||
{
|
{
|
||||||
if (absComparison)
|
if (absComparison)
|
||||||
{
|
{
|
||||||
|
@ -197,16 +197,16 @@ namespace vcg
|
||||||
{
|
{
|
||||||
p = eigenvalues[ k=i ];
|
p = eigenvalues[ k=i ];
|
||||||
for (j=i+1; j<dimension; j++)
|
for (j=i+1; j<dimension; j++)
|
||||||
if (eigenvalues[j] >= p)
|
if (eigenvalues[j] >= p)
|
||||||
p = eigenvalues[ k=j ];
|
p = eigenvalues[ k=j ];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k != i)
|
if (k != i)
|
||||||
{
|
{
|
||||||
eigenvalues[k] = eigenvalues[i]; // i.e.
|
eigenvalues[k] = eigenvalues[i]; // i.e.
|
||||||
eigenvalues[i] = p; // swaps the value of the elements i-th and k-th
|
eigenvalues[i] = p; // swaps the value of the elements i-th and k-th
|
||||||
|
|
||||||
for (j=0; j<dimension; j++)
|
for (j=0; j<dimension; j++)
|
||||||
{
|
{
|
||||||
p = eigenvectors[j][i]; // i.e.
|
p = eigenvectors[j][i]; // i.e.
|
||||||
eigenvectors[j][i] = eigenvectors[j][k]; // swaps the eigenvectors stored in the
|
eigenvectors[j][i] = eigenvectors[j][k]; // swaps the eigenvectors stored in the
|
||||||
|
@ -216,16 +216,16 @@ namespace vcg
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Computes (a^2 + b^2)^(1/2) without destructive underflow or overflow.
|
// Computes (a^2 + b^2)^(1/2) without destructive underflow or overflow.
|
||||||
template <typename TYPE>
|
template <typename TYPE>
|
||||||
inline static TYPE pythagora(TYPE a, TYPE b)
|
inline static TYPE pythagora(TYPE a, TYPE b)
|
||||||
{
|
{
|
||||||
TYPE abs_a = fabs(a);
|
TYPE abs_a = fabs(a);
|
||||||
TYPE abs_b = fabs(b);
|
TYPE abs_b = fabs(b);
|
||||||
if (abs_a > abs_b)
|
if (abs_a > abs_b)
|
||||||
return abs_a*sqrt((TYPE)1.0+sqr(abs_b/abs_a));
|
return abs_a*sqrt((TYPE)1.0+sqr(abs_b/abs_a));
|
||||||
else
|
else
|
||||||
return (abs_b == (TYPE)0.0 ? (TYPE)0.0 : abs_b*sqrt((TYPE)1.0+sqr(abs_a/abs_b)));
|
return (abs_b == (TYPE)0.0 ? (TYPE)0.0 : abs_b*sqrt((TYPE)1.0+sqr(abs_a/abs_b)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -243,12 +243,12 @@ namespace vcg
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
enum SortingStrategy {LeaveUnsorted=0, SortAscending=1, SortDescending=2};
|
enum SortingStrategy {LeaveUnsorted=0, SortAscending=1, SortDescending=2};
|
||||||
template< typename MATRIX_TYPE >
|
template< typename MATRIX_TYPE >
|
||||||
void Sort(MATRIX_TYPE &U, typename MATRIX_TYPE::ScalarType W[], MATRIX_TYPE &V, const SortingStrategy sorting) ;
|
void Sort(MATRIX_TYPE &U, typename MATRIX_TYPE::ScalarType W[], MATRIX_TYPE &V, const SortingStrategy sorting) ;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Given a matrix <I>A<SUB>mxn</SUB></I>, this routine computes its singular value decomposition,
|
* Given a matrix <I>A<SUB>mxn</SUB></I>, this routine computes its singular value decomposition,
|
||||||
|
@ -258,7 +258,7 @@ namespace vcg
|
||||||
* \param W the diagonal matrix of singular values <I>W</I>, stored as a vector <I>W[1...N]</I>
|
* \param W the diagonal matrix of singular values <I>W</I>, stored as a vector <I>W[1...N]</I>
|
||||||
* \param V the matrix <I>V</I> (not the transpose <I>V<SUP>T</SUP></I>)
|
* \param V the matrix <I>V</I> (not the transpose <I>V<SUP>T</SUP></I>)
|
||||||
* \param max_iters max iteration number (default = 30).
|
* \param max_iters max iteration number (default = 30).
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
template <typename MATRIX_TYPE>
|
template <typename MATRIX_TYPE>
|
||||||
static bool SingularValueDecomposition(MATRIX_TYPE &A, typename MATRIX_TYPE::ScalarType *W, MATRIX_TYPE &V, const SortingStrategy sorting=LeaveUnsorted, const int max_iters=30)
|
static bool SingularValueDecomposition(MATRIX_TYPE &A, typename MATRIX_TYPE::ScalarType *W, MATRIX_TYPE &V, const SortingStrategy sorting=LeaveUnsorted, const int max_iters=30)
|
||||||
|
@ -271,20 +271,20 @@ namespace vcg
|
||||||
bool convergence = true;
|
bool convergence = true;
|
||||||
|
|
||||||
rv1 = new ScalarType[n];
|
rv1 = new ScalarType[n];
|
||||||
g = scale = anorm = 0;
|
g = scale = anorm = 0;
|
||||||
// Householder reduction to bidiagonal form.
|
// Householder reduction to bidiagonal form.
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
l = i+1;
|
l = i+1;
|
||||||
rv1[i] = scale*g;
|
rv1[i] = scale*g;
|
||||||
g = s = scale = 0.0;
|
g = s = scale = 0.0;
|
||||||
if (i < m)
|
if (i < m)
|
||||||
{
|
{
|
||||||
for (k = i; k<m; k++)
|
for (k = i; k<m; k++)
|
||||||
scale += fabs(A[k][i]);
|
scale += fabs(A[k][i]);
|
||||||
if (scale)
|
if (scale)
|
||||||
{
|
{
|
||||||
for (k=i; k<m; k++)
|
for (k=i; k<m; k++)
|
||||||
{
|
{
|
||||||
A[k][i] /= scale;
|
A[k][i] /= scale;
|
||||||
s += A[k][i]*A[k][i];
|
s += A[k][i]*A[k][i];
|
||||||
|
@ -293,27 +293,27 @@ namespace vcg
|
||||||
g = -sign<ScalarType>( sqrt(s), f );
|
g = -sign<ScalarType>( sqrt(s), f );
|
||||||
h = f*g - s;
|
h = f*g - s;
|
||||||
A[i][i]=f-g;
|
A[i][i]=f-g;
|
||||||
for (j=l; j<n; j++)
|
for (j=l; j<n; j++)
|
||||||
{
|
{
|
||||||
for (s=0.0, k=i; k<m; k++)
|
for (s=0.0, k=i; k<m; k++)
|
||||||
s += A[k][i]*A[k][j];
|
s += A[k][i]*A[k][j];
|
||||||
f = s/h;
|
f = s/h;
|
||||||
for (k=i; k<m; k++)
|
for (k=i; k<m; k++)
|
||||||
A[k][j] += f*A[k][i];
|
A[k][j] += f*A[k][i];
|
||||||
}
|
}
|
||||||
for (k=i; k<m; k++)
|
for (k=i; k<m; k++)
|
||||||
A[k][i] *= scale;
|
A[k][i] *= scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
W[i] = scale *g;
|
W[i] = scale *g;
|
||||||
g = s = scale = 0.0;
|
g = s = scale = 0.0;
|
||||||
if (i < m && i != (n-1))
|
if (i < m && i != (n-1))
|
||||||
{
|
{
|
||||||
for (k=l; k<n; k++)
|
for (k=l; k<n; k++)
|
||||||
scale += fabs(A[i][k]);
|
scale += fabs(A[i][k]);
|
||||||
if (scale)
|
if (scale)
|
||||||
{
|
{
|
||||||
for (k=l; k<n; k++)
|
for (k=l; k<n; k++)
|
||||||
{
|
{
|
||||||
A[i][k] /= scale;
|
A[i][k] /= scale;
|
||||||
s += A[i][k]*A[i][k];
|
s += A[i][k]*A[i][k];
|
||||||
|
@ -322,40 +322,40 @@ namespace vcg
|
||||||
g = -sign<ScalarType>(sqrt(s),f);
|
g = -sign<ScalarType>(sqrt(s),f);
|
||||||
h = f*g - s;
|
h = f*g - s;
|
||||||
A[i][l] = f-g;
|
A[i][l] = f-g;
|
||||||
for (k=l; k<n; k++)
|
for (k=l; k<n; k++)
|
||||||
rv1[k] = A[i][k]/h;
|
rv1[k] = A[i][k]/h;
|
||||||
for (j=l; j<m; j++)
|
for (j=l; j<m; j++)
|
||||||
{
|
{
|
||||||
for (s=0.0, k=l; k<n; k++)
|
for (s=0.0, k=l; k<n; k++)
|
||||||
s += A[j][k]*A[i][k];
|
s += A[j][k]*A[i][k];
|
||||||
for (k=l; k<n; k++)
|
for (k=l; k<n; k++)
|
||||||
A[j][k] += s*rv1[k];
|
A[j][k] += s*rv1[k];
|
||||||
}
|
}
|
||||||
for (k=l; k<n; k++)
|
for (k=l; k<n; k++)
|
||||||
A[i][k] *= scale;
|
A[i][k] *= scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
anorm=math::Max( anorm, (fabs(W[i])+fabs(rv1[i])) );
|
anorm=math::Max( anorm, (fabs(W[i])+fabs(rv1[i])) );
|
||||||
}
|
}
|
||||||
// Accumulation of right-hand transformations.
|
// Accumulation of right-hand transformations.
|
||||||
for (i=(n-1); i>=0; i--)
|
for (i=(n-1); i>=0; i--)
|
||||||
{
|
{
|
||||||
//Accumulation of right-hand transformations.
|
//Accumulation of right-hand transformations.
|
||||||
if (i < (n-1))
|
if (i < (n-1))
|
||||||
{
|
{
|
||||||
if (g)
|
if (g)
|
||||||
{
|
{
|
||||||
for (j=l; j<n;j++) //Double division to avoid possible underflow.
|
for (j=l; j<n;j++) //Double division to avoid possible underflow.
|
||||||
V[j][i]=(A[i][j]/A[i][l])/g;
|
V[j][i]=(A[i][j]/A[i][l])/g;
|
||||||
for (j=l; j<n; j++)
|
for (j=l; j<n; j++)
|
||||||
{
|
{
|
||||||
for (s=0.0, k=l; k<n; k++)
|
for (s=0.0, k=l; k<n; k++)
|
||||||
s += A[i][k] * V[k][j];
|
s += A[i][k] * V[k][j];
|
||||||
for (k=l; k<n; k++)
|
for (k=l; k<n; k++)
|
||||||
V[k][j] += s*V[k][i];
|
V[k][j] += s*V[k][i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (j=l; j<n; j++)
|
for (j=l; j<n; j++)
|
||||||
V[i][j] = V[j][i] = 0.0;
|
V[i][j] = V[j][i] = 0.0;
|
||||||
}
|
}
|
||||||
V[i][i] = 1.0;
|
V[i][i] = 1.0;
|
||||||
|
@ -363,60 +363,60 @@ namespace vcg
|
||||||
l = i;
|
l = i;
|
||||||
}
|
}
|
||||||
// Accumulation of left-hand transformations.
|
// Accumulation of left-hand transformations.
|
||||||
for (i=math::Min(m,n)-1; i>=0; i--)
|
for (i=math::Min(m,n)-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
l = i+1;
|
l = i+1;
|
||||||
g = W[i];
|
g = W[i];
|
||||||
for (j=l; j<n; j++)
|
for (j=l; j<n; j++)
|
||||||
A[i][j]=0.0;
|
A[i][j]=0.0;
|
||||||
if (g)
|
if (g)
|
||||||
{
|
{
|
||||||
g = (ScalarType)1.0/g;
|
g = (ScalarType)1.0/g;
|
||||||
for (j=l; j<n; j++)
|
for (j=l; j<n; j++)
|
||||||
{
|
{
|
||||||
for (s=0.0, k=l; k<m; k++)
|
for (s=0.0, k=l; k<m; k++)
|
||||||
s += A[k][i]*A[k][j];
|
s += A[k][i]*A[k][j];
|
||||||
f = (s/A[i][i])*g;
|
f = (s/A[i][i])*g;
|
||||||
for (k=i; k<m; k++)
|
for (k=i; k<m; k++)
|
||||||
A[k][j] += f*A[k][i];
|
A[k][j] += f*A[k][i];
|
||||||
}
|
}
|
||||||
for (j=i; j<m; j++)
|
for (j=i; j<m; j++)
|
||||||
A[j][i] *= g;
|
A[j][i] *= g;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (j=i; j<m; j++)
|
for (j=i; j<m; j++)
|
||||||
A[j][i] = 0.0;
|
A[j][i] = 0.0;
|
||||||
++A[i][i];
|
++A[i][i];
|
||||||
}
|
}
|
||||||
// Diagonalization of the bidiagonal form: Loop over
|
// Diagonalization of the bidiagonal form: Loop over
|
||||||
// singular values, and over allowed iterations.
|
// singular values, and over allowed iterations.
|
||||||
for (k=(n-1); k>=0; k--)
|
for (k=(n-1); k>=0; k--)
|
||||||
{
|
{
|
||||||
for (its=1; its<=max_iters; its++)
|
for (its=1; its<=max_iters; its++)
|
||||||
{
|
{
|
||||||
flag=1;
|
flag=1;
|
||||||
for (l=k; l>=0; l--)
|
for (l=k; l>=0; l--)
|
||||||
{
|
{
|
||||||
// Test for splitting.
|
// Test for splitting.
|
||||||
nm=l-1;
|
nm=l-1;
|
||||||
// Note that rv1[1] is always zero.
|
// Note that rv1[1] is always zero.
|
||||||
if ((double)(fabs(rv1[l])+anorm) == anorm)
|
if ((double)(fabs(rv1[l])+anorm) == anorm)
|
||||||
{
|
{
|
||||||
flag=0;
|
flag=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((double)(fabs(W[nm])+anorm) == anorm)
|
if ((double)(fabs(W[nm])+anorm) == anorm)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
c=0.0; //Cancellation of rv1[l], if l > 1.
|
c=0.0; //Cancellation of rv1[l], if l > 1.
|
||||||
s=1.0;
|
s=1.0;
|
||||||
for (i=l ;i<=k; i++)
|
for (i=l ;i<=k; i++)
|
||||||
{
|
{
|
||||||
f = s*rv1[i];
|
f = s*rv1[i];
|
||||||
rv1[i] = c*rv1[i];
|
rv1[i] = c*rv1[i];
|
||||||
if ((double)(fabs(f)+anorm) == anorm)
|
if ((double)(fabs(f)+anorm) == anorm)
|
||||||
break;
|
break;
|
||||||
g = W[i];
|
g = W[i];
|
||||||
h = pythagora<ScalarType>(f,g);
|
h = pythagora<ScalarType>(f,g);
|
||||||
|
@ -424,7 +424,7 @@ namespace vcg
|
||||||
h = (ScalarType)1.0/h;
|
h = (ScalarType)1.0/h;
|
||||||
c = g*h;
|
c = g*h;
|
||||||
s = -f*h;
|
s = -f*h;
|
||||||
for (j=0; j<m; j++)
|
for (j=0; j<m; j++)
|
||||||
{
|
{
|
||||||
y = A[j][nm];
|
y = A[j][nm];
|
||||||
z = A[j][i];
|
z = A[j][i];
|
||||||
|
@ -435,10 +435,10 @@ namespace vcg
|
||||||
}
|
}
|
||||||
z = W[k];
|
z = W[k];
|
||||||
if (l == k) //Convergence.
|
if (l == k) //Convergence.
|
||||||
{
|
{
|
||||||
if (z < 0.0) { // Singular value is made nonnegative.
|
if (z < 0.0) { // Singular value is made nonnegative.
|
||||||
W[k] = -z;
|
W[k] = -z;
|
||||||
for (j=0; j<n; j++)
|
for (j=0; j<n; j++)
|
||||||
V[j][k] = -V[j][k];
|
V[j][k] = -V[j][k];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -455,9 +455,9 @@ namespace vcg
|
||||||
f = ((y-z)*(y+z) + (g-h)*(g+h))/((ScalarType)2.0*h*y);
|
f = ((y-z)*(y+z) + (g-h)*(g+h))/((ScalarType)2.0*h*y);
|
||||||
g = pythagora<ScalarType>(f,1.0);
|
g = pythagora<ScalarType>(f,1.0);
|
||||||
f=((x-z)*(x+z) + h*((y/(f+sign(g,f)))-h))/x;
|
f=((x-z)*(x+z) + h*((y/(f+sign(g,f)))-h))/x;
|
||||||
c=s=1.0;
|
c=s=1.0;
|
||||||
//Next QR transformation:
|
//Next QR transformation:
|
||||||
for (j=l; j<= nm;j++)
|
for (j=l; j<= nm;j++)
|
||||||
{
|
{
|
||||||
i = j+1;
|
i = j+1;
|
||||||
g = rv1[i];
|
g = rv1[i];
|
||||||
|
@ -472,7 +472,7 @@ namespace vcg
|
||||||
g = g*c - x*s;
|
g = g*c - x*s;
|
||||||
h = y*s;
|
h = y*s;
|
||||||
y *= c;
|
y *= c;
|
||||||
for (jj=0; jj<n; jj++)
|
for (jj=0; jj<n; jj++)
|
||||||
{
|
{
|
||||||
x = V[jj][j];
|
x = V[jj][j];
|
||||||
z = V[jj][i];
|
z = V[jj][i];
|
||||||
|
@ -482,7 +482,7 @@ namespace vcg
|
||||||
z = pythagora<ScalarType>(f,h);
|
z = pythagora<ScalarType>(f,h);
|
||||||
W[j] = z;
|
W[j] = z;
|
||||||
// Rotation can be arbitrary if z = 0.
|
// Rotation can be arbitrary if z = 0.
|
||||||
if (z)
|
if (z)
|
||||||
{
|
{
|
||||||
z = (ScalarType)1.0/z;
|
z = (ScalarType)1.0/z;
|
||||||
c = f*z;
|
c = f*z;
|
||||||
|
@ -490,7 +490,7 @@ namespace vcg
|
||||||
}
|
}
|
||||||
f = c*g + s*y;
|
f = c*g + s*y;
|
||||||
x = c*y - s*g;
|
x = c*y - s*g;
|
||||||
for (jj=0; jj<m; jj++)
|
for (jj=0; jj<m; jj++)
|
||||||
{
|
{
|
||||||
y = A[jj][j];
|
y = A[jj][j];
|
||||||
z = A[jj][i];
|
z = A[jj][i];
|
||||||
|
@ -518,46 +518,46 @@ namespace vcg
|
||||||
*/
|
*/
|
||||||
// TODO modify the last parameter type
|
// TODO modify the last parameter type
|
||||||
template< typename MATRIX_TYPE >
|
template< typename MATRIX_TYPE >
|
||||||
void Sort(MATRIX_TYPE &U, typename MATRIX_TYPE::ScalarType W[], MATRIX_TYPE &V, const SortingStrategy sorting)
|
void Sort(MATRIX_TYPE &U, typename MATRIX_TYPE::ScalarType W[], MATRIX_TYPE &V, const SortingStrategy sorting)
|
||||||
{
|
{
|
||||||
typedef typename MATRIX_TYPE::ScalarType ScalarType;
|
typedef typename MATRIX_TYPE::ScalarType ScalarType;
|
||||||
|
|
||||||
assert(U.ColumnsNumber()==V.ColumnsNumber());
|
assert(U.ColumnsNumber()==V.ColumnsNumber());
|
||||||
|
|
||||||
int mu = U.RowsNumber();
|
int mu = U.RowsNumber();
|
||||||
int mv = V.RowsNumber();
|
int mv = V.RowsNumber();
|
||||||
int n = U.ColumnsNumber();
|
int n = U.ColumnsNumber();
|
||||||
|
|
||||||
//ScalarType* u = &U[0][0];
|
//ScalarType* u = &U[0][0];
|
||||||
//ScalarType* v = &V[0][0];
|
//ScalarType* v = &V[0][0];
|
||||||
|
|
||||||
for (int i=0; i<n; i++)
|
for (int i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
int k = i;
|
int k = i;
|
||||||
ScalarType p = W[i];
|
ScalarType p = W[i];
|
||||||
switch (sorting)
|
switch (sorting)
|
||||||
{
|
{
|
||||||
case SortAscending:
|
case SortAscending:
|
||||||
{
|
{
|
||||||
for (int j=i+1; j<n; j++)
|
for (int j=i+1; j<n; j++)
|
||||||
{
|
{
|
||||||
if (W[j] < p)
|
if (W[j] < p)
|
||||||
{
|
{
|
||||||
k = j;
|
k = j;
|
||||||
p = W[j];
|
p = W[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SortDescending:
|
case SortDescending:
|
||||||
{
|
{
|
||||||
for (int j=i+1; j<n; j++)
|
for (int j=i+1; j<n; j++)
|
||||||
{
|
{
|
||||||
if (W[j] > p)
|
if (W[j] > p)
|
||||||
{
|
{
|
||||||
k = j;
|
k = j;
|
||||||
p = W[j];
|
p = W[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -572,24 +572,24 @@ namespace vcg
|
||||||
//ScalarType* ujk = u + k; // ujk = &U[0][k]
|
//ScalarType* ujk = u + k; // ujk = &U[0][k]
|
||||||
//ScalarType* vji = v + i; // vji = &V[0][i]
|
//ScalarType* vji = v + i; // vji = &V[0][i]
|
||||||
//ScalarType* vjk = v + k; // vjk = &V[0][k]
|
//ScalarType* vjk = v + k; // vjk = &V[0][k]
|
||||||
//if (j)
|
//if (j)
|
||||||
//{
|
//{
|
||||||
// for(;;) for( ; j!=0; --j, uji+=n, ujk+=n)
|
// for(;;) for( ; j!=0; --j, uji+=n, ujk+=n)
|
||||||
// { {
|
// { {
|
||||||
// p = *uji; p = *uji; // i.e.
|
// p = *uji; p = *uji; // i.e.
|
||||||
// *uji = *ujk; *uji = *ujk; // swap( U[s][i], U[s][k] )
|
// *uji = *ujk; *uji = *ujk; // swap( U[s][i], U[s][k] )
|
||||||
// *ujk = p; *ujk = p; //
|
// *ujk = p; *ujk = p; //
|
||||||
// if (!(--j)) }
|
// if (!(--j)) }
|
||||||
// break;
|
// break;
|
||||||
// uji += n;
|
// uji += n;
|
||||||
// ujk += n;
|
// ujk += n;
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
for(int s=0; j!=0; ++s, --j)
|
for(int s=0; j!=0; ++s, --j)
|
||||||
std::swap(U[s][i], U[s][k]);
|
std::swap(U[s][i], U[s][k]);
|
||||||
|
|
||||||
j = mv;
|
j = mv;
|
||||||
//if (j!=0)
|
//if (j!=0)
|
||||||
//{
|
//{
|
||||||
// for(;;) for ( ; j!=0; --j, vji+=n, ujk+=n)
|
// for(;;) for ( ; j!=0; --j, vji+=n, ujk+=n)
|
||||||
// { {
|
// { {
|
||||||
|
@ -598,7 +598,7 @@ namespace vcg
|
||||||
// *vjk = p; *vjk = p; //
|
// *vjk = p; *vjk = p; //
|
||||||
// if (!(--j)) }
|
// if (!(--j)) }
|
||||||
// break;
|
// break;
|
||||||
// vji += n;
|
// vji += n;
|
||||||
// vjk += n;
|
// vjk += n;
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
@ -610,7 +610,7 @@ namespace vcg
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Solves AxX = B for a vector X, where A is specified by the matrices <I>U<SUB>mxn</SUB></I>,
|
* Solves AxX = B for a vector X, where A is specified by the matrices <I>U<SUB>mxn</SUB></I>,
|
||||||
* <I>W<SUB>nx1</SUB></I> and <I>V<SUB>nxn</SUB></I> as returned by <CODE>SingularValueDecomposition</CODE>.
|
* <I>W<SUB>nx1</SUB></I> and <I>V<SUB>nxn</SUB></I> as returned by <CODE>SingularValueDecomposition</CODE>.
|
||||||
* No input quantities are destroyed, so the routine may be called sequentially with different bxs.
|
* No input quantities are destroyed, so the routine may be called sequentially with different bxs.
|
||||||
* \param x is the output solution vector (<I>x<SUB>nx1</SUB></I>)
|
* \param x is the output solution vector (<I>x<SUB>nx1</SUB></I>)
|
||||||
|
@ -630,20 +630,20 @@ namespace vcg
|
||||||
ScalarType s;
|
ScalarType s;
|
||||||
ScalarType *tmp = new ScalarType[columns_number];
|
ScalarType *tmp = new ScalarType[columns_number];
|
||||||
for (j=0; j<columns_number; j++) //Calculate U^T * B.
|
for (j=0; j<columns_number; j++) //Calculate U^T * B.
|
||||||
{
|
{
|
||||||
s = 0;
|
s = 0;
|
||||||
if (W[j]!=0) //Nonzero result only if wj is nonzero.
|
if (W[j]!=0) //Nonzero result only if wj is nonzero.
|
||||||
{
|
{
|
||||||
for (i=0; i<rows_number; i++)
|
for (i=0; i<rows_number; i++)
|
||||||
s += U[i][j]*b[i];
|
s += U[i][j]*b[i];
|
||||||
s /= W[j]; //This is the divide by wj .
|
s /= W[j]; //This is the divide by wj .
|
||||||
}
|
}
|
||||||
tmp[j]=s;
|
tmp[j]=s;
|
||||||
}
|
}
|
||||||
for (j=0;j<columns_number;j++) //Matrix multiply by V to get answer.
|
for (j=0;j<columns_number;j++) //Matrix multiply by V to get answer.
|
||||||
{
|
{
|
||||||
s = 0;
|
s = 0;
|
||||||
for (jj=0; jj<columns_number; jj++)
|
for (jj=0; jj<columns_number; jj++)
|
||||||
s += V[j][jj]*tmp[jj];
|
s += V[j][jj]*tmp[jj];
|
||||||
x[j]=s;
|
x[j]=s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -41,7 +41,7 @@ namespace vcg {
|
||||||
/**
|
/**
|
||||||
This class represents the common interface for any linear objects.
|
This class represents the common interface for any linear objects.
|
||||||
It consists (the declaration of) a set of functions and types that
|
It consists (the declaration of) a set of functions and types that
|
||||||
each such object mush have.
|
each such object mush have.
|
||||||
Linear have the Zero element (neutral element for sums)
|
Linear have the Zero element (neutral element for sums)
|
||||||
moltiplication (for a scalar), and two linear elements of
|
moltiplication (for a scalar), and two linear elements of
|
||||||
a given type can be summed.
|
a given type can be summed.
|
||||||
|
@ -56,7 +56,7 @@ namespace vcg {
|
||||||
class Linear{
|
class Linear{
|
||||||
public:
|
public:
|
||||||
typedef T ScalarType;
|
typedef T ScalarType;
|
||||||
inline void Zero();
|
inline void SetZero();
|
||||||
T operator + ( T const & p) const;
|
T operator + ( T const & p) const;
|
||||||
T operator - ( T const & p) const;
|
T operator - ( T const & p) const;
|
||||||
T operator * ( const ScalarType );
|
T operator * ( const ScalarType );
|
||||||
|
|
|
@ -49,21 +49,6 @@ namespace ndim{
|
||||||
/** \addtogroup math */
|
/** \addtogroup math */
|
||||||
/* @{ */
|
/* @{ */
|
||||||
|
|
||||||
/*!
|
|
||||||
* This class represent a diagonal <I>m</I><EFBFBD><I>m</I> matrix.
|
|
||||||
*/
|
|
||||||
class MatrixDiagBase{public:
|
|
||||||
virtual const int & Dimension()const =0;
|
|
||||||
virtual const float operator[](const int & i) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int N, class S>
|
|
||||||
class MatrixDiag: public Point<N,S>, public MatrixDiagBase{
|
|
||||||
public:
|
|
||||||
const int & Dimension() const {return N;}
|
|
||||||
MatrixDiag(const Point<N,S>&p):Point<N,S>(p){}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This class represent a generic <I>m</I><EFBFBD><I>n</I> matrix. The class is templated over the scalar type field.
|
* This class represent a generic <I>m</I><EFBFBD><I>n</I> matrix. The class is templated over the scalar type field.
|
||||||
* @param Scalar (Templete Parameter) Specifies the ScalarType field.
|
* @param Scalar (Templete Parameter) Specifies the ScalarType field.
|
||||||
|
@ -72,7 +57,7 @@ template<class _Scalar>
|
||||||
class Matrix : public Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> // FIXME col or row major ?
|
class Matrix : public Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> // FIXME col or row major ?
|
||||||
{
|
{
|
||||||
typedef Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> _Base;
|
typedef Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> _Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
_EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix,_Base);
|
_EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix,_Base);
|
||||||
|
|
|
@ -243,7 +243,7 @@ Matrix33<S> RotationMatrix(vcg::Point3<S> v0,vcg::Point3<S> v1,bool normalized=t
|
||||||
v0.Normalize();
|
v0.Normalize();
|
||||||
v1.Normalize();
|
v1.Normalize();
|
||||||
}
|
}
|
||||||
S dot=(v0*v1);
|
S dot=v0.dot(v1);
|
||||||
///control if there is no rotation
|
///control if there is no rotation
|
||||||
if (dot>((S)1-epsilon))
|
if (dot>((S)1-epsilon))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
ScalarType a[6]; // Matrice 3x3 simmetrica: a11 a12 a13 a22 a23 a33
|
ScalarType a[6]; // Matrice 3x3 simmetrica: a11 a12 a13 a22 a23 a33
|
||||||
ScalarType b[3]; // Vettore r3
|
ScalarType b[3]; // Vettore r3
|
||||||
ScalarType c; // Fattore scalare (se -1 quadrica nulla)
|
ScalarType c; // Fattore scalare (se -1 quadrica nulla)
|
||||||
|
|
||||||
inline Quadric() { c = -1; }
|
inline Quadric() { c = -1; }
|
||||||
|
|
||||||
// Necessari se si utilizza stl microsoft
|
// Necessari se si utilizza stl microsoft
|
||||||
|
@ -155,14 +155,14 @@ template <class ResultScalarType>
|
||||||
|
|
||||||
/* Versione veloce */
|
/* Versione veloce */
|
||||||
return ResultScalarType (
|
return ResultScalarType (
|
||||||
p[0]*p[0]*a[0] + 2*p[0]*p[1]*a[1] + 2*p[0]*p[2]*a[2] + p[0]*b[0]
|
p[0]*p[0]*a[0] + 2*p[0]*p[1]*a[1] + 2*p[0]*p[2]*a[2] + p[0]*b[0]
|
||||||
+ p[1]*p[1]*a[3] + 2*p[1]*p[2]*a[4] + p[1]*b[1]
|
+ p[1]*p[1]*a[3] + 2*p[1]*p[2]*a[4] + p[1]*b[1]
|
||||||
+ p[2]*p[2]*a[5] + p[2]*b[2] + c);
|
+ p[2]*p[2]*a[5] + p[2]*b[2] + c);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// spostare..risolve un sistema 3x3
|
// spostare..risolve un sistema 3x3
|
||||||
template<class FLTYPE>
|
template<class FLTYPE>
|
||||||
bool Gauss33( FLTYPE x[], FLTYPE C[3][3+1] )
|
bool Gauss33( FLTYPE x[], FLTYPE C[3][3+1] )
|
||||||
{
|
{
|
||||||
const FLTYPE keps = (FLTYPE)1e-3;
|
const FLTYPE keps = (FLTYPE)1e-3;
|
||||||
|
@ -227,7 +227,7 @@ bool Gauss33( FLTYPE x[], FLTYPE C[3][3+1] )
|
||||||
// determina il punto di errore minimo
|
// determina il punto di errore minimo
|
||||||
template <class ReturnScalarType>
|
template <class ReturnScalarType>
|
||||||
bool Minimum(Point3<ReturnScalarType> &x)
|
bool Minimum(Point3<ReturnScalarType> &x)
|
||||||
{
|
{
|
||||||
ReturnScalarType C[3][4];
|
ReturnScalarType C[3][4];
|
||||||
C[0][0]=a[0]; C[0][1]=a[1]; C[0][2]=a[2];
|
C[0][0]=a[0]; C[0][1]=a[1]; C[0][2]=a[2];
|
||||||
C[1][0]=a[1]; C[1][1]=a[3]; C[1][2]=a[4];
|
C[1][0]=a[1]; C[1][1]=a[3]; C[1][2]=a[4];
|
||||||
|
@ -240,10 +240,10 @@ bool Minimum(Point3<ReturnScalarType> &x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// determina il punto di errore minimo usando le fun di inversione di matrice che usano svd
|
// determina il punto di errore minimo usando le fun di inversione di matrice che usano svd
|
||||||
// Molto + lento
|
// Molto + lento
|
||||||
template <class ReturnScalarType>
|
template <class ReturnScalarType>
|
||||||
bool MinimumSVD(Point3<ReturnScalarType> &x)
|
bool MinimumSVD(Point3<ReturnScalarType> &x)
|
||||||
{
|
{
|
||||||
Matrix33<ReturnScalarType> C;
|
Matrix33<ReturnScalarType> C;
|
||||||
C[0][0]=a[0]; C[0][1]=a[1]; C[0][2]=a[2];
|
C[0][0]=a[0]; C[0][1]=a[1]; C[0][2]=a[2];
|
||||||
C[1][0]=a[1]; C[1][1]=a[3]; C[1][2]=a[4];
|
C[1][0]=a[1]; C[1][1]=a[3]; C[1][2]=a[4];
|
||||||
|
@ -259,7 +259,7 @@ bool MinimumSVD(Point3<ReturnScalarType> &x)
|
||||||
|
|
||||||
|
|
||||||
bool MinimumNew(Point3<ScalarType> &x) const
|
bool MinimumNew(Point3<ScalarType> &x) const
|
||||||
{
|
{
|
||||||
ScalarType c0=-b[0]/2;
|
ScalarType c0=-b[0]/2;
|
||||||
ScalarType c1=-b[1]/2;
|
ScalarType c1=-b[1]/2;
|
||||||
ScalarType c2=-b[2]/2;
|
ScalarType c2=-b[2]/2;
|
||||||
|
@ -279,12 +279,12 @@ bool MinimumNew(Point3<ScalarType> &x) const
|
||||||
}
|
}
|
||||||
// determina il punto di errore minimo vincolato nel segmento (a,b)
|
// determina il punto di errore minimo vincolato nel segmento (a,b)
|
||||||
bool Minimum(Point3<ScalarType> &x,Point3<ScalarType> &pa,Point3<ScalarType> &pb){
|
bool Minimum(Point3<ScalarType> &x,Point3<ScalarType> &pa,Point3<ScalarType> &pb){
|
||||||
ScalarType t1,t2, t4, t5, t8, t9,
|
ScalarType t1,t2, t4, t5, t8, t9,
|
||||||
t11,t12,t14,t15,t17,t18,t25,t26,t30,t34,t35,
|
t11,t12,t14,t15,t17,t18,t25,t26,t30,t34,t35,
|
||||||
t41,t42,t44,t45,t50,t52,t54,
|
t41,t42,t44,t45,t50,t52,t54,
|
||||||
t56,t21,t23,t37,t64,lambda;
|
t56,t21,t23,t37,t64,lambda;
|
||||||
|
|
||||||
t1 = a[4]*pb.z();
|
t1 = a[4]*pb.z();
|
||||||
t2 = t1*pa.y();
|
t2 = t1*pa.y();
|
||||||
t4 = a[1]*pb.y();
|
t4 = a[1]*pb.y();
|
||||||
t5 = t4*pa.x();
|
t5 = t4*pa.x();
|
||||||
|
@ -320,14 +320,14 @@ ScalarType t1,t2, t4, t5, t8, t9,
|
||||||
|
|
||||||
if(lambda<0) lambda=0; else if(lambda>1) lambda = 1;
|
if(lambda<0) lambda=0; else if(lambda>1) lambda = 1;
|
||||||
|
|
||||||
x = pa*(1.0-lambda)+pb*lambda;
|
x = pa*(1.0-lambda)+pb*lambda;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator *= ( const ScalarType & w ) // Amplifica una quadirca
|
void operator *= ( const ScalarType & w ) // Amplifica una quadirca
|
||||||
{
|
{
|
||||||
assert( IsValid() );
|
assert( IsValid() );
|
||||||
|
|
||||||
a[0] *= w;
|
a[0] *= w;
|
||||||
a[1] *= w;
|
a[1] *= w;
|
||||||
a[2] *= w;
|
a[2] *= w;
|
||||||
|
|
|
@ -92,7 +92,7 @@ class PointNormalDistanceFunctor {
|
||||||
inline bool operator () (const VERTEXTYPE & v, const VERTEXTYPE & vp, SCALARTYPE & minDist, Point3<SCALARTYPE> & q) {
|
inline bool operator () (const VERTEXTYPE & v, const VERTEXTYPE & vp, SCALARTYPE & minDist, Point3<SCALARTYPE> & q) {
|
||||||
|
|
||||||
float h = vcg::Distance(v.cP(),vp.P()) ;
|
float h = vcg::Distance(v.cP(),vp.P()) ;
|
||||||
float dev = InterPoint ()* ( pow((ScalarType) (1-v.cN()*vp.cN()),(ScalarType) Beta()) / (Gamma()*h +0.1));
|
float dev = InterPoint() * ( pow((ScalarType) (1-v.cN().dot(vp.cN())), (ScalarType)Beta()) / (Gamma()*h +0.1));
|
||||||
if(h+dev < minDist){
|
if(h+dev < minDist){
|
||||||
minDist = h+dev;
|
minDist = h+dev;
|
||||||
q = v.P();
|
q = v.P();
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -84,28 +84,28 @@ namespace vcg {
|
||||||
/**
|
/**
|
||||||
The templated class for representing 4 entity color.
|
The templated class for representing 4 entity color.
|
||||||
The class is templated over the ScalarType. class that is used to represent color with float or with unsigned chars. All the usual
|
The class is templated over the ScalarType. class that is used to represent color with float or with unsigned chars. All the usual
|
||||||
operator overloading (* + - ...) is present.
|
operator overloading (* + - ...) is present.
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
class Color4 : public Point4<T>
|
class Color4 : public Point4<T>
|
||||||
{
|
{
|
||||||
typedef Point4<T> Base;
|
typedef Point4<T> Base;
|
||||||
public:
|
public:
|
||||||
/// Constant for storing standard colors.
|
/// Constant for storing standard colors.
|
||||||
/// Each color is stored in a simple in so that the bit pattern match with the one of Color4b.
|
/// Each color is stored in a simple in so that the bit pattern match with the one of Color4b.
|
||||||
enum ColorConstant {
|
enum ColorConstant {
|
||||||
Black =0xff000000,
|
Black =0xff000000,
|
||||||
Gray =0xff808080,
|
Gray =0xff808080,
|
||||||
White =0xffffffff,
|
White =0xffffffff,
|
||||||
|
|
||||||
Red =0xff0000ff,
|
Red =0xff0000ff,
|
||||||
Green =0xff00ff00,
|
Green =0xff00ff00,
|
||||||
Blue =0xffff0000,
|
Blue =0xffff0000,
|
||||||
|
|
||||||
Cyan =0xffffff00,
|
Cyan =0xffffff00,
|
||||||
Yellow =0xff00ffff,
|
Yellow =0xff00ffff,
|
||||||
Magenta=0xffff00ff,
|
Magenta=0xffff00ff,
|
||||||
|
|
||||||
LightGray =0xffc0c0c0,
|
LightGray =0xffc0c0c0,
|
||||||
LightRed =0xff8080ff,
|
LightRed =0xff8080ff,
|
||||||
LightGreen =0xff80ff80,
|
LightGreen =0xff80ff80,
|
||||||
|
@ -116,7 +116,7 @@ public:
|
||||||
DarkGreen =0xff004000,
|
DarkGreen =0xff004000,
|
||||||
DarkBlue =0xff400000
|
DarkBlue =0xff400000
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Color4 ( const T nx, const T ny, const T nz , const T nw ) :Point4<T>(nx,ny,nz,nw) {};
|
inline Color4 ( const T nx, const T ny, const T nz , const T nw ) :Point4<T>(nx,ny,nz,nw) {};
|
||||||
// inline Color4 ( Color4 &c) :Point4<T>(c) {};
|
// inline Color4 ( Color4 &c) :Point4<T>(c) {};
|
||||||
inline Color4 ( const Point4<T> &c) :Point4<T>(c) {};
|
inline Color4 ( const Point4<T> &c) :Point4<T>(c) {};
|
||||||
|
@ -129,26 +129,26 @@ public:
|
||||||
// TODO make sure the types are the same
|
// TODO make sure the types are the same
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class Q>
|
template <class Q>
|
||||||
inline void Import(const Color4<Q> & b )
|
inline void Import(const Color4<Q> & b )
|
||||||
{
|
{
|
||||||
Point4<T>::V()[0] = T(b[0]);
|
(*this)[0] = T(b[0]);
|
||||||
Point4<T>::V()[1] = T(b[1]);
|
(*this)[1] = T(b[1]);
|
||||||
Point4<T>::V()[2] = T(b[2]);
|
(*this)[2] = T(b[2]);
|
||||||
Point4<T>::V()[3] = T(b[3]);
|
(*this)[3] = T(b[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Q>
|
template <class Q>
|
||||||
inline void Import(const Point4<Q> & b )
|
inline void Import(const Point4<Q> & b )
|
||||||
{
|
{
|
||||||
Point4<T>::V()[0] = T(b[0]);
|
(*this)[0] = T(b[0]);
|
||||||
Point4<T>::V()[1] = T(b[1]);
|
(*this)[1] = T(b[1]);
|
||||||
Point4<T>::V()[2] = T(b[2]);
|
(*this)[2] = T(b[2]);
|
||||||
Point4<T>::V()[3] = T(b[3]);
|
(*this)[3] = T(b[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Q>
|
template <class Q>
|
||||||
static inline Color4 Construct( const Color4<Q> & b )
|
static inline Color4 Construct( const Color4<Q> & b )
|
||||||
{
|
{
|
||||||
return Color4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
|
return Color4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
|
||||||
|
@ -156,13 +156,13 @@ public:
|
||||||
|
|
||||||
//inline void Import(const Color4<float> &b);
|
//inline void Import(const Color4<float> &b);
|
||||||
//inline void Import(const Color4<unsigned char> &b);
|
//inline void Import(const Color4<unsigned char> &b);
|
||||||
|
|
||||||
inline Color4 operator + ( const Color4 & p) const
|
inline Color4 operator + ( const Color4 & p) const
|
||||||
{
|
{
|
||||||
return Color4( (*this)[0]+p.V()[0], (*this)[1]+p.V()[1], (*this)[2]+p.V()[2], (*this)[3]+p.V()[3] );
|
return Color4( (*this)[0]+p.V()[0], (*this)[1]+p.V()[1], (*this)[2]+p.V()[2], (*this)[3]+p.V()[3] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void lerp(const Color4 &c0, const Color4 &c1, const float x);
|
inline void lerp(const Color4 &c0, const Color4 &c1, const float x);
|
||||||
inline void lerp(const Color4 &c0, const Color4 &c1, const Color4 &c2, const Point3f &ip);
|
inline void lerp(const Color4 &c0, const Color4 &c1, const Color4 &c2, const Point3f &ip);
|
||||||
/// given a float and a range set the corresponding color in the well known red->green->blue color ramp. To reverse the direction of the ramp just swap minf and maxf.
|
/// given a float and a range set the corresponding color in the well known red->green->blue color ramp. To reverse the direction of the ramp just swap minf and maxf.
|
||||||
|
@ -203,10 +203,10 @@ public:
|
||||||
case 4: r=t; g=p; b=v; break;
|
case 4: r=t; g=p; b=v; break;
|
||||||
case 5: r=v; g=p; b=q; break;
|
case 5: r=v; g=p; b=q; break;
|
||||||
}
|
}
|
||||||
Point4<T>::V()[0]=(unsigned char)(255*r);
|
(*this)[0]=(unsigned char)(255*r);
|
||||||
Point4<T>::V()[1]=(unsigned char)(255*g);
|
(*this)[1]=(unsigned char)(255*g);
|
||||||
Point4<T>::V()[2]=(unsigned char)(255*b);
|
(*this)[2]=(unsigned char)(255*b);
|
||||||
Point4<T>::V()[3]=255;
|
(*this)[3]=255;
|
||||||
// V()[0]=r*256;V()[1]=g*256;V()[2]=b*256;
|
// V()[0]=r*256;V()[1]=g*256;V()[2]=b*256;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,9 +221,9 @@ inline void SetGrayShade(float f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Given an integer returns a well ordering of colors
|
/** Given an integer returns a well ordering of colors
|
||||||
// so that every color differs as much as possible form the previous one
|
// so that every color differs as much as possible form the previous one
|
||||||
// params:
|
// params:
|
||||||
// n is the maximum expected value (max of the range)
|
// n is the maximum expected value (max of the range)
|
||||||
// v is the requested position
|
// v is the requested position
|
||||||
*/
|
*/
|
||||||
|
@ -239,7 +239,7 @@ inline static Color4 Scatter(int n, int a,float Sat=.3f,float Val=.9f)
|
||||||
a -= (m+1)>>1;
|
a -= (m+1)>>1;
|
||||||
m >>= 1;
|
m >>= 1;
|
||||||
}
|
}
|
||||||
else m = (m+1)>>1;
|
else m = (m+1)>>1;
|
||||||
if (r>n-b) r = n-b;
|
if (r>n-b) r = n-b;
|
||||||
|
|
||||||
//TRACE("Scatter range 0..%i, in %i out %i\n",n,a,b);
|
//TRACE("Scatter range 0..%i, in %i out %i\n",n,a,b);
|
||||||
|
@ -265,7 +265,7 @@ template <class T>
|
||||||
inline void Color4<T>::lerp(const Color4<T> &c0, const Color4<T> &c1, const Color4<T> &c2, const Point3f &ip)
|
inline void Color4<T>::lerp(const Color4<T> &c0, const Color4<T> &c1, const Color4<T> &c2, const Point3f &ip)
|
||||||
{
|
{
|
||||||
assert(fabs(ip[0]+ip[1]+ip[2]-1)<0.00001);
|
assert(fabs(ip[0]+ip[1]+ip[2]-1)<0.00001);
|
||||||
|
|
||||||
(*this)[0]=(T)(c0[0]*ip[0] + c1[0]*ip[1]+ c2[0]*ip[2]);
|
(*this)[0]=(T)(c0[0]*ip[0] + c1[0]*ip[1]+ c2[0]*ip[2]);
|
||||||
(*this)[1]=(T)(c0[1]*ip[0] + c1[1]*ip[1]+ c2[1]*ip[2]);
|
(*this)[1]=(T)(c0[1]*ip[0] + c1[1]*ip[1]+ c2[1]*ip[2]);
|
||||||
(*this)[2]=(T)(c0[2]*ip[0] + c1[2]*ip[1]+ c2[2]*ip[2]);
|
(*this)[2]=(T)(c0[2]*ip[0] + c1[2]*ip[1]+ c2[2]*ip[2]);
|
||||||
|
@ -276,7 +276,7 @@ inline void Color4<T>::lerp(const Color4<T> &c0, const Color4<T> &c1, const Colo
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void Color4<T>::ColorRamp(const float &minf,const float &maxf ,float v )
|
inline void Color4<T>::ColorRamp(const float &minf,const float &maxf ,float v )
|
||||||
{
|
{
|
||||||
if(minf>maxf) { ColorRamp(maxf,minf,maxf+(minf-v)); return; }
|
if(minf>maxf) { ColorRamp(maxf,minf,maxf+(minf-v)); return; }
|
||||||
if(v < minf ) { *this=Color4<T>(Color4<T>::Red); return; }
|
if(v < minf ) { *this=Color4<T>(Color4<T>::Red); return; }
|
||||||
//the case v > maxf is handled automatically at the end of the function
|
//the case v > maxf is handled automatically at the end of the function
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ inline void Color4<T>::ColorRamp(const float &minf,const float &maxf ,float v )
|
||||||
#if !defined(__GNUC__) || (__GNUC__ > 3)
|
#if !defined(__GNUC__) || (__GNUC__ > 3)
|
||||||
template <>
|
template <>
|
||||||
#endif
|
#endif
|
||||||
template <>
|
template <>
|
||||||
inline void Color4<float>::Import(const Color4<unsigned char> &b)
|
inline void Color4<float>::Import(const Color4<unsigned char> &b)
|
||||||
{
|
{
|
||||||
(*this)[0]=b[0]/255.0f;
|
(*this)[0]=b[0]/255.0f;
|
||||||
|
@ -334,7 +334,7 @@ inline void Color4<unsigned char>::Import(const Point4<float> &b)
|
||||||
#if !defined(__GNUC__) || (__GNUC__ > 3)
|
#if !defined(__GNUC__) || (__GNUC__ > 3)
|
||||||
template <>
|
template <>
|
||||||
#endif
|
#endif
|
||||||
template <>
|
template <>
|
||||||
inline Color4<unsigned char> Color4<unsigned char>::Construct( const Color4<float> & b )
|
inline Color4<unsigned char> Color4<unsigned char>::Construct( const Color4<float> & b )
|
||||||
{
|
{
|
||||||
return Color4<unsigned char>(
|
return Color4<unsigned char>(
|
||||||
|
@ -347,7 +347,7 @@ inline Color4<unsigned char> Color4<unsigned char>::Construct( const Color4<floa
|
||||||
#if !defined(__GNUC__) || (__GNUC__ > 3)
|
#if !defined(__GNUC__) || (__GNUC__ > 3)
|
||||||
template <>
|
template <>
|
||||||
#endif
|
#endif
|
||||||
template <>
|
template <>
|
||||||
inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
|
inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
|
||||||
{
|
{
|
||||||
return Color4<float>(
|
return Color4<float>(
|
||||||
|
@ -357,7 +357,7 @@ inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
|
||||||
(float)(b[3])/255.0f);
|
(float)(b[3])/255.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
//template <class T,class S>
|
//template <class T,class S>
|
||||||
//inline void Color4<T>::Import(const Color4<S> &b)
|
//inline void Color4<T>::Import(const Color4<S> &b)
|
||||||
//{
|
//{
|
||||||
// V()[0] = T(b[0]);
|
// V()[0] = T(b[0]);
|
||||||
|
@ -369,13 +369,13 @@ inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
|
||||||
template<>
|
template<>
|
||||||
inline Color4<unsigned char>::Color4(Color4<unsigned char>::ColorConstant cc)
|
inline Color4<unsigned char>::Color4(Color4<unsigned char>::ColorConstant cc)
|
||||||
{
|
{
|
||||||
*((int *)this )= cc;
|
*((int *)this )= cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline Color4<float>::Color4(Color4<float>::ColorConstant cc)
|
inline Color4<float>::Color4(Color4<float>::ColorConstant cc)
|
||||||
{
|
{
|
||||||
Import(Color4<unsigned char>((Color4<unsigned char>::ColorConstant)cc));
|
Import(Color4<unsigned char>((Color4<unsigned char>::ColorConstant)cc));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Color4<float> Clamp(Color4<float> &c)
|
inline Color4<float> Clamp(Color4<float> &c)
|
||||||
|
@ -389,8 +389,8 @@ inline Color4<float> Clamp(Color4<float> &c)
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline Color4<unsigned char> Color4<unsigned char>::operator + ( const Color4<unsigned char> & p) const
|
inline Color4<unsigned char> Color4<unsigned char>::operator + ( const Color4<unsigned char> & p) const
|
||||||
{
|
{
|
||||||
return Color4<unsigned char>(
|
return Color4<unsigned char>(
|
||||||
math::Clamp(int((*this)[0])+int(p[0]),0,255),
|
math::Clamp(int((*this)[0])+int(p[0]),0,255),
|
||||||
math::Clamp(int((*this)[1])+int(p[1]),0,255),
|
math::Clamp(int((*this)[1])+int(p[1]),0,255),
|
||||||
math::Clamp(int((*this)[2])+int(p[2]),0,255),
|
math::Clamp(int((*this)[2])+int(p[2]),0,255),
|
||||||
|
|
|
@ -0,0 +1,359 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* VCGLib o o *
|
||||||
|
* Visual and Computer Graphics Library o o *
|
||||||
|
* _ O _ *
|
||||||
|
* Copyright(C) 2004 \/)\/ *
|
||||||
|
* Visual Computing Lab /\/| *
|
||||||
|
* ISTI - Italian National Research Council | *
|
||||||
|
* \ *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* 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 *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||||
|
* for more details. *
|
||||||
|
* *
|
||||||
|
****************************************************************************/
|
||||||
|
/****************************************************************************
|
||||||
|
History
|
||||||
|
|
||||||
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.9 2006/10/07 16:51:43 m_di_benedetto
|
||||||
|
Implemented Scale() method (was only declared).
|
||||||
|
|
||||||
|
Revision 1.8 2006/01/19 13:53:19 m_di_benedetto
|
||||||
|
Fixed product by scalar and SquaredNorm()
|
||||||
|
|
||||||
|
Revision 1.7 2005/10/15 19:11:49 m_di_benedetto
|
||||||
|
Corrected return type in Angle() and protected member access in unary operator -
|
||||||
|
|
||||||
|
Revision 1.6 2005/03/18 16:34:42 fiorin
|
||||||
|
minor changes to comply gcc compiler
|
||||||
|
|
||||||
|
Revision 1.5 2004/05/10 13:22:25 cignoni
|
||||||
|
small syntax error Math -> math in Angle
|
||||||
|
|
||||||
|
Revision 1.4 2004/04/05 11:57:32 cignoni
|
||||||
|
Add V() access function
|
||||||
|
|
||||||
|
Revision 1.3 2004/03/10 17:42:40 tarini
|
||||||
|
Added comments (Dox) !
|
||||||
|
Added Import(). Costruct(), ScalarType... Corrected cross prod (sign). Added Angle. Now using Math:: stuff for trigon. etc.
|
||||||
|
|
||||||
|
Revision 1.2 2004/03/03 15:07:40 cignoni
|
||||||
|
renamed protected member v -> _v
|
||||||
|
|
||||||
|
Revision 1.1 2004/02/13 00:44:53 cignoni
|
||||||
|
First commit...
|
||||||
|
|
||||||
|
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __VCGLIB_POINT2
|
||||||
|
#define __VCGLIB_POINT2
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <vcg/math/base.h>
|
||||||
|
|
||||||
|
namespace vcg {
|
||||||
|
|
||||||
|
/** \addtogroup space */
|
||||||
|
/*@{*/
|
||||||
|
/**
|
||||||
|
The templated class for representing a point in 2D space.
|
||||||
|
The class is templated over the ScalarType class that is used to represent coordinates.
|
||||||
|
All the usual operator overloading (* + - ...) is present.
|
||||||
|
*/
|
||||||
|
template <class P2ScalarType> class Point2
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/// The only data member. Hidden to user.
|
||||||
|
P2ScalarType _v[2];
|
||||||
|
public:
|
||||||
|
/// the scalar type
|
||||||
|
typedef P2ScalarType ScalarType;
|
||||||
|
enum {Dimension = 2};
|
||||||
|
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/** @name Access to Coords.
|
||||||
|
access to coords is done by overloading of [] or explicit naming of coords (X,Y,)
|
||||||
|
("p[0]" or "p.X()" are equivalent) **/
|
||||||
|
inline const ScalarType &X() const {return _v[0];}
|
||||||
|
inline const ScalarType &Y() const {return _v[1];}
|
||||||
|
inline ScalarType &X() {return _v[0];}
|
||||||
|
inline ScalarType &Y() {return _v[1];}
|
||||||
|
inline const ScalarType * V() const
|
||||||
|
{
|
||||||
|
return _v;
|
||||||
|
}
|
||||||
|
inline ScalarType & V( const int i )
|
||||||
|
{
|
||||||
|
assert(i>=0 && i<2);
|
||||||
|
return _v[i];
|
||||||
|
}
|
||||||
|
inline const ScalarType & V( const int i ) const
|
||||||
|
{
|
||||||
|
assert(i>=0 && i<2);
|
||||||
|
return _v[i];
|
||||||
|
}
|
||||||
|
inline const ScalarType & operator [] ( const int i ) const
|
||||||
|
{
|
||||||
|
assert(i>=0 && i<2);
|
||||||
|
return _v[i];
|
||||||
|
}
|
||||||
|
inline ScalarType & operator [] ( const int i )
|
||||||
|
{
|
||||||
|
assert(i>=0 && i<2);
|
||||||
|
return _v[i];
|
||||||
|
}
|
||||||
|
//@}
|
||||||
|
/// empty constructor (does nothing)
|
||||||
|
inline Point2 () { }
|
||||||
|
/// x,y constructor
|
||||||
|
inline Point2 ( const ScalarType nx, const ScalarType ny )
|
||||||
|
{
|
||||||
|
_v[0] = nx; _v[1] = ny;
|
||||||
|
}
|
||||||
|
/// copy constructor
|
||||||
|
inline Point2 ( Point2 const & p)
|
||||||
|
{
|
||||||
|
_v[0]= p._v[0]; _v[1]= p._v[1];
|
||||||
|
}
|
||||||
|
/// copy
|
||||||
|
inline Point2 & operator =( Point2 const & p)
|
||||||
|
{
|
||||||
|
_v[0]= p._v[0]; _v[1]= p._v[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/// sets the point to (0,0)
|
||||||
|
inline void SetZero()
|
||||||
|
{ _v[0] = 0;_v[1] = 0;}
|
||||||
|
/// dot product
|
||||||
|
inline ScalarType operator * ( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return ( _v[0]*p._v[0] + _v[1]*p._v[1] );
|
||||||
|
}
|
||||||
|
/// cross product
|
||||||
|
inline ScalarType operator ^ ( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return _v[0]*p._v[1] - _v[1]*p._v[0];
|
||||||
|
}
|
||||||
|
//@{
|
||||||
|
/** @name Linearity for 2d points (operators +, -, *, /, *= ...) **/
|
||||||
|
inline Point2 operator + ( Point2 const & p) const
|
||||||
|
{
|
||||||
|
return Point2<ScalarType>( _v[0]+p._v[0], _v[1]+p._v[1] );
|
||||||
|
}
|
||||||
|
inline Point2 operator - ( Point2 const & p) const
|
||||||
|
{
|
||||||
|
return Point2<ScalarType>( _v[0]-p._v[0], _v[1]-p._v[1] );
|
||||||
|
}
|
||||||
|
inline Point2 operator * ( const ScalarType s ) const
|
||||||
|
{
|
||||||
|
return Point2<ScalarType>( _v[0] * s, _v[1] * s );
|
||||||
|
}
|
||||||
|
inline Point2 operator / ( const ScalarType s ) const
|
||||||
|
{
|
||||||
|
return Point2<ScalarType>( _v[0] / s, _v[1] / s );
|
||||||
|
}
|
||||||
|
inline Point2 & operator += ( Point2 const & p)
|
||||||
|
{
|
||||||
|
_v[0] += p._v[0]; _v[1] += p._v[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline Point2 & operator -= ( Point2 const & p)
|
||||||
|
{
|
||||||
|
_v[0] -= p._v[0]; _v[1] -= p._v[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline Point2 & operator *= ( const ScalarType s )
|
||||||
|
{
|
||||||
|
_v[0] *= s; _v[1] *= s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline Point2 & operator /= ( const ScalarType s )
|
||||||
|
{
|
||||||
|
_v[0] /= s; _v[1] /= s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//@}
|
||||||
|
/// returns the norm (Euclidian)
|
||||||
|
inline ScalarType Norm( void ) const
|
||||||
|
{
|
||||||
|
return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] );
|
||||||
|
}
|
||||||
|
/// returns the squared norm (Euclidian)
|
||||||
|
inline ScalarType SquaredNorm( void ) const
|
||||||
|
{
|
||||||
|
return ( _v[0]*_v[0] + _v[1]*_v[1] );
|
||||||
|
}
|
||||||
|
inline Point2 & Scale( const ScalarType sx, const ScalarType sy )
|
||||||
|
{
|
||||||
|
_v[0] *= sx;
|
||||||
|
_v[1] *= sy;
|
||||||
|
return * this;
|
||||||
|
}
|
||||||
|
/// normalizes, and returns itself as result
|
||||||
|
inline Point2 & Normalize( void )
|
||||||
|
{
|
||||||
|
ScalarType n = math::Sqrt(_v[0]*_v[0] + _v[1]*_v[1]);
|
||||||
|
if(n>0.0) { _v[0] /= n; _v[1] /= n; }
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/// points equality
|
||||||
|
inline bool operator == ( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return (_v[0]==p._v[0] && _v[1]==p._v[1]);
|
||||||
|
}
|
||||||
|
/// disparity between points
|
||||||
|
inline bool operator != ( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return ( (_v[0]!=p._v[0]) || (_v[1]!=p._v[1]) );
|
||||||
|
}
|
||||||
|
/// lexical ordering
|
||||||
|
inline bool operator < ( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return (_v[1]!=p._v[1])?(_v[1]<p._v[1]):
|
||||||
|
(_v[0]<p._v[0]);
|
||||||
|
}
|
||||||
|
/// lexical ordering
|
||||||
|
inline bool operator > ( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return (_v[1]!=p._v[1])?(_v[1]>p._v[1]):
|
||||||
|
(_v[0]>p._v[0]);
|
||||||
|
}
|
||||||
|
/// lexical ordering
|
||||||
|
inline bool operator <= ( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return (_v[1]!=p._v[1])?(_v[1]< p._v[1]):
|
||||||
|
(_v[0]<=p._v[0]);
|
||||||
|
}
|
||||||
|
/// lexical ordering
|
||||||
|
inline bool operator >= ( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return (_v[1]!=p._v[1])?(_v[1]> p._v[1]):
|
||||||
|
(_v[0]>=p._v[0]);
|
||||||
|
}
|
||||||
|
/// returns the distance to another point p
|
||||||
|
inline ScalarType Distance( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return Norm(*this-p);
|
||||||
|
}
|
||||||
|
/// returns the suqared distance to another point p
|
||||||
|
inline ScalarType SquaredDistance( Point2 const & p ) const
|
||||||
|
{
|
||||||
|
return Norm2(*this-p);
|
||||||
|
}
|
||||||
|
/// returns the angle with X axis (radiants, in [-PI, +PI] )
|
||||||
|
inline ScalarType Angle() const {
|
||||||
|
return math::Atan2(_v[1],_v[0]);
|
||||||
|
}
|
||||||
|
/// transform the point in cartesian coords into polar coords
|
||||||
|
inline Point2 & Cartesian2Polar()
|
||||||
|
{
|
||||||
|
ScalarType t = Angle();
|
||||||
|
_v[0] = Norm();
|
||||||
|
_v[1] = t;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/// transform the point in polar coords into cartesian coords
|
||||||
|
inline Point2 & Polar2Cartesian()
|
||||||
|
{
|
||||||
|
ScalarType l = _v[0];
|
||||||
|
_v[0] = (ScalarType)(l*math::Cos(_v[1]));
|
||||||
|
_v[1] = (ScalarType)(l*math::Sin(_v[1]));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/// rotates the point of an angle (radiants, counterclockwise)
|
||||||
|
inline Point2 & Rotate( const ScalarType rad )
|
||||||
|
{
|
||||||
|
ScalarType t = _v[0];
|
||||||
|
ScalarType s = math::Sin(rad);
|
||||||
|
ScalarType c = math::Cos(rad);
|
||||||
|
|
||||||
|
_v[0] = _v[0]*c - _v[1]*s;
|
||||||
|
_v[1] = t *s + _v[1]*c;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Questa funzione estende il vettore ad un qualsiasi numero di dimensioni
|
||||||
|
/// paddando gli elementi estesi con zeri
|
||||||
|
inline ScalarType Ext( const int i ) const
|
||||||
|
{
|
||||||
|
if(i>=0 && i<2) return _v[i];
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
/// imports from 2D points of different types
|
||||||
|
template <class T>
|
||||||
|
inline void Import( const Point2<T> & b )
|
||||||
|
{
|
||||||
|
_v[0] = b.X(); _v[1] = b.Y();
|
||||||
|
}
|
||||||
|
/// constructs a 2D points from an existing one of different type
|
||||||
|
template <class T>
|
||||||
|
static Point2 Construct( const Point2<T> & b )
|
||||||
|
{
|
||||||
|
return Point2(b.X(),b.Y());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}; // end class definition
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T Angle( Point2<T> const & p0, Point2<T> const & p1 )
|
||||||
|
{
|
||||||
|
return p1.Angle() - p0.Angle();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Point2<T> operator - ( Point2<T> const & p ){
|
||||||
|
return Point2<T>( -p[0], -p[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Point2<T> operator * ( const T s, Point2<T> const & p ){
|
||||||
|
return Point2<T>( p[0] * s, p[1] * s );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T Norm( Point2<T> const & p ){
|
||||||
|
return p.Norm();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T SquaredNorm( Point2<T> const & p ){
|
||||||
|
return p.SquaredNorm();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Point2<T> & Normalize( Point2<T> & p ){
|
||||||
|
return p.Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T Distance( Point2<T> const & p1,Point2<T> const & p2 ){
|
||||||
|
return Norm(p1-p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T SquaredDistance( Point2<T> const & p1,Point2<T> const & p2 ){
|
||||||
|
return SquaredNorm(p1-p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Point2<short> Point2s;
|
||||||
|
typedef Point2<int> Point2i;
|
||||||
|
typedef Point2<float> Point2f;
|
||||||
|
typedef Point2<double> Point2d;
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
} // end namespace
|
||||||
|
#endif
|
|
@ -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. *
|
||||||
|
@ -68,8 +68,8 @@ namespace vcg {
|
||||||
/*@{*/
|
/*@{*/
|
||||||
/**
|
/**
|
||||||
The templated class for representing a point in 4D space.
|
The templated class for representing a point in 4D space.
|
||||||
The class is templated over the ScalarType class that is used to represent coordinates.
|
The class is templated over the ScalarType class that is used to represent coordinates.
|
||||||
All the usual operator (* + - ...) are defined.
|
All the usual operator (* + - ...) are defined.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <class T> class Point4
|
template <class T> class Point4
|
||||||
|
@ -84,7 +84,7 @@ public:
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @name Standard Constructors and Initializers
|
/** @name Standard Constructors and Initializers
|
||||||
No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different point types
|
No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different point types
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
@ -94,15 +94,15 @@ public:
|
||||||
_v[0] = nx; _v[1] = ny; _v[2] = nz; _v[3] = nw;
|
_v[0] = nx; _v[1] = ny; _v[2] = nz; _v[3] = nw;
|
||||||
}
|
}
|
||||||
inline Point4 ( const T p[4] )
|
inline Point4 ( const T p[4] )
|
||||||
{
|
{
|
||||||
_v[0] = p[0]; _v[1]= p[1]; _v[2] = p[2]; _v[3]= p[3];
|
_v[0] = p[0]; _v[1]= p[1]; _v[2] = p[2]; _v[3]= p[3];
|
||||||
}
|
}
|
||||||
inline Point4 ( const Point4 & p )
|
inline Point4 ( const Point4 & p )
|
||||||
{
|
{
|
||||||
_v[0]= p._v[0]; _v[1]= p._v[1]; _v[2]= p._v[2]; _v[3]= p._v[3];
|
_v[0]= p._v[0]; _v[1]= p._v[1]; _v[2]= p._v[2]; _v[3]= p._v[3];
|
||||||
}
|
}
|
||||||
inline void Zero()
|
inline void SetZero()
|
||||||
{
|
{
|
||||||
_v[0] = _v[1] = _v[2] = _v[3]= 0;
|
_v[0] = _v[1] = _v[2] = _v[3]= 0;
|
||||||
}
|
}
|
||||||
template <class Q>
|
template <class Q>
|
||||||
|
@ -114,7 +114,7 @@ public:
|
||||||
_v[3] = T(b[3]);
|
_v[3] = T(b[3]);
|
||||||
}
|
}
|
||||||
/// constuctor that imports from different Point4 types
|
/// constuctor that imports from different Point4 types
|
||||||
template <class Q>
|
template <class Q>
|
||||||
static inline Point4 Construct( const Point4<Q> & b )
|
static inline Point4 Construct( const Point4<Q> & b )
|
||||||
{
|
{
|
||||||
return Point4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
|
return Point4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
|
||||||
|
@ -124,7 +124,7 @@ public:
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @name Data Access.
|
/** @name Data Access.
|
||||||
access to data is done by overloading of [] or explicit naming of coords (x,y,z,w)
|
access to data is done by overloading of [] or explicit naming of coords (x,y,z,w)
|
||||||
**/
|
**/
|
||||||
inline const T & operator [] ( const int i ) const
|
inline const T & operator [] ( const int i ) const
|
||||||
|
@ -155,7 +155,7 @@ public:
|
||||||
assert(i>=0 && i<4);
|
assert(i>=0 && i<4);
|
||||||
return _v[i];
|
return _v[i];
|
||||||
}
|
}
|
||||||
/// Padding function: give a default 0 value to all the elements that are not in the [0..2] range.
|
/// Padding function: give a default 0 value to all the elements that are not in the [0..2] range.
|
||||||
/// Useful for managing in a consistent way object that could have point2 / point3 / point4
|
/// Useful for managing in a consistent way object that could have point2 / point3 / point4
|
||||||
inline T Ext( const int i ) const
|
inline T Ext( const int i ) const
|
||||||
{
|
{
|
||||||
|
@ -163,12 +163,12 @@ public:
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/** @name Linear operators and the likes
|
/** @name Linear operators and the likes
|
||||||
**/
|
**/
|
||||||
inline Point4 operator + ( const Point4 & p) const
|
inline Point4 operator + ( const Point4 & p) const
|
||||||
{
|
{
|
||||||
return Point4( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2], _v[3]+p._v[3] );
|
return Point4( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2], _v[3]+p._v[3] );
|
||||||
}
|
}
|
||||||
inline Point4 operator - ( const Point4 & p) const
|
inline Point4 operator - ( const Point4 & p) const
|
||||||
|
@ -208,7 +208,7 @@ public:
|
||||||
return Point4( -_v[0], -_v[1], -_v[2], -_v[3] );
|
return Point4( -_v[0], -_v[1], -_v[2], -_v[3] );
|
||||||
}
|
}
|
||||||
inline Point4 VectProd ( const Point4 &x, const Point4 &z ) const
|
inline Point4 VectProd ( const Point4 &x, const Point4 &z ) const
|
||||||
{
|
{
|
||||||
Point4 res;
|
Point4 res;
|
||||||
const Point4 &y = *this;
|
const Point4 &y = *this;
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ public:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/** @name Norms and normalizations
|
/** @name Norms and normalizations
|
||||||
**/
|
**/
|
||||||
|
@ -237,7 +237,7 @@ public:
|
||||||
{
|
{
|
||||||
return _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3];
|
return _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3];
|
||||||
}
|
}
|
||||||
/// Euclidian normalization
|
/// Euclidian normalization
|
||||||
inline Point4 & Normalize()
|
inline Point4 & Normalize()
|
||||||
{
|
{
|
||||||
T n = sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );
|
T n = sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );
|
||||||
|
@ -251,14 +251,14 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/** @name Comparison operators (lexicographical order)
|
/** @name Comparison operators (lexicographical order)
|
||||||
**/
|
**/
|
||||||
inline bool operator == ( const Point4& p ) const
|
inline bool operator == ( const Point4& p ) const
|
||||||
{
|
{
|
||||||
return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] && _v[3]==p._v[3];
|
return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] && _v[3]==p._v[3];
|
||||||
}
|
}
|
||||||
inline bool operator != ( const Point4 & p ) const
|
inline bool operator != ( const Point4 & p ) const
|
||||||
{
|
{
|
||||||
return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] || _v[3]!=p._v[3];
|
return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] || _v[3]!=p._v[3];
|
||||||
|
@ -292,7 +292,7 @@ public:
|
||||||
(_v[0]>=p._v[0]);
|
(_v[0]>=p._v[0]);
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/** @name Dot products
|
/** @name Dot products
|
||||||
**/
|
**/
|
||||||
|
@ -326,7 +326,7 @@ public:
|
||||||
if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); }
|
if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); }
|
||||||
|
|
||||||
return ( (k0 + k1) + k2 ) +k3;
|
return ( (k0 + k1) + k2 ) +k3;
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ template<class T>
|
||||||
double StableDot ( Point4<T> const & p0, Point4<T> const & p1 )
|
double StableDot ( Point4<T> const & p0, Point4<T> const & p1 )
|
||||||
{
|
{
|
||||||
return p0.StableDot(p1);
|
return p0.StableDot(p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef Point4<short> Point4s;
|
typedef Point4<short> Point4s;
|
||||||
typedef Point4<int> Point4i;
|
typedef Point4<int> Point4i;
|
||||||
|
|
|
@ -88,7 +88,7 @@ Point3<S> PlaneFittingPoints( std::vector< Point3<S> > & samples,Plane3<S> &p){
|
||||||
d[1]=res[1][mini];
|
d[1]=res[1][mini];
|
||||||
d[2]=res[2][mini];
|
d[2]=res[2][mini];
|
||||||
|
|
||||||
p.SetOffset(c*d/d.Norm());
|
p.SetOffset(c.dot(d)/d.Norm());
|
||||||
p.SetDirection(d/d.Norm());
|
p.SetDirection(d/d.Norm());
|
||||||
|
|
||||||
return eval;
|
return eval;
|
||||||
|
|
|
@ -271,12 +271,12 @@ namespace vcg {
|
||||||
Point3t p21 = p2-p1;
|
Point3t p21 = p2-p1;
|
||||||
Point3t p20 = p2-p0;
|
Point3t p20 = p2-p0;
|
||||||
|
|
||||||
ScalarType delta0_p01 = p10*p1;
|
ScalarType delta0_p01 = p10.dot(p1);
|
||||||
ScalarType delta1_p01 = -p10*p0;
|
ScalarType delta1_p01 = -p10.dot(p0);
|
||||||
ScalarType delta0_p02 = p20*p2;
|
ScalarType delta0_p02 = p20.dot(p2);
|
||||||
ScalarType delta2_p02 = -p20*p0;
|
ScalarType delta2_p02 = -p20.dot(p0);
|
||||||
ScalarType delta1_p12 = p21*p2;
|
ScalarType delta1_p12 = p21.dot(p2);
|
||||||
ScalarType delta2_p12 = -p21*p1;
|
ScalarType delta2_p12 = -p21.dot(p1);
|
||||||
|
|
||||||
// the closest point can be one of the vertices of the triangle
|
// the closest point can be one of the vertices of the triangle
|
||||||
if (delta1_p01<=ScalarType(0.0) && delta2_p02<=ScalarType(0.0)) { witness = p0; }
|
if (delta1_p01<=ScalarType(0.0) && delta2_p02<=ScalarType(0.0)) { witness = p0; }
|
||||||
|
@ -284,10 +284,10 @@ namespace vcg {
|
||||||
else if (delta0_p02<=ScalarType(0.0) && delta1_p12<=ScalarType(0.0)) { witness = p2; }
|
else if (delta0_p02<=ScalarType(0.0) && delta1_p12<=ScalarType(0.0)) { witness = p2; }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScalarType temp = p10*p2;
|
ScalarType temp = p10.dot(p2);
|
||||||
ScalarType delta0_p012 = delta0_p01*delta1_p12 + delta2_p12*temp;
|
ScalarType delta0_p012 = delta0_p01*delta1_p12 + delta2_p12*temp;
|
||||||
ScalarType delta1_p012 = delta1_p01*delta0_p02 - delta2_p02*temp;
|
ScalarType delta1_p012 = delta1_p01*delta0_p02 - delta2_p02*temp;
|
||||||
ScalarType delta2_p012 = delta2_p02*delta0_p01 - delta1_p01*(p20*p1);
|
ScalarType delta2_p012 = delta2_p02*delta0_p01 - delta1_p01*(p20.dot(p1));
|
||||||
|
|
||||||
// otherwise, can be a point lying on same edge of the triangle
|
// otherwise, can be a point lying on same edge of the triangle
|
||||||
if (delta0_p012<=ScalarType(0.0))
|
if (delta0_p012<=ScalarType(0.0))
|
||||||
|
@ -366,10 +366,10 @@ namespace vcg {
|
||||||
typedef typename SEGMENTTYPE::ScalarType T;
|
typedef typename SEGMENTTYPE::ScalarType T;
|
||||||
const T epsilon = T(1e-8);
|
const T epsilon = T(1e-8);
|
||||||
|
|
||||||
T k = pl.Direction() * (sg.P1()-sg.P0());
|
T k = pl.Direction().dot((sg.P1()-sg.P0()));
|
||||||
if( (k > -epsilon) && (k < epsilon))
|
if( (k > -epsilon) && (k < epsilon))
|
||||||
return false;
|
return false;
|
||||||
T r = (pl.Offset() - pl.Direction()*sg.P0())/k; // Compute ray distance
|
T r = (pl.Offset() - pl.Direction().dot(sg.P0()))/k; // Compute ray distance
|
||||||
if( (r<0) || (r > 1.0))
|
if( (r<0) || (r > 1.0))
|
||||||
return false;
|
return false;
|
||||||
po = sg.P0()*(1-r)+sg.P1() * r;
|
po = sg.P0()*(1-r)+sg.P1() * r;
|
||||||
|
@ -404,7 +404,7 @@ namespace vcg {
|
||||||
|
|
||||||
/// intersection between two triangles
|
/// intersection between two triangles
|
||||||
template<typename TRIANGLETYPE>
|
template<typename TRIANGLETYPE>
|
||||||
inline bool Intersection(const TRIANGLETYPE & t0,const TRIANGLETYPE & t1){
|
inline bool Intersection_(const TRIANGLETYPE & t0,const TRIANGLETYPE & t1){
|
||||||
return NoDivTriTriIsect(t0.P0(0),t0.P0(1),t0.P0(2),
|
return NoDivTriTriIsect(t0.P0(0),t0.P0(1),t0.P0(2),
|
||||||
t1.P0(0),t1.P0(1),t1.P0(2));
|
t1.P0(0),t1.P0(1),t1.P0(2));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
#define VCG_SPACE_NORMAL_EXTRAPOLATION_H
|
#define VCG_SPACE_NORMAL_EXTRAPOLATION_H
|
||||||
|
|
||||||
#include <vcg/math/matrix33.h>
|
#include <vcg/math/matrix33.h>
|
||||||
#include <vcg/math/linear.h>
|
#include <vcg/math/linear.h>
|
||||||
#include <vcg/math/lin_algebra.h>
|
#include <vcg/math/lin_algebra.h>
|
||||||
#include <vcg/math/disjoint_set.h>
|
#include <vcg/math/disjoint_set.h>
|
||||||
#include <vcg/space/box3.h>
|
#include <vcg/space/box3.h>
|
||||||
|
@ -57,7 +57,7 @@ namespace vcg
|
||||||
typedef typename vcg::Matrix33<ScalarType> MatrixType;
|
typedef typename vcg::Matrix33<ScalarType> MatrixType;
|
||||||
|
|
||||||
enum NormalOrientation {IsCorrect=0, MustBeFlipped=1};
|
enum NormalOrientation {IsCorrect=0, MustBeFlipped=1};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************
|
/*************************************************
|
||||||
* Inner class definitions
|
* Inner class definitions
|
||||||
|
@ -68,10 +68,10 @@ namespace vcg
|
||||||
// Object functor: compute the distance between a vertex and a point
|
// Object functor: compute the distance between a vertex and a point
|
||||||
struct VertPointDistanceFunctor
|
struct VertPointDistanceFunctor
|
||||||
{
|
{
|
||||||
inline bool operator()(const VertexType &v, const CoordType &p, ScalarType &d, CoordType &q) const
|
inline bool operator()(const VertexType &v, const CoordType &p, ScalarType &d, CoordType &q) const
|
||||||
{
|
{
|
||||||
ScalarType distance = vcg::Distance(p, v.P());
|
ScalarType distance = vcg::Distance(p, v.P());
|
||||||
if (distance>d)
|
if (distance>d)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
d = distance;
|
d = distance;
|
||||||
|
@ -95,10 +95,10 @@ namespace vcg
|
||||||
// Object functor: compute the distance between a point and the plane
|
// Object functor: compute the distance between a point and the plane
|
||||||
struct PlanePointDistanceFunctor
|
struct PlanePointDistanceFunctor
|
||||||
{
|
{
|
||||||
inline bool operator()(const Plane &plane, const CoordType &p, ScalarType &d, CoordType &q) const
|
inline bool operator()(const Plane &plane, const CoordType &p, ScalarType &d, CoordType &q) const
|
||||||
{
|
{
|
||||||
ScalarType distance = vcg::Distance(p, plane.center);
|
ScalarType distance = vcg::Distance(p, plane.center);
|
||||||
if (distance>d)
|
if (distance>d)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
d = distance;
|
d = distance;
|
||||||
|
@ -134,7 +134,7 @@ namespace vcg
|
||||||
VertexPointer vertex;
|
VertexPointer vertex;
|
||||||
std::vector< MSTNode* > sons;
|
std::vector< MSTNode* > sons;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector< Plane > PlaneContainer;
|
typedef std::vector< Plane > PlaneContainer;
|
||||||
typedef typename PlaneContainer::iterator PlaneIterator;
|
typedef typename PlaneContainer::iterator PlaneIterator;
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ namespace vcg
|
||||||
int percentage;
|
int percentage;
|
||||||
char message[128];
|
char message[128];
|
||||||
sprintf(message, "Locating tangent planes...");
|
sprintf(message, "Locating tangent planes...");
|
||||||
std::vector< Plane > tangent_planes(vertex_count);
|
std::vector< Plane > tangent_planes(vertex_count);
|
||||||
vcg::Octree< VertexType, ScalarType > octree_for_planes;
|
vcg::Octree< VertexType, ScalarType > octree_for_planes;
|
||||||
octree_for_planes.Set( begin, end );
|
octree_for_planes.Set( begin, end );
|
||||||
|
|
||||||
|
@ -182,8 +182,8 @@ namespace vcg
|
||||||
for (unsigned int n=0; n<k; n++)
|
for (unsigned int n=0; n<k; n++)
|
||||||
{
|
{
|
||||||
diff = nearest_points[n] - plane->center;
|
diff = nearest_points[n] - plane->center;
|
||||||
for (int i=0; i<3; i++)
|
for (int i=0; i<3; i++)
|
||||||
for (int j=0; j<3; j++)
|
for (int j=0; j<3; j++)
|
||||||
covariance_matrix[i][j]+=diff[i]*diff[j];
|
covariance_matrix[i][j]+=diff[i]*diff[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,10 +195,10 @@ namespace vcg
|
||||||
for (int d=0; d<3; d++)
|
for (int d=0; d<3; d++)
|
||||||
plane->normal[d] = eigenvectors[d][2];
|
plane->normal[d] = eigenvectors[d][2];
|
||||||
plane->normal.Normalize();
|
plane->normal.Normalize();
|
||||||
iter->N() = plane->normal;
|
iter->N() = plane->normal;
|
||||||
plane->index = int( std::distance(begin, iter) );
|
plane->index = int( std::distance(begin, iter) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: build the Riemannian graph, i.e. the graph where each point is connected to the k-nearest neigbours.
|
// Step 2: build the Riemannian graph, i.e. the graph where each point is connected to the k-nearest neigbours.
|
||||||
dataset_bb.SetNull();
|
dataset_bb.SetNull();
|
||||||
PlaneIterator ePlane = tangent_planes.end();
|
PlaneIterator ePlane = tangent_planes.end();
|
||||||
|
@ -215,7 +215,7 @@ namespace vcg
|
||||||
for (PlaneIterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
|
for (PlaneIterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
|
||||||
{
|
{
|
||||||
if (callback!=NULL && (++progress%step)==0 && (percentage=int((progress*100)/vertex_count))<100) (callback)(percentage, message);
|
if (callback!=NULL && (++progress%step)==0 && (percentage=int((progress*100)/vertex_count))<100) (callback)(percentage, message);
|
||||||
|
|
||||||
unsigned int kk = k;
|
unsigned int kk = k;
|
||||||
PlanePointDistanceFunctor ppdf;
|
PlanePointDistanceFunctor ppdf;
|
||||||
DummyObjectMarker dom;
|
DummyObjectMarker dom;
|
||||||
|
@ -224,7 +224,7 @@ namespace vcg
|
||||||
|
|
||||||
for (unsigned int n=0; n<k; n++)
|
for (unsigned int n=0; n<k; n++)
|
||||||
if (iPlane->index<nearest_planes[n]->index)
|
if (iPlane->index<nearest_planes[n]->index)
|
||||||
riemannian_graph[iPlane->index].push_back( RiemannianEdge( nearest_planes[n], 1.0f - fabs(iPlane->normal * nearest_planes[n]->normal)) );
|
riemannian_graph[iPlane->index].push_back(RiemannianEdge(nearest_planes[n], 1.0f - fabs(iPlane->normal .dot(nearest_planes[n]->normal))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: compute the minimum spanning tree (MST) over the Riemannian graph (we use the Kruskal algorithm)
|
// Step 3: compute the minimum spanning tree (MST) over the Riemannian graph (we use the Kruskal algorithm)
|
||||||
|
@ -237,7 +237,7 @@ namespace vcg
|
||||||
|
|
||||||
std::sort( E.begin(), E.end() );
|
std::sort( E.begin(), E.end() );
|
||||||
vcg::DisjointSet<Plane> planeset;
|
vcg::DisjointSet<Plane> planeset;
|
||||||
|
|
||||||
for (typename std::vector< Plane >::iterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
|
for (typename std::vector< Plane >::iterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
|
||||||
planeset.MakeSet( &*iPlane );
|
planeset.MakeSet( &*iPlane );
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ namespace vcg
|
||||||
for ( ; iMSTEdge!=eMSTEdge; iMSTEdge++)
|
for ( ; iMSTEdge!=eMSTEdge; iMSTEdge++)
|
||||||
{
|
{
|
||||||
if (callback!=NULL && (++progress%step)==0 && (percentage=int((progress*100)/mst_size))<100) (callback)(percentage, message);
|
if (callback!=NULL && (++progress%step)==0 && (percentage=int((progress*100)/mst_size))<100) (callback)(percentage, message);
|
||||||
|
|
||||||
int u_index = int(iMSTEdge->u->index);
|
int u_index = int(iMSTEdge->u->index);
|
||||||
int v_index = int(iMSTEdge->v->index);
|
int v_index = int(iMSTEdge->v->index);
|
||||||
incident_edges[ u_index ].push_back( v_index ),
|
incident_edges[ u_index ].push_back( v_index ),
|
||||||
|
@ -271,15 +271,15 @@ namespace vcg
|
||||||
// Traverse the incident_edges vector and build the MST
|
// Traverse the incident_edges vector and build the MST
|
||||||
VertexIterator iCurrentVertex, iSonVertex;
|
VertexIterator iCurrentVertex, iSonVertex;
|
||||||
std::vector< MSTNode > MST(vertex_count);
|
std::vector< MSTNode > MST(vertex_count);
|
||||||
|
|
||||||
typename std::vector< Plane >::iterator iFirstPlane = tangent_planes.begin();
|
typename std::vector< Plane >::iterator iFirstPlane = tangent_planes.begin();
|
||||||
typename std::vector< Plane >::iterator iCurrentPlane, iSonPlane;
|
typename std::vector< Plane >::iterator iCurrentPlane, iSonPlane;
|
||||||
|
|
||||||
MSTNode *mst_root;
|
MSTNode *mst_root;
|
||||||
int r_index = (root_index!=-1)? root_index : rand()*vertex_count/RAND_MAX;
|
int r_index = (root_index!=-1)? root_index : rand()*vertex_count/RAND_MAX;
|
||||||
mst_root = &MST[ r_index ];
|
mst_root = &MST[ r_index ];
|
||||||
mst_root->parent = mst_root; //the parent of the root is the root itself
|
mst_root->parent = mst_root; //the parent of the root is the root itself
|
||||||
|
|
||||||
if (orientation==MustBeFlipped)
|
if (orientation==MustBeFlipped)
|
||||||
{
|
{
|
||||||
iCurrentVertex = begin;
|
iCurrentVertex = begin;
|
||||||
|
@ -304,7 +304,7 @@ namespace vcg
|
||||||
std::advance((iCurrentVertex=begin), current_node_index); //retrieve the pointer to the correspective vertex
|
std::advance((iCurrentVertex=begin), current_node_index); //retrieve the pointer to the correspective vertex
|
||||||
current_node->vertex = &*iCurrentVertex; //and associate it to the MST node
|
current_node->vertex = &*iCurrentVertex; //and associate it to the MST node
|
||||||
|
|
||||||
std::vector< int >::iterator iSon = incident_edges[ current_node_index ].begin();
|
std::vector< int >::iterator iSon = incident_edges[ current_node_index ].begin();
|
||||||
std::vector< int >::iterator eSon = incident_edges[ current_node_index ].end();
|
std::vector< int >::iterator eSon = incident_edges[ current_node_index ].end();
|
||||||
for ( ; iSon!=eSon; iSon++)
|
for ( ; iSon!=eSon; iSon++)
|
||||||
{
|
{
|
||||||
|
@ -316,7 +316,7 @@ namespace vcg
|
||||||
//std::advance((iSonVertex=begin), *iSon);//retrieve the pointer to the Vertex associated to son
|
//std::advance((iSonVertex=begin), *iSon);//retrieve the pointer to the Vertex associated to son
|
||||||
border.push( *iSon );
|
border.push( *iSon );
|
||||||
}
|
}
|
||||||
maxSize = vcg::math::Max<int>(maxSize, queueSize);
|
maxSize = vcg::math::Max<int>(maxSize, queueSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,11 +337,11 @@ namespace vcg
|
||||||
for (int s=0; s<int(current_node->sons.size()); s++)
|
for (int s=0; s<int(current_node->sons.size()); s++)
|
||||||
{
|
{
|
||||||
if (callback!=NULL && ((++progress%step)==0) && (percentage=int((maxSize-queueSize)*100/maxSize))<100) (callback)(percentage, message);
|
if (callback!=NULL && ((++progress%step)==0) && (percentage=int((maxSize-queueSize)*100/maxSize))<100) (callback)(percentage, message);
|
||||||
|
|
||||||
if (current_node->vertex->N()*current_node->sons[s]->vertex->N()<ScalarType(0.0f))
|
if (current_node->vertex->N().dot(current_node->sons[s]->vertex->N())<ScalarType(0.0f))
|
||||||
current_node->sons[s]->vertex->N() *= ScalarType(-1.0f);
|
current_node->sons[s]->vertex->N() *= ScalarType(-1.0f);
|
||||||
border.push( current_node->sons[s] );
|
border.push( current_node->sons[s] );
|
||||||
maxSize = vcg::math::Max<int>(maxSize, queueSize);
|
maxSize = vcg::math::Max<int>(maxSize, queueSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -62,21 +62,21 @@ Revision 1.1 2004/03/16 03:07:38 tarini
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
|
|
||||||
namespace ndim{
|
namespace ndim{
|
||||||
|
|
||||||
|
|
||||||
//template <int N, class S>
|
|
||||||
|
//template <int N, class S>
|
||||||
//class Point;
|
//class Point;
|
||||||
|
|
||||||
/** \addtogroup space */
|
/** \addtogroup space */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
/**
|
/**
|
||||||
The templated class for representing a point in R^N space.
|
The templated class for representing a point in R^N space.
|
||||||
The class is templated over the ScalarType class that is used to represent coordinates.
|
The class is templated over the ScalarType class that is used to represent coordinates.
|
||||||
PointBase provides the interface and the common operators for points
|
PointBase provides the interface and the common operators for points
|
||||||
of any dimensionality.
|
of any dimensionality.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <int N, class S>
|
template <int N, class S>
|
||||||
class Point
|
class Point
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -94,14 +94,14 @@ public:
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @name Standard Constructors and Initializers
|
/** @name Standard Constructors and Initializers
|
||||||
No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different PointType types
|
No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different PointType types
|
||||||
**/
|
**/
|
||||||
|
|
||||||
inline Point () { };
|
inline Point () { };
|
||||||
// inline Point ( const S nv[N] );
|
// inline Point ( const S nv[N] );
|
||||||
|
|
||||||
/// Padding function: give a default 0 value to all the elements that are not in the [0..2] range.
|
/// Padding function: give a default 0 value to all the elements that are not in the [0..2] range.
|
||||||
/// Useful for managing in a consistent way object that could have point2 / point3 / point4
|
/// Useful for managing in a consistent way object that could have point2 / point3 / point4
|
||||||
inline S Ext( const int i ) const
|
inline S Ext( const int i ) const
|
||||||
{
|
{
|
||||||
|
@ -127,7 +127,7 @@ public:
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// importer for homogeneous points
|
/// importer for homogeneous points
|
||||||
template <class S2>
|
template <class S2>
|
||||||
inline void ImportHomo( const Point<N-1,S2> & b )
|
inline void ImportHomo( const Point<N-1,S2> & b )
|
||||||
{
|
{
|
||||||
|
@ -137,7 +137,7 @@ public:
|
||||||
_v[N-1] = 1.0;
|
_v[N-1] = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// constructor for homogeneus point.
|
/// constructor for homogeneus point.
|
||||||
template <int N2, class S2>
|
template <int N2, class S2>
|
||||||
static inline PointType Construct( const Point<N-1,S2> & b )
|
static inline PointType Construct( const Point<N-1,S2> & b )
|
||||||
{
|
{
|
||||||
|
@ -149,7 +149,7 @@ public:
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @name Data Access.
|
/** @name Data Access.
|
||||||
access to data is done by overloading of [] or explicit naming of coords (x,y,z)**/
|
access to data is done by overloading of [] or explicit naming of coords (x,y,z)**/
|
||||||
|
|
||||||
inline S & operator [] ( const int i )
|
inline S & operator [] ( const int i )
|
||||||
|
@ -162,10 +162,10 @@ public:
|
||||||
assert(i>=0 && i<N);
|
assert(i>=0 && i<N);
|
||||||
return _v[i];
|
return _v[i];
|
||||||
}
|
}
|
||||||
inline const S &X() const { return _v[0]; }
|
inline const S &X() const { return _v[0]; }
|
||||||
inline const S &Y() const { return _v[1]; }
|
inline const S &Y() const { return _v[1]; }
|
||||||
inline const S &Z() const { static_assert(N>2); return _v[2]; }
|
inline const S &Z() const { static_assert(N>2); return _v[2]; }
|
||||||
/// W is in any case the last coordinate.
|
/// W is in any case the last coordinate.
|
||||||
/// (in a 2D point, W() == Y(). In a 3D point, W()==Z()
|
/// (in a 2D point, W() == Y(). In a 3D point, W()==Z()
|
||||||
/// in a 4D point, W() is a separate component)
|
/// in a 4D point, W() is a separate component)
|
||||||
inline const S &W() const { return _v[N-1]; }
|
inline const S &W() const { return _v[N-1]; }
|
||||||
|
@ -190,11 +190,11 @@ public:
|
||||||
//@}
|
//@}
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @name Linearity for points
|
/** @name Linearity for points
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/// sets a PointType to Zero
|
/// sets a PointType to Zero
|
||||||
inline void Zero()
|
inline void SetZero()
|
||||||
{
|
{
|
||||||
for(unsigned int ii = 0; ii < Dimension;++ii)
|
for(unsigned int ii = 0; ii < Dimension;++ii)
|
||||||
V(ii) = S();
|
V(ii) = S();
|
||||||
|
@ -259,7 +259,7 @@ public:
|
||||||
V(ii) *= s;
|
V(ii) *= s;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PointType operator - () const
|
inline PointType operator - () const
|
||||||
{
|
{
|
||||||
PointType res;
|
PointType res;
|
||||||
|
@ -336,7 +336,7 @@ public:
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @name Comparison Operators.
|
/** @name Comparison Operators.
|
||||||
Lexicographic order.
|
Lexicographic order.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
@ -350,10 +350,10 @@ public:
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @name
|
/** @name
|
||||||
Glocal to Local and viceversa
|
Glocal to Local and viceversa
|
||||||
(provided for uniformity with other spatial classes. trivial for points)
|
(provided for uniformity with other spatial classes. trivial for points)
|
||||||
**/
|
**/
|
||||||
|
|
||||||
inline PointType LocalToGlobal(ParamType p) const{
|
inline PointType LocalToGlobal(ParamType p) const{
|
||||||
return *this; }
|
return *this; }
|
||||||
|
@ -372,9 +372,9 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class S>
|
template <class S>
|
||||||
class Point2 : public Point<2,S> {
|
class Point2 : public Point<2,S> {
|
||||||
public:
|
public:
|
||||||
typedef S ScalarType;
|
typedef S ScalarType;
|
||||||
typedef Point2 PointType;
|
typedef Point2 PointType;
|
||||||
using Point<2,S>::_v;
|
using Point<2,S>::_v;
|
||||||
|
@ -435,13 +435,13 @@ public:
|
||||||
inline Point2 ( const S nv[2] ){
|
inline Point2 ( const S nv[2] ){
|
||||||
_v[0]=nv[0]; _v[1]=nv[1]; };
|
_v[0]=nv[0]; _v[1]=nv[1]; };
|
||||||
|
|
||||||
inline Point2 operator + ( Point2 const & p) const {
|
inline Point2 operator + ( Point2 const & p) const {
|
||||||
return Point2( _v[0]+p._v[0], _v[1]+p._v[1]); }
|
return Point2( _v[0]+p._v[0], _v[1]+p._v[1]); }
|
||||||
|
|
||||||
inline Point2 operator - ( Point2 const & p) const {
|
inline Point2 operator - ( Point2 const & p) const {
|
||||||
return Point2( _v[0]-p._v[0], _v[1]-p._v[1]); }
|
return Point2( _v[0]-p._v[0], _v[1]-p._v[1]); }
|
||||||
|
|
||||||
inline Point2 operator * ( const S s ) const {
|
inline Point2 operator * ( const S s ) const {
|
||||||
return Point2( _v[0]*s, _v[1]*s ); }
|
return Point2( _v[0]*s, _v[1]*s ); }
|
||||||
|
|
||||||
inline Point2 operator / ( const S s ) const {
|
inline Point2 operator / ( const S s ) const {
|
||||||
|
@ -499,7 +499,7 @@ public:
|
||||||
inline Point2 & Normalize() {
|
inline Point2 & Normalize() {
|
||||||
PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n;} return *this;};
|
PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n;} return *this;};
|
||||||
|
|
||||||
template <class PT> Point2 & Normalize(const PT &p){
|
template <class PT> Point2 & Normalize(const PT &p){
|
||||||
PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; }
|
PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; }
|
||||||
return *this;};
|
return *this;};
|
||||||
|
|
||||||
|
@ -507,10 +507,10 @@ public:
|
||||||
if (_v[2]!=0.0) { _v[0] /= W(); W()=1.0; } return *this;};
|
if (_v[2]!=0.0) { _v[0] /= W(); W()=1.0; } return *this;};
|
||||||
|
|
||||||
inline S NormInfinity() const {
|
inline S NormInfinity() const {
|
||||||
return math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ); }
|
return math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ); }
|
||||||
|
|
||||||
inline S NormOne() const {
|
inline S NormOne() const {
|
||||||
return math::Abs(_v[0])+ math::Abs(_v[1]);}
|
return math::Abs(_v[0])+ math::Abs(_v[1]);}
|
||||||
|
|
||||||
inline S operator % ( Point2 const & p ) const {
|
inline S operator % ( Point2 const & p ) const {
|
||||||
return _v[0] * p._v[1] - _v[1] * p._v[0]; }
|
return _v[0] * p._v[1] - _v[1] * p._v[0]; }
|
||||||
|
@ -519,10 +519,10 @@ public:
|
||||||
return _v[0]+_v[1];}
|
return _v[0]+_v[1];}
|
||||||
|
|
||||||
inline S Max() const {
|
inline S Max() const {
|
||||||
return math::Max( _v[0], _v[1] ); }
|
return math::Max( _v[0], _v[1] ); }
|
||||||
|
|
||||||
inline S Min() const {
|
inline S Min() const {
|
||||||
return math::Min( _v[0], _v[1] ); }
|
return math::Min( _v[0], _v[1] ); }
|
||||||
|
|
||||||
inline int MaxI() const {
|
inline int MaxI() const {
|
||||||
return (_v[0] < _v[1]) ? 1:0; };
|
return (_v[0] < _v[1]) ? 1:0; };
|
||||||
|
@ -539,9 +539,9 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
class Point3 : public Point<3,S> {
|
class Point3 : public Point<3,S> {
|
||||||
public:
|
public:
|
||||||
typedef S ScalarType;
|
typedef S ScalarType;
|
||||||
typedef Point3<S> PointType;
|
typedef Point3<S> PointType;
|
||||||
using Point<3,S>::_v;
|
using Point<3,S>::_v;
|
||||||
|
@ -576,13 +576,13 @@ public:
|
||||||
inline Point3 ( const S nv[3] ){
|
inline Point3 ( const S nv[3] ){
|
||||||
_v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; };
|
_v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; };
|
||||||
|
|
||||||
inline Point3 operator + ( Point3 const & p) const{
|
inline Point3 operator + ( Point3 const & p) const{
|
||||||
return Point3( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2]); }
|
return Point3( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2]); }
|
||||||
|
|
||||||
inline Point3 operator - ( Point3 const & p) const {
|
inline Point3 operator - ( Point3 const & p) const {
|
||||||
return Point3( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2]); }
|
return Point3( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2]); }
|
||||||
|
|
||||||
inline Point3 operator * ( const S s ) const {
|
inline Point3 operator * ( const S s ) const {
|
||||||
return Point3( _v[0]*s, _v[1]*s , _v[2]*s ); }
|
return Point3( _v[0]*s, _v[1]*s , _v[2]*s ); }
|
||||||
|
|
||||||
inline Point3 operator / ( const S s ) const {
|
inline Point3 operator / ( const S s ) const {
|
||||||
|
@ -642,13 +642,13 @@ public:
|
||||||
(_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); }
|
(_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); }
|
||||||
|
|
||||||
inline PointType & Normalize() {
|
inline PointType & Normalize() {
|
||||||
S n = Norm();
|
S n = Norm();
|
||||||
if(n!=0.0) {
|
if(n!=0.0) {
|
||||||
n=S(1.0)/n;
|
n=S(1.0)/n;
|
||||||
_v[0]*=n; _v[1]*=n; _v[2]*=n; }
|
_v[0]*=n; _v[1]*=n; _v[2]*=n; }
|
||||||
return *this;};
|
return *this;};
|
||||||
|
|
||||||
template <class PT> PointType & Normalize(const PT &p){
|
template <class PT> PointType & Normalize(const PT &p){
|
||||||
S n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; }
|
S n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; }
|
||||||
return *this;};
|
return *this;};
|
||||||
|
|
||||||
|
@ -658,10 +658,10 @@ public:
|
||||||
|
|
||||||
inline S NormInfinity() const {
|
inline S NormInfinity() const {
|
||||||
return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ),
|
return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ),
|
||||||
math::Abs(_v[3]) ); }
|
math::Abs(_v[3]) ); }
|
||||||
|
|
||||||
inline S NormOne() const {
|
inline S NormOne() const {
|
||||||
return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]));}
|
return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]));}
|
||||||
|
|
||||||
inline S operator % ( PointType const & p ) const {
|
inline S operator % ( PointType const & p ) const {
|
||||||
S t = (*this)*p; /* Area, general formula */
|
S t = (*this)*p; /* Area, general formula */
|
||||||
|
@ -671,10 +671,10 @@ public:
|
||||||
return _v[0]+_v[1]+_v[2];}
|
return _v[0]+_v[1]+_v[2];}
|
||||||
|
|
||||||
inline S Max() const {
|
inline S Max() const {
|
||||||
return math::Max( math::Max( _v[0], _v[1] ), _v[2] ); }
|
return math::Max( math::Max( _v[0], _v[1] ), _v[2] ); }
|
||||||
|
|
||||||
inline S Min() const {
|
inline S Min() const {
|
||||||
return math::Min( math::Min( _v[0], _v[1] ), _v[2] ); }
|
return math::Min( math::Min( _v[0], _v[1] ), _v[2] ); }
|
||||||
|
|
||||||
inline int MaxI() const {
|
inline int MaxI() const {
|
||||||
int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; return i;};
|
int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; return i;};
|
||||||
|
@ -691,16 +691,16 @@ public:
|
||||||
frexp( double(k0), &exp0 );
|
frexp( double(k0), &exp0 );
|
||||||
frexp( double(k1), &exp1 );
|
frexp( double(k1), &exp1 );
|
||||||
frexp( double(k2), &exp2 );
|
frexp( double(k2), &exp2 );
|
||||||
if( exp0<exp1 )
|
if( exp0<exp1 )
|
||||||
if(exp0<exp2) return (k1+k2)+k0; else return (k0+k1)+k2;
|
if(exp0<exp2) return (k1+k2)+k0; else return (k0+k1)+k2;
|
||||||
else
|
else
|
||||||
if(exp1<exp2) return (k0+k2)+k1; else return (k0+k1)+k2;
|
if(exp1<exp2) return (k0+k2)+k1; else return (k0+k1)+k2;
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
class Point4 : public Point<4,S> {
|
class Point4 : public Point<4,S> {
|
||||||
public:
|
public:
|
||||||
typedef S ScalarType;
|
typedef S ScalarType;
|
||||||
|
@ -727,13 +727,13 @@ public:
|
||||||
inline Point4 ( const S nv[4] ){
|
inline Point4 ( const S nv[4] ){
|
||||||
_v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; _v[3]=nv[3]; };
|
_v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; _v[3]=nv[3]; };
|
||||||
|
|
||||||
inline Point4 operator + ( Point4 const & p) const {
|
inline Point4 operator + ( Point4 const & p) const {
|
||||||
return Point4( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2], _v[3]+p._v[3] ); }
|
return Point4( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2], _v[3]+p._v[3] ); }
|
||||||
|
|
||||||
inline Point4 operator - ( Point4 const & p) const {
|
inline Point4 operator - ( Point4 const & p) const {
|
||||||
return Point4( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2], _v[3]-p._v[3] ); }
|
return Point4( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2], _v[3]-p._v[3] ); }
|
||||||
|
|
||||||
inline Point4 operator * ( const S s ) const {
|
inline Point4 operator * ( const S s ) const {
|
||||||
return Point4( _v[0]*s, _v[1]*s , _v[2]*s , _v[3]*s ); }
|
return Point4( _v[0]*s, _v[1]*s , _v[2]*s , _v[3]*s ); }
|
||||||
|
|
||||||
inline PointType operator ^ ( PointType const & p ) const {
|
inline PointType operator ^ ( PointType const & p ) const {
|
||||||
|
@ -801,7 +801,7 @@ public:
|
||||||
PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n; _v[2]*=n; _v[3]*=n; }
|
PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n; _v[2]*=n; _v[3]*=n; }
|
||||||
return *this;};
|
return *this;};
|
||||||
|
|
||||||
template <class PT> PointType & Normalize(const PT &p){
|
template <class PT> PointType & Normalize(const PT &p){
|
||||||
PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; V(3)*=n; }
|
PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; V(3)*=n; }
|
||||||
return *this;};
|
return *this;};
|
||||||
|
|
||||||
|
@ -811,10 +811,10 @@ public:
|
||||||
|
|
||||||
inline S NormInfinity() const {
|
inline S NormInfinity() const {
|
||||||
return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ),
|
return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ),
|
||||||
math::Max( math::Abs(_v[2]), math::Abs(_v[3]) ) ); }
|
math::Max( math::Abs(_v[2]), math::Abs(_v[3]) ) ); }
|
||||||
|
|
||||||
inline S NormOne() const {
|
inline S NormOne() const {
|
||||||
return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]),math::Abs(_v[3]));}
|
return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]),math::Abs(_v[3]));}
|
||||||
|
|
||||||
inline S operator % ( PointType const & p ) const {
|
inline S operator % ( PointType const & p ) const {
|
||||||
S t = (*this)*p; /* Area, general formula */
|
S t = (*this)*p; /* Area, general formula */
|
||||||
|
@ -824,10 +824,10 @@ public:
|
||||||
return _v[0]+_v[1]+_v[2]+_v[3];}
|
return _v[0]+_v[1]+_v[2]+_v[3];}
|
||||||
|
|
||||||
inline S Max() const {
|
inline S Max() const {
|
||||||
return math::Max( math::Max( _v[0], _v[1] ), math::Max( _v[2], _v[3] )); }
|
return math::Max( math::Max( _v[0], _v[1] ), math::Max( _v[2], _v[3] )); }
|
||||||
|
|
||||||
inline S Min() const {
|
inline S Min() const {
|
||||||
return math::Min( math::Min( _v[0], _v[1] ), math::Min( _v[2], _v[3] )); }
|
return math::Min( math::Min( _v[0], _v[1] ), math::Min( _v[2], _v[3] )); }
|
||||||
|
|
||||||
inline int MaxI() const {
|
inline int MaxI() const {
|
||||||
int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; if (_v[i] < _v[3]) i=3;
|
int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; if (_v[i] < _v[3]) i=3;
|
||||||
|
@ -872,9 +872,9 @@ template <class S>
|
||||||
inline S AngleN( Point3<S> const & p1, Point3<S> const & p2 )
|
inline S AngleN( Point3<S> const & p1, Point3<S> const & p2 )
|
||||||
{
|
{
|
||||||
S w = p1*p2;
|
S w = p1*p2;
|
||||||
if(w>1)
|
if(w>1)
|
||||||
w = 1;
|
w = 1;
|
||||||
else if(w<-1)
|
else if(w<-1)
|
||||||
w=-1;
|
w=-1;
|
||||||
return (S) acos(w);
|
return (S) acos(w);
|
||||||
}
|
}
|
||||||
|
@ -914,14 +914,14 @@ inline S SquaredDistance( Point<N,S> const & p1,Point<N,S> const & p2 )
|
||||||
|
|
||||||
//template <typename S>
|
//template <typename S>
|
||||||
//struct Point2:public Point<2,S>{
|
//struct Point2:public Point<2,S>{
|
||||||
// inline Point2(){};
|
// inline Point2(){};
|
||||||
// inline Point2(Point<2,S> const & p):Point<2,S>(p){} ;
|
// inline Point2(Point<2,S> const & p):Point<2,S>(p){} ;
|
||||||
// inline Point2( const S a, const S b):Point<2,S>(a,b){};
|
// inline Point2( const S a, const S b):Point<2,S>(a,b){};
|
||||||
//};
|
//};
|
||||||
//
|
//
|
||||||
//template <typename S>
|
//template <typename S>
|
||||||
//struct Point3:public Point3<S> {
|
//struct Point3:public Point3<S> {
|
||||||
// inline Point3(){};
|
// inline Point3(){};
|
||||||
// inline Point3(Point3<S> const & p):Point3<S> (p){}
|
// inline Point3(Point3<S> const & p):Point3<S> (p){}
|
||||||
// inline Point3( const S a, const S b, const S c):Point3<S> (a,b,c){};
|
// inline Point3( const S a, const S b, const S c):Point3<S> (a,b,c){};
|
||||||
//};
|
//};
|
||||||
|
@ -929,7 +929,7 @@ inline S SquaredDistance( Point<N,S> const & p1,Point<N,S> const & p2 )
|
||||||
//
|
//
|
||||||
//template <typename S>
|
//template <typename S>
|
||||||
//struct Point4:public Point4<S>{
|
//struct Point4:public Point4<S>{
|
||||||
// inline Point4(){};
|
// inline Point4(){};
|
||||||
// inline Point4(Point4<S> const & p):Point4<S>(p){}
|
// inline Point4(Point4<S> const & p):Point4<S>(p){}
|
||||||
// inline Point4( const S a, const S b, const S c, const S d):Point4<S>(a,b,c,d){};
|
// inline Point4( const S a, const S b, const S c, const S d):Point4<S>(a,b,c,d){};
|
||||||
//};
|
//};
|
||||||
|
@ -942,7 +942,7 @@ typedef Point2<short> Vector2s;
|
||||||
typedef Point2<int> Vector2i;
|
typedef Point2<int> Vector2i;
|
||||||
typedef Point2<float> Vector2f;
|
typedef Point2<float> Vector2f;
|
||||||
typedef Point2<double> Vector2d;
|
typedef Point2<double> Vector2d;
|
||||||
|
|
||||||
typedef Point3<short> Point3s;
|
typedef Point3<short> Point3s;
|
||||||
typedef Point3<int> Point3i;
|
typedef Point3<int> Point3i;
|
||||||
typedef Point3<float> Point3f;
|
typedef Point3<float> Point3f;
|
||||||
|
@ -951,8 +951,8 @@ typedef Point3<short> Vector3s;
|
||||||
typedef Point3<int> Vector3i;
|
typedef Point3<int> Vector3i;
|
||||||
typedef Point3<float> Vector3f;
|
typedef Point3<float> Vector3f;
|
||||||
typedef Point3<double> Vector3d;
|
typedef Point3<double> Vector3d;
|
||||||
|
|
||||||
|
|
||||||
typedef Point4<short> Point4s;
|
typedef Point4<short> Point4s;
|
||||||
typedef Point4<int> Point4i;
|
typedef Point4<int> Point4i;
|
||||||
typedef Point4<float> Point4f;
|
typedef Point4<float> Point4f;
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -20,282 +20,166 @@
|
||||||
* for more details. *
|
* for more details. *
|
||||||
* *
|
* *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/****************************************************************************
|
|
||||||
History
|
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
#ifndef VCG_USE_EIGEN
|
||||||
Revision 1.9 2006/10/07 16:51:43 m_di_benedetto
|
#include "deprecated_point2.h"
|
||||||
Implemented Scale() method (was only declared).
|
#else
|
||||||
|
|
||||||
Revision 1.8 2006/01/19 13:53:19 m_di_benedetto
|
|
||||||
Fixed product by scalar and SquaredNorm()
|
|
||||||
|
|
||||||
Revision 1.7 2005/10/15 19:11:49 m_di_benedetto
|
|
||||||
Corrected return type in Angle() and protected member access in unary operator -
|
|
||||||
|
|
||||||
Revision 1.6 2005/03/18 16:34:42 fiorin
|
|
||||||
minor changes to comply gcc compiler
|
|
||||||
|
|
||||||
Revision 1.5 2004/05/10 13:22:25 cignoni
|
|
||||||
small syntax error Math -> math in Angle
|
|
||||||
|
|
||||||
Revision 1.4 2004/04/05 11:57:32 cignoni
|
|
||||||
Add V() access function
|
|
||||||
|
|
||||||
Revision 1.3 2004/03/10 17:42:40 tarini
|
|
||||||
Added comments (Dox) !
|
|
||||||
Added Import(). Costruct(), ScalarType... Corrected cross prod (sign). Added Angle. Now using Math:: stuff for trigon. etc.
|
|
||||||
|
|
||||||
Revision 1.2 2004/03/03 15:07:40 cignoni
|
|
||||||
renamed protected member v -> _v
|
|
||||||
|
|
||||||
Revision 1.1 2004/02/13 00:44:53 cignoni
|
|
||||||
First commit...
|
|
||||||
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __VCGLIB_POINT2
|
#ifndef __VCGLIB_POINT2
|
||||||
#define __VCGLIB_POINT2
|
#define __VCGLIB_POINT2
|
||||||
|
|
||||||
#include <assert.h>
|
#include "../math/eigen.h"
|
||||||
#include <vcg/math/base.h>
|
#include <vcg/math/base.h>
|
||||||
|
|
||||||
|
namespace vcg{
|
||||||
|
template<class Scalar> class Point2;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Eigen{
|
||||||
|
template<typename Scalar>
|
||||||
|
struct ei_traits<vcg::Point2<Scalar> > : ei_traits<Eigen::Matrix<Scalar,2,1> > {};
|
||||||
|
}
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
|
|
||||||
/** \addtogroup space */
|
/** \addtogroup space */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
/**
|
/**
|
||||||
The templated class for representing a point in 2D space.
|
The templated class for representing a point in 2D space.
|
||||||
The class is templated over the ScalarType class that is used to represent coordinates.
|
The class is templated over the Scalar class that is used to represent coordinates.
|
||||||
All the usual operator overloading (* + - ...) is present.
|
All the usual operator overloading (* + - ...) is present.
|
||||||
*/
|
*/
|
||||||
template <class P2ScalarType> class Point2
|
template <class _Scalar> class Point2 : public Eigen::Matrix<_Scalar,2,1>
|
||||||
{
|
{
|
||||||
protected:
|
typedef Eigen::Matrix<_Scalar,2,1> _Base;
|
||||||
/// The only data member. Hidden to user.
|
using _Base::coeff;
|
||||||
P2ScalarType _v[2];
|
using _Base::coeffRef;
|
||||||
|
using _Base::setZero;
|
||||||
|
using _Base::data;
|
||||||
|
using _Base::V;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// the scalar type
|
|
||||||
typedef P2ScalarType ScalarType;
|
_EIGEN_GENERIC_PUBLIC_INTERFACE(Point2,_Base);
|
||||||
|
typedef Scalar ScalarType;
|
||||||
|
|
||||||
|
VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Point2)
|
||||||
|
|
||||||
enum {Dimension = 2};
|
enum {Dimension = 2};
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
/** @name Access to Coords.
|
||||||
/** @name Access to Coords.
|
|
||||||
access to coords is done by overloading of [] or explicit naming of coords (X,Y,)
|
access to coords is done by overloading of [] or explicit naming of coords (X,Y,)
|
||||||
("p[0]" or "p.X()" are equivalent) **/
|
("p[0]" or "p.X()" are equivalent) **/
|
||||||
inline const ScalarType &X() const {return _v[0];}
|
inline const Scalar &X() const {return data()[0];}
|
||||||
inline const ScalarType &Y() const {return _v[1];}
|
inline const Scalar &Y() const {return data()[1];}
|
||||||
inline ScalarType &X() {return _v[0];}
|
inline Scalar &X() {return data()[0];}
|
||||||
inline ScalarType &Y() {return _v[1];}
|
inline Scalar &Y() {return data()[1];}
|
||||||
inline const ScalarType * V() const
|
|
||||||
{
|
inline Scalar & V( const int i )
|
||||||
return _v;
|
|
||||||
}
|
|
||||||
inline ScalarType & V( const int i )
|
|
||||||
{
|
{
|
||||||
assert(i>=0 && i<2);
|
assert(i>=0 && i<2);
|
||||||
return _v[i];
|
return data()[i];
|
||||||
}
|
}
|
||||||
inline const ScalarType & V( const int i ) const
|
inline const Scalar & V( const int i ) const
|
||||||
{
|
{
|
||||||
assert(i>=0 && i<2);
|
assert(i>=0 && i<2);
|
||||||
return _v[i];
|
return data()[i];
|
||||||
}
|
|
||||||
inline const ScalarType & operator [] ( const int i ) const
|
|
||||||
{
|
|
||||||
assert(i>=0 && i<2);
|
|
||||||
return _v[i];
|
|
||||||
}
|
|
||||||
inline ScalarType & operator [] ( const int i )
|
|
||||||
{
|
|
||||||
assert(i>=0 && i<2);
|
|
||||||
return _v[i];
|
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
/// empty constructor (does nothing)
|
|
||||||
|
/// empty constructor (does nothing)
|
||||||
inline Point2 () { }
|
inline Point2 () { }
|
||||||
/// x,y constructor
|
/// x,y constructor
|
||||||
inline Point2 ( const ScalarType nx, const ScalarType ny )
|
inline Point2 ( const Scalar nx, const Scalar ny ) : Base(nx,ny) {}
|
||||||
|
/// copy constructor
|
||||||
|
inline Point2(Point2 const & p) : Base(p) {}
|
||||||
|
template<typename OtherDerived>
|
||||||
|
inline Point2(const Eigen::MatrixBase<OtherDerived>& other) : Base(other) {}
|
||||||
|
|
||||||
|
/// cross product
|
||||||
|
inline Scalar operator ^ ( Point2 const & p ) const
|
||||||
{
|
{
|
||||||
_v[0] = nx; _v[1] = ny;
|
return data()[0]*p.data()[1] - data()[1]*p.data()[0];
|
||||||
}
|
}
|
||||||
/// copy constructor
|
|
||||||
inline Point2 ( Point2 const & p)
|
inline Point2 & Scale( const Scalar sx, const Scalar sy )
|
||||||
{
|
|
||||||
_v[0]= p._v[0]; _v[1]= p._v[1];
|
|
||||||
}
|
|
||||||
/// copy
|
|
||||||
inline Point2 & operator =( Point2 const & p)
|
|
||||||
{
|
{
|
||||||
_v[0]= p._v[0]; _v[1]= p._v[1];
|
data()[0] *= sx;
|
||||||
return *this;
|
data()[1] *= sy;
|
||||||
}
|
|
||||||
/// sets the point to (0,0)
|
|
||||||
inline void Zero()
|
|
||||||
{ _v[0] = 0;_v[1] = 0;}
|
|
||||||
/// dot product
|
|
||||||
inline ScalarType operator * ( Point2 const & p ) const
|
|
||||||
{
|
|
||||||
return ( _v[0]*p._v[0] + _v[1]*p._v[1] );
|
|
||||||
}
|
|
||||||
/// cross product
|
|
||||||
inline ScalarType operator ^ ( Point2 const & p ) const
|
|
||||||
{
|
|
||||||
return _v[0]*p._v[1] - _v[1]*p._v[0];
|
|
||||||
}
|
|
||||||
//@{
|
|
||||||
/** @name Linearity for 2d points (operators +, -, *, /, *= ...) **/
|
|
||||||
inline Point2 operator + ( Point2 const & p) const
|
|
||||||
{
|
|
||||||
return Point2<ScalarType>( _v[0]+p._v[0], _v[1]+p._v[1] );
|
|
||||||
}
|
|
||||||
inline Point2 operator - ( Point2 const & p) const
|
|
||||||
{
|
|
||||||
return Point2<ScalarType>( _v[0]-p._v[0], _v[1]-p._v[1] );
|
|
||||||
}
|
|
||||||
inline Point2 operator * ( const ScalarType s ) const
|
|
||||||
{
|
|
||||||
return Point2<ScalarType>( _v[0] * s, _v[1] * s );
|
|
||||||
}
|
|
||||||
inline Point2 operator / ( const ScalarType s ) const
|
|
||||||
{
|
|
||||||
return Point2<ScalarType>( _v[0] / s, _v[1] / s );
|
|
||||||
}
|
|
||||||
inline Point2 & operator += ( Point2 const & p)
|
|
||||||
{
|
|
||||||
_v[0] += p._v[0]; _v[1] += p._v[1];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
inline Point2 & operator -= ( Point2 const & p)
|
|
||||||
{
|
|
||||||
_v[0] -= p._v[0]; _v[1] -= p._v[1];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
inline Point2 & operator *= ( const ScalarType s )
|
|
||||||
{
|
|
||||||
_v[0] *= s; _v[1] *= s;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
inline Point2 & operator /= ( const ScalarType s )
|
|
||||||
{
|
|
||||||
_v[0] /= s; _v[1] /= s;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
/// returns the norm (Euclidian)
|
|
||||||
inline ScalarType Norm( void ) const
|
|
||||||
{
|
|
||||||
return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] );
|
|
||||||
}
|
|
||||||
/// returns the squared norm (Euclidian)
|
|
||||||
inline ScalarType SquaredNorm( void ) const
|
|
||||||
{
|
|
||||||
return ( _v[0]*_v[0] + _v[1]*_v[1] );
|
|
||||||
}
|
|
||||||
inline Point2 & Scale( const ScalarType sx, const ScalarType sy )
|
|
||||||
{
|
|
||||||
_v[0] *= sx;
|
|
||||||
_v[1] *= sy;
|
|
||||||
return * this;
|
return * this;
|
||||||
}
|
}
|
||||||
/// normalizes, and returns itself as result
|
|
||||||
inline Point2 & Normalize( void )
|
/// lexical ordering
|
||||||
{
|
|
||||||
ScalarType n = math::Sqrt(_v[0]*_v[0] + _v[1]*_v[1]);
|
|
||||||
if(n>0.0) { _v[0] /= n; _v[1] /= n; }
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
/// points equality
|
|
||||||
inline bool operator == ( Point2 const & p ) const
|
|
||||||
{
|
|
||||||
return (_v[0]==p._v[0] && _v[1]==p._v[1]);
|
|
||||||
}
|
|
||||||
/// disparity between points
|
|
||||||
inline bool operator != ( Point2 const & p ) const
|
|
||||||
{
|
|
||||||
return ( (_v[0]!=p._v[0]) || (_v[1]!=p._v[1]) );
|
|
||||||
}
|
|
||||||
/// lexical ordering
|
|
||||||
inline bool operator < ( Point2 const & p ) const
|
inline bool operator < ( Point2 const & p ) const
|
||||||
{
|
{
|
||||||
return (_v[1]!=p._v[1])?(_v[1]<p._v[1]):
|
return (data()[1]!=p.data()[1])?(data()[1]<p.data()[1]):
|
||||||
(_v[0]<p._v[0]);
|
(data()[0]<p.data()[0]);
|
||||||
}
|
}
|
||||||
/// lexical ordering
|
/// lexical ordering
|
||||||
inline bool operator > ( Point2 const & p ) const
|
inline bool operator > ( Point2 const & p ) const
|
||||||
{
|
{
|
||||||
return (_v[1]!=p._v[1])?(_v[1]>p._v[1]):
|
return (data()[1]!=p.data()[1])?(data()[1]>p.data()[1]):
|
||||||
(_v[0]>p._v[0]);
|
(data()[0]>p.data()[0]);
|
||||||
}
|
}
|
||||||
/// lexical ordering
|
/// lexical ordering
|
||||||
inline bool operator <= ( Point2 const & p ) const
|
inline bool operator <= ( Point2 const & p ) const
|
||||||
{
|
{
|
||||||
return (_v[1]!=p._v[1])?(_v[1]< p._v[1]):
|
return (data()[1]!=p.data()[1])?(data()[1]< p.data()[1]):
|
||||||
(_v[0]<=p._v[0]);
|
(data()[0]<=p.data()[0]);
|
||||||
}
|
}
|
||||||
/// lexical ordering
|
/// lexical ordering
|
||||||
inline bool operator >= ( Point2 const & p ) const
|
inline bool operator >= ( Point2 const & p ) const
|
||||||
{
|
{
|
||||||
return (_v[1]!=p._v[1])?(_v[1]> p._v[1]):
|
return (data()[1]!=p.data()[1])?(data()[1]> p.data()[1]):
|
||||||
(_v[0]>=p._v[0]);
|
(data()[0]>=p.data()[0]);
|
||||||
}
|
}
|
||||||
/// returns the distance to another point p
|
|
||||||
inline ScalarType Distance( Point2 const & p ) const
|
/// returns the angle with X axis (radiants, in [-PI, +PI] )
|
||||||
{
|
inline Scalar Angle() const {
|
||||||
return Norm(*this-p);
|
return math::Atan2(data()[1],data()[0]);
|
||||||
}
|
|
||||||
/// returns the suqared distance to another point p
|
|
||||||
inline ScalarType SquaredDistance( Point2 const & p ) const
|
|
||||||
{
|
|
||||||
return Norm2(*this-p);
|
|
||||||
}
|
|
||||||
/// returns the angle with X axis (radiants, in [-PI, +PI] )
|
|
||||||
inline ScalarType Angle() const {
|
|
||||||
return math::Atan2(_v[1],_v[0]);
|
|
||||||
}
|
}
|
||||||
/// transform the point in cartesian coords into polar coords
|
/// transform the point in cartesian coords into polar coords
|
||||||
inline Point2 & Cartesian2Polar()
|
inline Point2 & Cartesian2Polar()
|
||||||
{
|
{
|
||||||
ScalarType t = Angle();
|
Scalar t = Angle();
|
||||||
_v[0] = Norm();
|
data()[0] = this->norm();
|
||||||
_v[1] = t;
|
data()[1] = t;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
/// transform the point in polar coords into cartesian coords
|
/// transform the point in polar coords into cartesian coords
|
||||||
inline Point2 & Polar2Cartesian()
|
inline Point2 & Polar2Cartesian()
|
||||||
{
|
{
|
||||||
ScalarType l = _v[0];
|
Scalar l = data()[0];
|
||||||
_v[0] = (ScalarType)(l*math::Cos(_v[1]));
|
data()[0] = (Scalar)(l*math::Cos(data()[1]));
|
||||||
_v[1] = (ScalarType)(l*math::Sin(_v[1]));
|
data()[1] = (Scalar)(l*math::Sin(data()[1]));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
/// rotates the point of an angle (radiants, counterclockwise)
|
/// rotates the point of an angle (radiants, counterclockwise)
|
||||||
inline Point2 & Rotate( const ScalarType rad )
|
inline Point2 & Rotate( const Scalar rad )
|
||||||
{
|
{
|
||||||
ScalarType t = _v[0];
|
Scalar t = data()[0];
|
||||||
ScalarType s = math::Sin(rad);
|
Scalar s = math::Sin(rad);
|
||||||
ScalarType c = math::Cos(rad);
|
Scalar c = math::Cos(rad);
|
||||||
|
|
||||||
_v[0] = _v[0]*c - _v[1]*s;
|
data()[0] = data()[0]*c - data()[1]*s;
|
||||||
_v[1] = t *s + _v[1]*c;
|
data()[1] = t *s + data()[1]*c;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Questa funzione estende il vettore ad un qualsiasi numero di dimensioni
|
/// Questa funzione estende il vettore ad un qualsiasi numero di dimensioni
|
||||||
/// paddando gli elementi estesi con zeri
|
/// paddando gli elementi estesi con zeri
|
||||||
inline ScalarType Ext( const int i ) const
|
inline Scalar Ext( const int i ) const
|
||||||
{
|
{
|
||||||
if(i>=0 && i<2) return _v[i];
|
if(i>=0 && i<2) return data()[i];
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
/// imports from 2D points of different types
|
/// imports from 2D points of different types
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void Import( const Point2<T> & b )
|
inline void Import( const Point2<T> & b )
|
||||||
{
|
{
|
||||||
_v[0] = b.X(); _v[1] = b.Y();
|
data()[0] = b.X(); data()[1] = b.Y();
|
||||||
}
|
}
|
||||||
/// constructs a 2D points from an existing one of different type
|
/// constructs a 2D points from an existing one of different type
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -303,8 +187,6 @@ public:
|
||||||
{
|
{
|
||||||
return Point2(b.X(),b.Y());
|
return Point2(b.X(),b.Y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // end class definition
|
}; // end class definition
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,41 +196,6 @@ inline T Angle( Point2<T> const & p0, Point2<T> const & p1 )
|
||||||
return p1.Angle() - p0.Angle();
|
return p1.Angle() - p0.Angle();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline Point2<T> operator - ( Point2<T> const & p ){
|
|
||||||
return Point2<T>( -p[0], -p[1] );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline Point2<T> operator * ( const T s, Point2<T> const & p ){
|
|
||||||
return Point2<T>( p[0] * s, p[1] * s );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T Norm( Point2<T> const & p ){
|
|
||||||
return p.Norm();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T SquaredNorm( Point2<T> const & p ){
|
|
||||||
return p.SquaredNorm();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline Point2<T> & Normalize( Point2<T> & p ){
|
|
||||||
return p.Normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T Distance( Point2<T> const & p1,Point2<T> const & p2 ){
|
|
||||||
return Norm(p1-p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T SquaredDistance( Point2<T> const & p1,Point2<T> const & p2 ){
|
|
||||||
return SquaredNorm(p1-p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef Point2<short> Point2s;
|
typedef Point2<short> Point2s;
|
||||||
typedef Point2<int> Point2i;
|
typedef Point2<int> Point2i;
|
||||||
typedef Point2<float> Point2f;
|
typedef Point2<float> Point2f;
|
||||||
|
@ -357,3 +204,5 @@ typedef Point2<double> Point2d;
|
||||||
/*@}*/
|
/*@}*/
|
||||||
} // end namespace
|
} // end namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -38,6 +38,17 @@ template<class Scalar> class Point3;
|
||||||
namespace Eigen{
|
namespace Eigen{
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_traits<vcg::Point3<Scalar> > : ei_traits<Eigen::Matrix<Scalar,3,1> > {};
|
struct ei_traits<vcg::Point3<Scalar> > : ei_traits<Eigen::Matrix<Scalar,3,1> > {};
|
||||||
|
|
||||||
|
template<typename Scalar>
|
||||||
|
struct NumTraits<vcg::Point3<Scalar> > : NumTraits<Scalar>
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
ReadCost = 3,
|
||||||
|
AddCost = 3,
|
||||||
|
MulCost = 3
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
|
|
|
@ -51,13 +51,22 @@ namespace vcg
|
||||||
enum DrawMode {DMUser,DMWire,DMSolid} ;
|
enum DrawMode {DMUser,DMWire,DMSolid} ;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
///used to find right trasformation in case of rotation
|
///used to find right transformation in case of rotation
|
||||||
static void XAxis( vcg::Point3f zero, vcg::Point3f uno, Matrix44f & tr){
|
static void XAxis(vcg::Point3f zero, vcg::Point3f uno, Matrix44f & tr)
|
||||||
|
{
|
||||||
|
#ifndef VCG_USE_EIGEN
|
||||||
tr.SetZero();
|
tr.SetZero();
|
||||||
*((vcg::Point3f*)&tr[0][0]) = uno-zero;
|
*((vcg::Point3f*)&tr[0][0]) = uno-zero;
|
||||||
GetUV(*((vcg::Point3f*)tr[0]),*((vcg::Point3f*)tr[1]),*((vcg::Point3f*)tr[2]));
|
GetUV(*((vcg::Point3f*)tr[0]),*((vcg::Point3f*)tr[1]),*((vcg::Point3f*)tr[2]));
|
||||||
tr[3][3] = 1.0;
|
tr[3][3] = 1.0;
|
||||||
*((vcg::Point3f*)&tr[3][0]) = zero;
|
*((vcg::Point3f*)&tr[3][0]) = zero;
|
||||||
|
#else
|
||||||
|
tr.col(0).start<3>().setZero();
|
||||||
|
tr.row(0).start<3>() = (uno-zero).normalized(); // n
|
||||||
|
tr.row(1).start<3>() = tr.row(0).start<3>().unitOrthogonal(); // u
|
||||||
|
tr.row(2).start<3>() = tr.row(0).start<3>().cross(tr.row(1).start<3>()).normalized(); // v
|
||||||
|
tr.row(3) << zero.transpose(), 1.;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//set drawingmode parameters
|
//set drawingmode parameters
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -60,7 +60,7 @@ First working version!
|
||||||
#ifndef VCG_GL_SPACE_H
|
#ifndef VCG_GL_SPACE_H
|
||||||
#define VCG_GL_SPACE_H
|
#define VCG_GL_SPACE_H
|
||||||
|
|
||||||
// Please note that this file assume that you have already included your
|
// Please note that this file assume that you have already included your
|
||||||
// gl-extension wrapping utility, and that therefore all the extension symbol are already defined.
|
// gl-extension wrapping utility, and that therefore all the extension symbol are already defined.
|
||||||
|
|
||||||
#include <vcg/space/triangle3.h>
|
#include <vcg/space/triangle3.h>
|
||||||
|
@ -108,16 +108,16 @@ namespace vcg {
|
||||||
|
|
||||||
inline void glColor(Color4b const & c) { glColor4ubv(c.V());}
|
inline void glColor(Color4b const & c) { glColor4ubv(c.V());}
|
||||||
inline void glClearColor(Color4b const &c) { ::glClearColor(float(c[0])/255.0f,float(c[1])/255.0f,float(c[2])/255.0f,1.0f);}
|
inline void glClearColor(Color4b const &c) { ::glClearColor(float(c[0])/255.0f,float(c[1])/255.0f,float(c[2])/255.0f,1.0f);}
|
||||||
inline void glLight(GLenum light, GLenum pname, Color4b const & c) {
|
inline void glLight(GLenum light, GLenum pname, Color4b const & c) {
|
||||||
static float cf[4];
|
static float cf[4];
|
||||||
cf[0]=float(cf[0]/255.0); cf[1]=float(c[1]/255.0); cf[2]=float(c[2]/255.0); cf[3]=float(c[3]/255.0);
|
cf[0]=float(cf[0]/255.0); cf[1]=float(c[1]/255.0); cf[2]=float(c[2]/255.0); cf[3]=float(c[3]/255.0);
|
||||||
glLightfv(light,pname,cf);
|
glLightfv(light,pname,cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void glBoxWire(Box3<T> const & b)
|
inline void glBoxWire(Box3<T> const & b)
|
||||||
{
|
{
|
||||||
glPushAttrib(GL_ENABLE_BIT);
|
glPushAttrib(GL_ENABLE_BIT);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glBegin(GL_LINE_STRIP);
|
glBegin(GL_LINE_STRIP);
|
||||||
|
@ -137,13 +137,13 @@ namespace vcg {
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glVertex3f((float)b.min[0],(float)b.min[1],(float)b.min[2]);
|
glVertex3f((float)b.min[0],(float)b.min[1],(float)b.min[2]);
|
||||||
glVertex3f((float)b.min[0],(float)b.min[1],(float)b.max[2]);
|
glVertex3f((float)b.min[0],(float)b.min[1],(float)b.max[2]);
|
||||||
|
|
||||||
glVertex3f((float)b.max[0],(float)b.min[1],(float)b.min[2]);
|
glVertex3f((float)b.max[0],(float)b.min[1],(float)b.min[2]);
|
||||||
glVertex3f((float)b.max[0],(float)b.min[1],(float)b.max[2]);
|
glVertex3f((float)b.max[0],(float)b.min[1],(float)b.max[2]);
|
||||||
|
|
||||||
glVertex3f((float)b.max[0],(float)b.max[1],(float)b.min[2]);
|
glVertex3f((float)b.max[0],(float)b.max[1],(float)b.min[2]);
|
||||||
glVertex3f((float)b.max[0],(float)b.max[1],(float)b.max[2]);
|
glVertex3f((float)b.max[0],(float)b.max[1],(float)b.max[2]);
|
||||||
|
|
||||||
glVertex3f((float)b.min[0],(float)b.max[1],(float)b.min[2]);
|
glVertex3f((float)b.min[0],(float)b.max[1],(float)b.min[2]);
|
||||||
glVertex3f((float)b.min[0],(float)b.max[1],(float)b.max[2]);
|
glVertex3f((float)b.min[0],(float)b.max[1],(float)b.max[2]);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
@ -151,7 +151,7 @@ namespace vcg {
|
||||||
};
|
};
|
||||||
template <class T>
|
template <class T>
|
||||||
/// Funzione di utilita' per la visualizzazione in OpenGL (flat shaded)
|
/// Funzione di utilita' per la visualizzazione in OpenGL (flat shaded)
|
||||||
inline void glBoxFlat(Box3<T> const & b)
|
inline void glBoxFlat(Box3<T> const & b)
|
||||||
{
|
{
|
||||||
glPushAttrib(GL_SHADE_MODEL);
|
glPushAttrib(GL_SHADE_MODEL);
|
||||||
glShadeModel(GL_FLAT);
|
glShadeModel(GL_FLAT);
|
||||||
|
@ -190,10 +190,10 @@ inline void glBoxFlat(Box3<T> const & b)
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
/// Setta i sei clip planes di opengl a far vedere solo l'interno del box
|
/// Setta i sei clip planes di opengl a far vedere solo l'interno del box
|
||||||
inline void glBoxClip(const Box3<T> & b)
|
inline void glBoxClip(const Box3<T> & b)
|
||||||
{
|
{
|
||||||
double eq[4];
|
double eq[4];
|
||||||
eq[0]= 1; eq[1]= 0; eq[2]= 0; eq[3]=(double)-b.min[0];
|
eq[0]= 1; eq[1]= 0; eq[2]= 0; eq[3]=(double)-b.min[0];
|
||||||
glClipPlane(GL_CLIP_PLANE0,eq);
|
glClipPlane(GL_CLIP_PLANE0,eq);
|
||||||
eq[0]=-1; eq[1]= 0; eq[2]= 0; eq[3]=(double) b.max[0];
|
eq[0]=-1; eq[1]= 0; eq[2]= 0; eq[3]=(double) b.max[0];
|
||||||
|
@ -211,8 +211,8 @@ inline void glBoxClip(const Box3<T> & b)
|
||||||
glClipPlane(GL_CLIP_PLANE5,eq);
|
glClipPlane(GL_CLIP_PLANE5,eq);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void glBoxWire(const Box2<T> & b)
|
inline void glBoxWire(const Box2<T> & b)
|
||||||
{
|
{
|
||||||
glPushAttrib(GL_ENABLE_BIT);
|
glPushAttrib(GL_ENABLE_BIT);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glBegin(GL_LINE_LOOP);
|
glBegin(GL_LINE_LOOP);
|
||||||
|
@ -222,7 +222,7 @@ inline void glBoxClip(const Box3<T> & b)
|
||||||
glVertex2f((float)b.max[0],(float)b.max[1]);
|
glVertex2f((float)b.max[0],(float)b.max[1]);
|
||||||
glVertex2f((float)b.min[0],(float)b.max[1]);
|
glVertex2f((float)b.min[0],(float)b.max[1]);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
};
|
};
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -280,8 +280,21 @@ template <class TetraType>
|
||||||
|
|
||||||
#ifdef VCG_USE_EIGEN
|
#ifdef VCG_USE_EIGEN
|
||||||
|
|
||||||
#define _WRAP_EIGEN_XPR(FUNC) template<typename Derived> \
|
template<typename Derived, int Rows=Derived::RowsAtCompileTime, int Cols=Derived::ColsAtCompileTime>
|
||||||
inline void FUNC(const Eigen::MatrixBase<Derived>& p) { FUNC(p.eval()); }
|
struct EvalToKnownPointType;
|
||||||
|
|
||||||
|
template<typename Derived> struct EvalToKnownPointType<Derived,2,1>
|
||||||
|
{ typedef Point2<typename Derived::Scalar> Type; };
|
||||||
|
|
||||||
|
template<typename Derived> struct EvalToKnownPointType<Derived,3,1>
|
||||||
|
{ typedef Point3<typename Derived::Scalar> Type; };
|
||||||
|
|
||||||
|
template<typename Derived> struct EvalToKnownPointType<Derived,4,1>
|
||||||
|
{ typedef Point4<typename Derived::Scalar> Type; };
|
||||||
|
|
||||||
|
#define _WRAP_EIGEN_XPR(FUNC) template<typename Derived> \
|
||||||
|
inline void FUNC(const Eigen::MatrixBase<Derived>& p) { \
|
||||||
|
FUNC(typename EvalToKnownPointType<Derived>::Type(p)); }
|
||||||
|
|
||||||
_WRAP_EIGEN_XPR(glVertex)
|
_WRAP_EIGEN_XPR(glVertex)
|
||||||
_WRAP_EIGEN_XPR(glNormal)
|
_WRAP_EIGEN_XPR(glNormal)
|
||||||
|
|
|
@ -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. *
|
||||||
|
@ -123,8 +123,8 @@ first draft: it includes glew !
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
|
|
||||||
|
|
||||||
// classe base di glwrap usata solo per poter usare i vari drawmode, normalmode senza dover
|
// classe base di glwrap usata solo per poter usare i vari drawmode, normalmode senza dover
|
||||||
// specificare tutto il tipo (a volte lunghissimo)
|
// specificare tutto il tipo (a volte lunghissimo)
|
||||||
// della particolare classe glwrap usata.
|
// della particolare classe glwrap usata.
|
||||||
class GLW
|
class GLW
|
||||||
{
|
{
|
||||||
|
@ -135,17 +135,17 @@ public:
|
||||||
enum TextureMode{TMNone, TMPerVert, TMPerWedge, TMPerWedgeMulti};
|
enum TextureMode{TMNone, TMPerVert, TMPerWedge, TMPerWedgeMulti};
|
||||||
enum Hint {
|
enum Hint {
|
||||||
HNUseTriStrip = 0x0001, // ha bisogno che ci sia la fftopology gia calcolata!
|
HNUseTriStrip = 0x0001, // ha bisogno che ci sia la fftopology gia calcolata!
|
||||||
// HNUseEdgeStrip = 0x0002, //
|
// HNUseEdgeStrip = 0x0002, //
|
||||||
HNUseDisplayList = 0x0004,
|
HNUseDisplayList = 0x0004,
|
||||||
HNCacheDisplayList = 0x0008, // Each mode has its dl;
|
HNCacheDisplayList = 0x0008, // Each mode has its dl;
|
||||||
HNLazyDisplayList = 0x0010, // Display list are generated only when requested
|
HNLazyDisplayList = 0x0010, // Display list are generated only when requested
|
||||||
HNIsTwoManifold = 0x0020, // There is no need to make DetachComplex before .
|
HNIsTwoManifold = 0x0020, // There is no need to make DetachComplex before .
|
||||||
HNUsePerWedgeNormal = 0x0040, //
|
HNUsePerWedgeNormal = 0x0040, //
|
||||||
HNHasFFTopology = 0x0080, // E' l'utente che si preoccupa di tenere aggiornata la topologia ff
|
HNHasFFTopology = 0x0080, // E' l'utente che si preoccupa di tenere aggiornata la topologia ff
|
||||||
HNHasVFTopology = 0x0100, // E' l'utente che si preoccupa di tenere aggiornata la topologia vf
|
HNHasVFTopology = 0x0100, // E' l'utente che si preoccupa di tenere aggiornata la topologia vf
|
||||||
HNHasVertNormal = 0x0200, // E' l'utente che si preoccupa di tenere aggiornata le normali per faccia
|
HNHasVertNormal = 0x0200, // E' l'utente che si preoccupa di tenere aggiornata le normali per faccia
|
||||||
HNHasFaceNormal = 0x0400, // E' l'utente che si preoccupa di tenere aggiornata le normali per vertice
|
HNHasFaceNormal = 0x0400, // E' l'utente che si preoccupa di tenere aggiornata le normali per vertice
|
||||||
HNUseVArray = 0x0800,
|
HNUseVArray = 0x0800,
|
||||||
HNUseLazyEdgeStrip = 0x1000, // Edge Strip are generated only when requested
|
HNUseLazyEdgeStrip = 0x1000, // Edge Strip are generated only when requested
|
||||||
HNUseVBO = 0x2000 // Use Vertex Buffer Object
|
HNUseVBO = 0x2000 // Use Vertex Buffer Object
|
||||||
};
|
};
|
||||||
|
@ -160,7 +160,7 @@ public:
|
||||||
CHAll = 0xff
|
CHAll = 0xff
|
||||||
};
|
};
|
||||||
enum HintParami {
|
enum HintParami {
|
||||||
HNPDisplayListSize =0
|
HNPDisplayListSize =0
|
||||||
};
|
};
|
||||||
enum HintParamf {
|
enum HintParamf {
|
||||||
HNPCreaseAngle =0, // crease angle in radians
|
HNPCreaseAngle =0, // crease angle in radians
|
||||||
|
@ -181,16 +181,16 @@ public:
|
||||||
|
|
||||||
// GL Array Elemet
|
// GL Array Elemet
|
||||||
class GLAElem {
|
class GLAElem {
|
||||||
public :
|
public :
|
||||||
int glmode;
|
int glmode;
|
||||||
int len;
|
int len;
|
||||||
int start;
|
int start;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class MESH_TYPE, bool partial = false , class FACE_POINTER_CONTAINER = std::vector<typename MESH_TYPE::FacePointer> >
|
template <class MESH_TYPE, bool partial = false , class FACE_POINTER_CONTAINER = std::vector<typename MESH_TYPE::FacePointer> >
|
||||||
class GlTrimesh : public GLW
|
class GlTrimesh : public GLW
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -207,7 +207,7 @@ public:
|
||||||
// The parameters of hints
|
// The parameters of hints
|
||||||
int HNParami[8];
|
int HNParami[8];
|
||||||
float HNParamf[8];
|
float HNParamf[8];
|
||||||
|
|
||||||
MESH_TYPE *m;
|
MESH_TYPE *m;
|
||||||
GlTrimesh()
|
GlTrimesh()
|
||||||
{
|
{
|
||||||
|
@ -217,7 +217,7 @@ public:
|
||||||
cdm=DMNone;
|
cdm=DMNone;
|
||||||
ccm=CMNone;
|
ccm=CMNone;
|
||||||
cnm=NMNone;
|
cnm=NMNone;
|
||||||
|
|
||||||
SetHintParamf(HNPCreaseAngle,float(M_PI/5));
|
SetHintParamf(HNPCreaseAngle,float(M_PI/5));
|
||||||
SetHintParamf(HNPZTwist,0.00005f);
|
SetHintParamf(HNPZTwist,0.00005f);
|
||||||
SetHintParamf(HNPPointSize,1.0f);
|
SetHintParamf(HNPPointSize,1.0f);
|
||||||
|
@ -228,12 +228,12 @@ public:
|
||||||
//Delete the VBOs
|
//Delete the VBOs
|
||||||
if(curr_hints&HNUseVBO)
|
if(curr_hints&HNUseVBO)
|
||||||
{
|
{
|
||||||
for(int i=0;i<3;++i)
|
for(int i=0;i<3;++i)
|
||||||
if(glIsBuffer(array_buffers[i]))
|
if(glIsBuffer(array_buffers[i]))
|
||||||
glDeleteBuffersARB(1, (GLuint *)(array_buffers+i));
|
glDeleteBuffersARB(1, (GLuint *)(array_buffers+i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetHintParami(const HintParami hip, const int value)
|
void SetHintParami(const HintParami hip, const int value)
|
||||||
{
|
{
|
||||||
HNParami[hip]=value;
|
HNParami[hip]=value;
|
||||||
|
@ -250,16 +250,16 @@ public:
|
||||||
{
|
{
|
||||||
return HNParamf[hip];
|
return HNParamf[hip];
|
||||||
}
|
}
|
||||||
void SetHint(Hint hn)
|
void SetHint(Hint hn)
|
||||||
{
|
{
|
||||||
curr_hints |= hn;
|
curr_hints |= hn;
|
||||||
}
|
}
|
||||||
void ClearHint(Hint hn)
|
void ClearHint(Hint hn)
|
||||||
{
|
{
|
||||||
curr_hints&=(~hn);
|
curr_hints&=(~hn);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int dl;
|
unsigned int dl;
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
|
|
||||||
DrawMode cdm; // Current DrawMode
|
DrawMode cdm; // Current DrawMode
|
||||||
|
@ -269,7 +269,7 @@ public:
|
||||||
void Update(/*Change c=CHAll*/)
|
void Update(/*Change c=CHAll*/)
|
||||||
{
|
{
|
||||||
if(m==0) return;
|
if(m==0) return;
|
||||||
|
|
||||||
if(curr_hints&HNUseVArray || curr_hints&HNUseVBO)
|
if(curr_hints&HNUseVArray || curr_hints&HNUseVBO)
|
||||||
{
|
{
|
||||||
typename MESH_TYPE::FaceIterator fi;
|
typename MESH_TYPE::FaceIterator fi;
|
||||||
|
@ -285,15 +285,15 @@ void Update(/*Change c=CHAll*/)
|
||||||
{
|
{
|
||||||
if(!glIsBuffer(array_buffers[1]))
|
if(!glIsBuffer(array_buffers[1]))
|
||||||
glGenBuffers(2,(GLuint*)array_buffers);
|
glGenBuffers(2,(GLuint*)array_buffers);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
|
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
|
||||||
glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
|
glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
|
||||||
(char *)&(m->vert[0].P()), GL_STATIC_DRAW_ARB);
|
(char *)&(m->vert[0].P()), GL_STATIC_DRAW_ARB);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]);
|
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]);
|
||||||
glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
|
glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
|
||||||
(char *)&(m->vert[0].N()), GL_STATIC_DRAW_ARB);
|
(char *)&(m->vert[0].N()), GL_STATIC_DRAW_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
|
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
|
||||||
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
|
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
|
||||||
}
|
}
|
||||||
|
@ -316,12 +316,12 @@ void Update(/*Change c=CHAll*/)
|
||||||
// if(!(curr_hints&HNHasVFTopology)) m->VFTopology();
|
// if(!(curr_hints&HNHasVFTopology)) m->VFTopology();
|
||||||
// CreaseWN(*m,MESH_TYPE::scalar_type(GetHintParamf(HNPCreaseAngle)));
|
// CreaseWN(*m,MESH_TYPE::scalar_type(GetHintParamf(HNPCreaseAngle)));
|
||||||
//}
|
//}
|
||||||
//if(C!=0) { // force the recomputation of display list
|
//if(C!=0) { // force the recomputation of display list
|
||||||
// cdm=DMNone;
|
// cdm=DMNone;
|
||||||
// ccm=CMNone;
|
// ccm=CMNone;
|
||||||
// cnm=NMNone;
|
// cnm=NMNone;
|
||||||
//}
|
//}
|
||||||
//if((curr_hints&HNUseVArray) && (curr_hints&HNUseTriStrip))
|
//if((curr_hints&HNUseVArray) && (curr_hints&HNUseTriStrip))
|
||||||
// {
|
// {
|
||||||
// ConvertTriStrip<MESH_TYPE>(*m,TStrip,TStripF,TStripVED,TStripVEI);
|
// ConvertTriStrip<MESH_TYPE>(*m,TStrip,TStripF,TStripVED,TStripVEI);
|
||||||
// }
|
// }
|
||||||
|
@ -420,14 +420,14 @@ void DrawFill()
|
||||||
typename FACE_POINTER_CONTAINER::iterator fp;
|
typename FACE_POINTER_CONTAINER::iterator fp;
|
||||||
|
|
||||||
typename MESH_TYPE::FaceIterator fi;
|
typename MESH_TYPE::FaceIterator fi;
|
||||||
|
|
||||||
|
|
||||||
typename std::vector<typename MESH_TYPE::FaceType*>::iterator fip;
|
typename std::vector<typename MESH_TYPE::FaceType*>::iterator fip;
|
||||||
short curtexname=-1;
|
short curtexname=-1;
|
||||||
|
|
||||||
if(cm == CMPerMesh)
|
if(cm == CMPerMesh)
|
||||||
glColor(m->C());
|
glColor(m->C());
|
||||||
|
|
||||||
if(tm == TMPerWedge || tm == TMPerWedgeMulti )
|
if(tm == TMPerWedge || tm == TMPerWedgeMulti )
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
@ -441,10 +441,10 @@ void DrawFill()
|
||||||
|
|
||||||
if (nm==NMPerVert)
|
if (nm==NMPerVert)
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]);
|
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]);
|
||||||
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
|
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
|
||||||
}
|
}
|
||||||
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
|
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
|
||||||
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
|
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES ,m->fn*3,GL_UNSIGNED_INT, &(*indices.begin()) );
|
glDrawElements(GL_TRIANGLES ,m->fn*3,GL_UNSIGNED_INT, &(*indices.begin()) );
|
||||||
|
@ -458,8 +458,8 @@ void DrawFill()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(curr_hints&HNUseVArray)
|
if(curr_hints&HNUseVArray)
|
||||||
{
|
{
|
||||||
if( (cm==CMNone) || (cm==CMPerMesh) )
|
if( (cm==CMNone) || (cm==CMPerMesh) )
|
||||||
{
|
{
|
||||||
|
@ -469,7 +469,7 @@ void DrawFill()
|
||||||
|
|
||||||
if (nm==NMPerVert)
|
if (nm==NMPerVert)
|
||||||
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0]));
|
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0]));
|
||||||
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->P()[0]));
|
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->P()[0]));
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES ,m->fn*3,GL_UNSIGNED_INT, &(*indices.begin()) );
|
glDrawElements(GL_TRIANGLES ,m->fn*3,GL_UNSIGNED_INT, &(*indices.begin()) );
|
||||||
glDisableClientState (GL_VERTEX_ARRAY);
|
glDisableClientState (GL_VERTEX_ARRAY);
|
||||||
|
@ -480,8 +480,8 @@ void DrawFill()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
||||||
if(curr_hints&HNUseTriStrip)
|
if(curr_hints&HNUseTriStrip)
|
||||||
{
|
{
|
||||||
//if( (nm==NMPerVert) && ((cm==CMNone) || (cm==CMPerMesh)))
|
//if( (nm==NMPerVert) && ((cm==CMNone) || (cm==CMPerMesh)))
|
||||||
// if(curr_hints&HNUseVArray){
|
// if(curr_hints&HNUseVArray){
|
||||||
|
@ -492,7 +492,7 @@ void DrawFill()
|
||||||
// std::vector<GLAElem>::iterator vi;
|
// std::vector<GLAElem>::iterator vi;
|
||||||
// for(vi=TStripVED.begin();vi!=TStripVED.end();++vi)
|
// for(vi=TStripVED.begin();vi!=TStripVED.end();++vi)
|
||||||
// glDrawElements(vi->glmode ,vi->len,GL_UNSIGNED_SHORT,&TStripVEI[vi->start] );
|
// glDrawElements(vi->glmode ,vi->len,GL_UNSIGNED_SHORT,&TStripVEI[vi->start] );
|
||||||
//
|
//
|
||||||
// glDisableClientState (GL_NORMAL_ARRAY );
|
// glDisableClientState (GL_NORMAL_ARRAY );
|
||||||
// glDisableClientState (GL_VERTEX_ARRAY);
|
// glDisableClientState (GL_VERTEX_ARRAY);
|
||||||
// return;
|
// return;
|
||||||
|
@ -519,7 +519,7 @@ void DrawFill()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(partial)
|
if(partial)
|
||||||
fp = face_pointers.begin();
|
fp = face_pointers.begin();
|
||||||
else
|
else
|
||||||
fi = m->face.begin();
|
fi = m->face.begin();
|
||||||
|
@ -537,9 +537,9 @@ void DrawFill()
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
while( (partial)?(fp!=face_pointers.end()):(fi!=m->face.end()))
|
while( (partial)?(fp!=face_pointers.end()):(fi!=m->face.end()))
|
||||||
{
|
{
|
||||||
typename MESH_TYPE::FaceType & f = (partial)?(*(*fp)): *fi;
|
typename MESH_TYPE::FaceType & f = (partial)?(*(*fp)): *fi;
|
||||||
|
@ -551,7 +551,7 @@ void DrawFill()
|
||||||
{
|
{
|
||||||
curtexname=(*fi).WT(0).n();
|
curtexname=(*fi).WT(0).n();
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
if (curtexname >= 0)
|
if (curtexname >= 0)
|
||||||
{
|
{
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
@ -561,10 +561,10 @@ void DrawFill()
|
||||||
{
|
{
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nm == NMPerFace) glNormal(f.cN());
|
if(nm == NMPerFace) glNormal(f.cN());
|
||||||
if(nm == NMPerVert) glNormal(f.V(0)->cN());
|
if(nm == NMPerVert) glNormal(f.V(0)->cN());
|
||||||
if(nm == NMPerWedge)glNormal(f.WN(0));
|
if(nm == NMPerWedge)glNormal(f.WN(0));
|
||||||
|
@ -595,14 +595,14 @@ void DrawFill()
|
||||||
else
|
else
|
||||||
++fi;
|
++fi;
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Basic Point drawing fucntion
|
/// Basic Point drawing fucntion
|
||||||
// works also for mesh with deleted vertices
|
// works also for mesh with deleted vertices
|
||||||
template<NormalMode nm, ColorMode cm>
|
template<NormalMode nm, ColorMode cm>
|
||||||
void DrawPointsBase()
|
void DrawPointsBase()
|
||||||
|
@ -610,12 +610,12 @@ void DrawPointsBase()
|
||||||
typename MESH_TYPE::VertexIterator vi;
|
typename MESH_TYPE::VertexIterator vi;
|
||||||
glBegin(GL_POINTS);
|
glBegin(GL_POINTS);
|
||||||
if(cm==CMPerMesh) glColor(m->C());
|
if(cm==CMPerMesh) glColor(m->C());
|
||||||
|
|
||||||
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())
|
||||||
{
|
{
|
||||||
if(nm==NMPerVert) glNormal((*vi).cN());
|
if(nm==NMPerVert) glNormal((*vi).cN());
|
||||||
if(cm==CMPerVert) glColor((*vi).C());
|
if(cm==CMPerVert) glColor((*vi).C());
|
||||||
glVertex((*vi).P());
|
glVertex((*vi).P());
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
@ -628,27 +628,27 @@ double CameraDistance(){
|
||||||
Point3<typename MESH_TYPE::ScalarType> c=m->bbox.Center();
|
Point3<typename MESH_TYPE::ScalarType> c=m->bbox.Center();
|
||||||
res=mm*c;
|
res=mm*c;
|
||||||
return Norm(res);
|
return Norm(res);
|
||||||
}
|
}
|
||||||
template<NormalMode nm, ColorMode cm>
|
template<NormalMode nm, ColorMode cm>
|
||||||
void DrawPoints()
|
void DrawPoints()
|
||||||
{
|
{
|
||||||
glPointSize(GetHintParamf(HNPPointSize));
|
glPointSize(GetHintParamf(HNPPointSize));
|
||||||
|
|
||||||
float camDist=CameraDistance();
|
float camDist=CameraDistance();
|
||||||
float quadratic[] = { 0.0f, 0.0f, 1.0f/(camDist*camDist) };
|
float quadratic[] = { 0.0f, 0.0f, 1.0f/(camDist*camDist) };
|
||||||
glPointParameterfv( GL_POINT_DISTANCE_ATTENUATION, quadratic );
|
glPointParameterfv( GL_POINT_DISTANCE_ATTENUATION, quadratic );
|
||||||
glPointParameterf( GL_POINT_SIZE_MAX, 16.0f );
|
glPointParameterf( GL_POINT_SIZE_MAX, 16.0f );
|
||||||
glPointParameterf( GL_POINT_SIZE_MIN, 1.0f );
|
glPointParameterf( GL_POINT_SIZE_MIN, 1.0f );
|
||||||
|
|
||||||
if(m->vn!=(int)m->vert.size())
|
if(m->vn!=(int)m->vert.size())
|
||||||
{
|
{
|
||||||
DrawPointsBase<nm,cm>();
|
DrawPointsBase<nm,cm>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perfect case, no deleted stuff,
|
// Perfect case, no deleted stuff,
|
||||||
// draw the vertices using vertex arrays
|
// draw the vertices using vertex arrays
|
||||||
if (nm==NMPerVert)
|
if (nm==NMPerVert)
|
||||||
{
|
{
|
||||||
glEnableClientState (GL_NORMAL_ARRAY);
|
glEnableClientState (GL_NORMAL_ARRAY);
|
||||||
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0]));
|
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0]));
|
||||||
|
@ -658,17 +658,17 @@ void DrawPoints()
|
||||||
glEnableClientState (GL_COLOR_ARRAY);
|
glEnableClientState (GL_COLOR_ARRAY);
|
||||||
glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->C()[0]));
|
glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->C()[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnableClientState (GL_VERTEX_ARRAY);
|
glEnableClientState (GL_VERTEX_ARRAY);
|
||||||
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->P()[0]));
|
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->P()[0]));
|
||||||
|
|
||||||
//glDrawElements(GL_POINTS ,m->vn,GL_UNSIGNED_INT, &(*indices.begin()) );
|
//glDrawElements(GL_POINTS ,m->vn,GL_UNSIGNED_INT, &(*indices.begin()) );
|
||||||
glDrawArrays(GL_POINTS,0,m->vn);
|
glDrawArrays(GL_POINTS,0,m->vn);
|
||||||
|
|
||||||
glDisableClientState (GL_VERTEX_ARRAY);
|
glDisableClientState (GL_VERTEX_ARRAY);
|
||||||
if (nm==NMPerVert) glDisableClientState (GL_NORMAL_ARRAY);
|
if (nm==NMPerVert) glDisableClientState (GL_NORMAL_ARRAY);
|
||||||
if (cm==CMPerVert) glDisableClientState (GL_COLOR_ARRAY);
|
if (cm==CMPerVert) glDisableClientState (GL_COLOR_ARRAY);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,7 +709,7 @@ void DrawFlatWire()
|
||||||
DrawWire<NMPerVert,CMNone>();
|
DrawWire<NMPerVert,CMNone>();
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
//glDepthRange(0,1.0f);
|
//glDepthRange(0,1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <NormalMode nm, ColorMode cm>
|
template <NormalMode nm, ColorMode cm>
|
||||||
void DrawRadar()
|
void DrawRadar()
|
||||||
|
@ -720,7 +720,7 @@ void DrawRadar()
|
||||||
glDepthMask(0);
|
glDepthMask(0);
|
||||||
glDepthRange(ZTWIST,1.0f);
|
glDepthRange(ZTWIST,1.0f);
|
||||||
|
|
||||||
if (cm == CMNone)
|
if (cm == CMNone)
|
||||||
glColor4f(0.2f, 1.0f, 0.4f, 0.2f);
|
glColor4f(0.2f, 1.0f, 0.4f, 0.2f);
|
||||||
// DrawFill<nm,cm,TMNone>();
|
// DrawFill<nm,cm,TMNone>();
|
||||||
Draw<DMFlat,CMNone,TMNone>();
|
Draw<DMFlat,CMNone,TMNone>();
|
||||||
|
@ -760,12 +760,12 @@ void DrawTexture_NPV_TPW2()
|
||||||
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(0).t(0));
|
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(0).t(0));
|
||||||
glNormal((*fi).V(0)->N());
|
glNormal((*fi).V(0)->N());
|
||||||
glVertex((*fi).V(0)->P());
|
glVertex((*fi).V(0)->P());
|
||||||
|
|
||||||
glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(1).t(0));
|
glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(1).t(0));
|
||||||
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(1).t(0));
|
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(1).t(0));
|
||||||
glNormal((*fi).V(1)->N());
|
glNormal((*fi).V(1)->N());
|
||||||
glVertex((*fi).V(1)->P());
|
glVertex((*fi).V(1)->P());
|
||||||
|
|
||||||
glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(2).t(0));
|
glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(2).t(0));
|
||||||
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(2).t(0));
|
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(2).t(0));
|
||||||
glNormal((*fi).V(2)->N());
|
glNormal((*fi).V(2)->N());
|
||||||
|
@ -799,10 +799,10 @@ void DrawWire()
|
||||||
DrawFill<nm,cm,TMNone>();
|
DrawFill<nm,cm,TMNone>();
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
// }
|
// }
|
||||||
//else
|
//else
|
||||||
// {
|
// {
|
||||||
// if(!HasEdges()) ComputeEdges();
|
// if(!HasEdges()) ComputeEdges();
|
||||||
|
|
||||||
//if(cm==CMPerMesh) glColor(m->C());
|
//if(cm==CMPerMesh) glColor(m->C());
|
||||||
//std::vector< MESH_TYPE::VertexType *>::iterator vi;
|
//std::vector< MESH_TYPE::VertexType *>::iterator vi;
|
||||||
//glBegin(GL_LINE_STRIP);
|
//glBegin(GL_LINE_STRIP);
|
||||||
|
@ -818,7 +818,7 @@ void DrawWire()
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//glEnd();
|
//glEnd();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBBox(ColorMode cm)
|
void DrawBBox(ColorMode cm)
|
||||||
|
@ -838,7 +838,7 @@ la mesh non abbia complex (o se li aveva fossero stati detached)
|
||||||
Abbia le normali per faccia normalizzate!!
|
Abbia le normali per faccia normalizzate!!
|
||||||
|
|
||||||
|
|
||||||
Prende una mesh e duplica tutti gli edge le cui normali nelle facce incidenti formano un angolo maggiore
|
Prende una mesh e duplica tutti gli edge le cui normali nelle facce incidenti formano un angolo maggiore
|
||||||
di <angle> (espresso in rad).
|
di <angle> (espresso in rad).
|
||||||
foreach face
|
foreach face
|
||||||
foreach unvisited vert vi
|
foreach unvisited vert vi
|
||||||
|
@ -859,17 +859,17 @@ void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad)
|
||||||
std::vector<GLW::VertToSplit<MESH_TYPE> > SPL;
|
std::vector<GLW::VertToSplit<MESH_TYPE> > SPL;
|
||||||
std::vector<typename MESH_TYPE::VertexType> newvert;
|
std::vector<typename MESH_TYPE::VertexType> newvert;
|
||||||
newvert.reserve(m.fn*3);
|
newvert.reserve(m.fn*3);
|
||||||
// indica se un il vertice z della faccia e' stato processato
|
// indica se un il vertice z della faccia e' stato processato
|
||||||
enum {VISITED_0= MESH_TYPE::FaceType::USER0,
|
enum {VISITED_0= MESH_TYPE::FaceType::USER0,
|
||||||
VISITED_1= MESH_TYPE::FaceType::USER0<<1,
|
VISITED_1= MESH_TYPE::FaceType::USER0<<1,
|
||||||
VISITED_2= MESH_TYPE::FaceType::USER0<<2} ;
|
VISITED_2= MESH_TYPE::FaceType::USER0<<2} ;
|
||||||
int vis[3]={VISITED_0,VISITED_1,VISITED_2};
|
int vis[3]={VISITED_0,VISITED_1,VISITED_2};
|
||||||
|
|
||||||
int _t2=clock();
|
int _t2=clock();
|
||||||
typename MESH_TYPE::FaceIterator fi;
|
typename MESH_TYPE::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()) (*fi).Supervisor_Flags()&= (~(VISITED_0 | VISITED_1 | VISITED_2));
|
if(!(*fi).IsD()) (*fi).Supervisor_Flags()&= (~(VISITED_0 | VISITED_1 | VISITED_2));
|
||||||
|
|
||||||
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)
|
||||||
|
@ -883,7 +883,7 @@ void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad)
|
||||||
GLW::VertToSplit<MESH_TYPE> spl;
|
GLW::VertToSplit<MESH_TYPE> spl;
|
||||||
spl.newp=false;
|
spl.newp=false;
|
||||||
spl.edge=-1;
|
spl.edge=-1;
|
||||||
|
|
||||||
//Primo giro per trovare un bordo da cui partire
|
//Primo giro per trovare un bordo da cui partire
|
||||||
do {
|
do {
|
||||||
he.FlipF();
|
he.FlipF();
|
||||||
|
@ -897,15 +897,15 @@ void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad)
|
||||||
he.FlipE();
|
he.FlipE();
|
||||||
nextf=he.f->F(he.z);
|
nextf=he.f->F(he.z);
|
||||||
typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N();
|
typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N();
|
||||||
if(ps<cosangle) break;
|
if(ps<cosangle) break;
|
||||||
int vz=0;
|
int vz=0;
|
||||||
if(he.v == he.f->V(he.z)) vz=he.z;
|
if(he.v == he.f->V(he.z)) vz=he.z;
|
||||||
if(he.v == he.f->V((he.z+1)%3)) vz=(he.z+1)%3;
|
if(he.v == he.f->V((he.z+1)%3)) vz=(he.z+1)%3;
|
||||||
assert((he.f->Supervisor_Flags() & vis[vz] )==0);
|
assert((he.f->Supervisor_Flags() & vis[vz] )==0);
|
||||||
} while(he!=she);
|
} while(he!=she);
|
||||||
}
|
}
|
||||||
he.FlipE();
|
he.FlipE();
|
||||||
|
|
||||||
she=he;
|
she=he;
|
||||||
newvert.push_back(*(*fi).V(j));
|
newvert.push_back(*(*fi).V(j));
|
||||||
typename MESH_TYPE::vertex_pointer curvert=&newvert.back();
|
typename MESH_TYPE::vertex_pointer curvert=&newvert.back();
|
||||||
|
@ -920,14 +920,14 @@ void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad)
|
||||||
if(he.v == he.f->V(he.z)) spl.z=he.z;
|
if(he.v == he.f->V(he.z)) spl.z=he.z;
|
||||||
if(he.v == he.f->V((he.z+1)%3)) spl.z=(he.z+1)%3;
|
if(he.v == he.f->V((he.z+1)%3)) spl.z=(he.z+1)%3;
|
||||||
assert(spl.z>=0);
|
assert(spl.z>=0);
|
||||||
//VCTRACE(" -- spinning face vert %i Adding spl face %i vert %i\n",
|
//VCTRACE(" -- spinning face vert %i Adding spl face %i vert %i\n",
|
||||||
// he.v-m.vert.begin(), spl.f-m.face.begin(), spl.z );
|
// he.v-m.vert.begin(), spl.f-m.face.begin(), spl.z );
|
||||||
assert((spl.f->Supervisor_Flags() & vis[spl.z] )==0);
|
assert((spl.f->Supervisor_Flags() & vis[spl.z] )==0);
|
||||||
spl.f->Supervisor_Flags() |= vis[spl.z];
|
spl.f->Supervisor_Flags() |= vis[spl.z];
|
||||||
SPL.push_back(spl);
|
SPL.push_back(spl);
|
||||||
spl.newp=false;
|
spl.newp=false;
|
||||||
spl.edge=-1;
|
spl.edge=-1;
|
||||||
if(he.IsBorder()) break;
|
if(he.IsBorder()) break;
|
||||||
nextf=he.f->F(he.z);
|
nextf=he.f->F(he.z);
|
||||||
if(nextf==she.f) break;
|
if(nextf==she.f) break;
|
||||||
typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N();
|
typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N();
|
||||||
|
@ -941,7 +941,7 @@ void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad)
|
||||||
he.FlipF();
|
he.FlipF();
|
||||||
if(spl.newp) spl.edge=he.z;
|
if(spl.newp) spl.edge=he.z;
|
||||||
he.FlipE();
|
he.FlipE();
|
||||||
|
|
||||||
}while(he!=she);
|
}while(he!=she);
|
||||||
}
|
}
|
||||||
assert(SPL.size()==m.fn*3);
|
assert(SPL.size()==m.fn*3);
|
||||||
|
@ -952,9 +952,9 @@ void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad)
|
||||||
(*vsi).f->V((*vsi).z)=(*vsi).v;
|
(*vsi).f->V((*vsi).z)=(*vsi).v;
|
||||||
if((*vsi).newp){
|
if((*vsi).newp){
|
||||||
assert((*vsi).edge>=0 && (*vsi).edge<3);
|
assert((*vsi).edge>=0 && (*vsi).edge<3);
|
||||||
if(!(*vsi).f->IsBorder( (*vsi).edge) )
|
if(!(*vsi).f->IsBorder( (*vsi).edge) )
|
||||||
(*vsi).f->Detach((*vsi).edge);
|
(*vsi).f->Detach((*vsi).edge);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,20 +978,20 @@ void CreaseWN(MESH_TYPE &m, typename MESH_TYPE::scalar_type angle)
|
||||||
}
|
}
|
||||||
|
|
||||||
typename MESH_TYPE::scalar_type cosangle=Cos(angle);
|
typename MESH_TYPE::scalar_type cosangle=Cos(angle);
|
||||||
|
|
||||||
typename MESH_TYPE::FaceIterator fi;
|
typename MESH_TYPE::FaceIterator fi;
|
||||||
|
|
||||||
// Clear the per wedge normals
|
// Clear the per wedge normals
|
||||||
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())
|
||||||
{
|
{
|
||||||
(*fi).WN(0)=MESH_TYPE::vectorial_type(0,0,0);
|
(*fi).WN(0)=MESH_TYPE::vectorial_type(0,0,0);
|
||||||
(*fi).WN(1)=MESH_TYPE::vectorial_type(0,0,0);
|
(*fi).WN(1)=MESH_TYPE::vectorial_type(0,0,0);
|
||||||
(*fi).WN(2)=MESH_TYPE::vectorial_type(0,0,0);
|
(*fi).WN(2)=MESH_TYPE::vectorial_type(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
typename MESH_TYPE::FaceType::vectorial_type nn;
|
typename MESH_TYPE::FaceType::vectorial_type nn;
|
||||||
|
|
||||||
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())
|
||||||
{
|
{
|
||||||
nn=(*fi).cN();
|
nn=(*fi).cN();
|
||||||
for(int i=0;i<3;++i)
|
for(int i=0;i<3;++i)
|
||||||
|
@ -1003,9 +1003,9 @@ void CreaseWN(MESH_TYPE &m, typename MESH_TYPE::scalar_type angle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -352,7 +352,7 @@ void MovableCoordinateFrame::RotateToAlign(const Point3f source, const Point3f d
|
||||||
|
|
||||||
Point3f axis = dest ^ source;
|
Point3f axis = dest ^ source;
|
||||||
float sinangle = axis.Norm();
|
float sinangle = axis.Norm();
|
||||||
float cosangle = dest * source;
|
float cosangle = dest.dot(source);
|
||||||
float angle = math::Atan2(sinangle,cosangle);
|
float angle = math::Atan2(sinangle,cosangle);
|
||||||
|
|
||||||
if( math::Abs(angle) < EPSILON )
|
if( math::Abs(angle) < EPSILON )
|
||||||
|
|
|
@ -417,7 +417,7 @@ namespace io {
|
||||||
{
|
{
|
||||||
raggio = -((*fi).V(0)->P() + (*fi).V(1)->P() + (*fi).V(2)->P()) / 3.0;
|
raggio = -((*fi).V(0)->P() + (*fi).V(1)->P() + (*fi).V(2)->P()) / 3.0;
|
||||||
raggio.Normalize();
|
raggio.Normalize();
|
||||||
if((raggio * (*fi).N()) < limit)
|
if((raggio.dot((*fi).N())) < limit)
|
||||||
Allocator<OpenMeshType>::DeleteFace(m,*fi);
|
Allocator<OpenMeshType>::DeleteFace(m,*fi);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue