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:
Paolo Cignoni 2008-10-28 00:59:46 +00:00
parent 393ec38d54
commit 7befff7bec
32 changed files with 1150 additions and 913 deletions

View File

@ -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

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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

View File

@ -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;

View File

@ -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;
} }

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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"

View File

@ -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); }

View File

@ -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;
} }

View File

@ -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 );

View File

@ -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);

View File

@ -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))
{ {

View File

@ -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;

View File

@ -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();

View File

@ -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),

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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));
} }

View File

@ -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);
} }
} }
} }

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 )

View File

@ -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);
} }