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

@ -345,9 +345,9 @@ class Clustering
{ {
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));
} }

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

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

@ -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 ;
} }
@ -360,21 +360,21 @@ public:
// 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();
@ -495,7 +495,7 @@ 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;
} }
} }
@ -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

@ -135,6 +135,8 @@ namespace math {
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;
} }

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

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

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

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

@ -133,19 +133,19 @@ public:
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>
@ -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;
} }

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

@ -101,7 +101,7 @@ public:
{ {
_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;
} }

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

@ -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)
@ -338,7 +338,7 @@ namespace vcg
{ {
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

@ -194,7 +194,7 @@ public:
**/ **/
/// 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();

View File

@ -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]; data()[0] *= sx;
} data()[1] *= sy;
/// 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 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

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

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