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){
nn=NormalizedNormal(*x.F());
ndiff=nn*on[i++];
ndiff=nn.dot(on[i++]);
if(ndiff<MinCos) MinCos=ndiff;
}
if(Params().QualityCheck){
@ -416,7 +416,7 @@ public:
{
if(Params().NormalCheck){
nn=NormalizedNormal(*x.F());
ndiff=nn*on[i++];
ndiff=nn.dot(on[i++]);
if(ndiff<MinCos) MinCos=ndiff;
}
if(Params().QualityCheck){
@ -542,7 +542,7 @@ static void InitQuadric(TriMeshType &m)
if(!Params().UseArea)
p.Normalize();
p.SetOffset( p.Direction() * (*pf).V(0)->cP());
p.SetOffset( p.Direction().dot((*pf).V(0)->cP()));
// Calcolo quadrica delle facce
q.ByPlane(p);
@ -559,10 +559,10 @@ static void InitQuadric(TriMeshType &m)
// Nota che la lunghezza dell'edge DEVE essere Normalizzata
// 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)
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
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);
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::VertexIterator VertexIterator;
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;
/* class for Parameters */
@ -110,11 +110,11 @@ private:
/* 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,
CoordType&x){
CoordType a = x2-x1, b = x4-x3, c = x3-x1;
x = x1 + a * ( (c^b)*(a^b)) / (a^b).SquaredNorm();
}
void IntersectionLineLine(const CoordType & x1,const CoordType & x2,const CoordType & x3,const CoordType & x4, CoordType&x)
{
CoordType a = x2-x1, b = x4-x3, c = x3-x1;
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);
ScalarType dd = (P->vert[id].P() - B[1]).Norm();
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){
bestv = angle;
best = id;
@ -301,7 +301,7 @@ FourPCS<MeshType>::SelectCoplanarBase(){
B[2] = P->vert[best].P();
//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]);
VertexType * v =0;
ScalarType dist,radius = dtol*4.0;
@ -322,7 +322,7 @@ FourPCS<MeshType>::SelectCoplanarBase(){
return false;
best = -1; bestv=std::numeric_limits<float>::max();
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){
bestv = angle;
best = i;
@ -337,8 +337,8 @@ FourPCS<MeshType>::SelectCoplanarBase(){
std::swap(B[1],B[2]);
IntersectionLineLine(B[0],B[1],B[2],B[3],x);
r1 = (x - B[0])*(B[1]-B[0]) / (B[1]-B[0]).SquaredNorm();
r2 = (x - B[2])*(B[3]-B[2]) / (B[3]-B[2]).SquaredNorm();
r1 = (x - B[0]).dot(B[1]-B[0]) / (B[1]-B[0]).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 )
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]);
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;
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;
fix.push_back(p);
@ -565,7 +565,7 @@ int FourPCS<MeshType>::EvaluateSample(CandiType & fp, CoordType & tp, CoordType
>(*Q,ugridQ,vq,radius, dist );
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
if ( (f0!=f1) && (!ShareEdge(f0,f1))
&& (!ShareVertex(f0,f1)) )
return (vcg::Intersection<FaceType>((*f0),(*f1)));
return (vcg::Intersection_<FaceType>((*f0),(*f1)));
return false;
}

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -101,7 +101,7 @@ class HashedPoint3i : public Point3i
{
public:
const size_t Hash() const
const size_t Hash() const
{
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)
{
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.
n+=f.cN();
n+=f.cN();
cnt++;
}
AverageCell(): p(0,0,0), n(0,0,0),cnt(0){}
@ -139,7 +139,7 @@ class AverageCell
CoordType n;
int cnt;
int id;
CoordType Pos() const
CoordType Pos() const
{
return p/cnt;
}
@ -159,9 +159,9 @@ class AverageColorCell
p+=f.cV(i)->cP();
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.
n+=f.cN();
n+=f.cN();
cnt++;
}
AverageColorCell(): p(0,0,0), n(0,0,0), c(0,0,0),cnt(0){}
@ -170,12 +170,12 @@ class AverageColorCell
CoordType c;
int cnt;
int id;
Color4b Col() const
Color4b Col() const
{
return Color4b(c[0]/cnt,c[1]/cnt,c[2]/cnt,255);
}
CoordType Pos() const
CoordType Pos() const
{
return p/cnt;
}
@ -187,7 +187,7 @@ class AverageColorCell
*/
template<class MeshType, class CellType, bool Selected=true>
class Clustering
{
{
public:
typedef typename MeshType::ScalarType ScalarType;
typedef typename MeshType::CoordType CoordType;
@ -198,7 +198,7 @@ class Clustering
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
// will be merged into two identical but opposite faces.
// will be merged into two identical but opposite faces.
// So in practice:
// 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
@ -207,7 +207,7 @@ class Clustering
class SimpleTri
{
public:
public:
CellType *v[3];
const int ii(int i) const {return *((int *)(&(v[i])));}
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)
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[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;
@ -238,13 +238,13 @@ class Clustering
// 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
// _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
// 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
// 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[2] = Grid.dim[2]/Grid.siz[2];
}
BasicGrid<ScalarType> Grid;
#ifdef _MSC_VER
@ -283,7 +283,7 @@ class Clustering
#endif
STDEXT::hash_map<HashedPoint3i,CellType> GridCell;
void Add(MeshType &m)
{
FaceIterator fi;
@ -300,17 +300,17 @@ class Clustering
Grid.PToIP((*fi).cV(i)->cP(), pi );
st.v[i]=&(GridCell[pi]);
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 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();
TriSet.insert(st);
}
// 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)
{
m.Clear();
@ -339,23 +339,23 @@ class Clustering
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(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
if(!DuplicateFaceParam)
if(!DuplicateFaceParam)
{
CoordType N=vcg::Normal(m.face[i]);
int badOrient=0;
if( N*(*ti).v[0]->n <0) ++badOrient;
if( N*(*ti).v[1]->n <0) ++badOrient;
if( N*(*ti).v[2]->n <0) ++badOrient;
if( N.dot((*ti).v[0]->n) <0) ++badOrient;
if( N.dot((*ti).v[1]->n) <0) ++badOrient;
if( N.dot((*ti).v[2]->n) <0) ++badOrient;
if(badOrient>2)
std::swap(m.face[i].V(0),m.face[i].V(1));
}
i++;
}
}
}; //end class clustering
}; //end class clustering
} // namespace tri
} // namespace vcg

View File

@ -176,7 +176,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT>
dir.Normalize();
//direction of normal inside the mesh
if ((dir*closestNorm)<0)
if ((dir.dot(closestNorm))<0)
dist=-dist;
//the intersection exist
return true;

View File

@ -212,7 +212,7 @@ namespace vcg {
void ComputeAngle()
{
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;
}

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -40,17 +40,17 @@ Revision 1.13 2005/11/17 00:42:03 cignoni
#define _VCG_INERTIA_
/*
The algorithm is based on a three step reduction of the volume integrals
to successively simpler integrals. The algorithm is designed to minimize
the numerical errors that can result from poorly conditioned alignment of
polyhedral faces. It is also designed for efficiency. All required volume
integrals of a polyhedron are computed together during a single walk over
the boundary of the polyhedron; exploiting common subexpressions reduces
The algorithm is based on a three step reduction of the volume integrals
to successively simpler integrals. The algorithm is designed to minimize
the numerical errors that can result from poorly conditioned alignment of
polyhedral faces. It is also designed for efficiency. All required volume
integrals of a polyhedron are computed together during a single walk over
the boundary of the polyhedron; exploiting common subexpressions reduces
floating point operations.
For more information, check out:
Brian Mirtich,
Brian Mirtich,
``Fast and Accurate Computation of Polyhedral Mass Properties,''
journal of graphics tools, volume 1, number 2, 1996
@ -67,7 +67,7 @@ namespace vcg
template <class InertiaMeshType>
class Inertia
{
typedef InertiaMeshType MeshType;
typedef InertiaMeshType MeshType;
typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::VertexPointer VertexPointer;
typedef typename MeshType::VertexIterator VertexIterator;
@ -121,7 +121,7 @@ public:
db = b1 - b0;
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;
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;
C1 = a1 + a0;
@ -180,7 +180,7 @@ void CompFaceIntegrals(FaceType &f)
Faaa = k1 * Paaa;
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*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));
@ -197,13 +197,13 @@ void Compute(MeshType &m)
tri::UpdateNormals<MeshType>::PerFaceNormalized(m);
double nx, ny, nz;
T0 = T1[X] = T1[Y] = T1[Z]
= T2[X] = T2[Y] = T2[Z]
T0 = T1[X] = T1[Y] = T1[Z]
= T2[X] = T2[Y] = T2[Z]
= TP[X] = TP[Y] = TP[Z] = 0;
FaceIterator fi;
for (fi=m.face.begin(); fi!=m.face.end();++fi) if(!(*fi).IsD()) {
FaceType &f=(*fi);
nx = fabs(f.N()[0]);
ny = fabs(f.N()[1]);
nz = fabs(f.N()[2]);
@ -233,12 +233,12 @@ void Compute(MeshType &m)
}
ScalarType Mass()
{
{
return static_cast<ScalarType>(T0);
}
Point3<ScalarType> CenterOfMass()
{
{
Point3<ScalarType> r;
r[X] = T1[X] / 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[Y][Y] -= T0 * (r[Z]*r[Z] + r[X]*r[X]);
J[Z][Z] -= T0 * (r[X]*r[X] + r[Y]*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[Z][X] = J[X][Z] += T0 * r[Z] * r[X];
J[X][Y] = J[Y][X] += T0 * r[X] * r[Y];
J[Y][Z] = J[Z][Y] += T0 * r[Y] * r[Z];
J[Z][X] = J[X][Z] += T0 * r[Z] * r[X];
}
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[Y][Y] -= T0 * (r[Z]*r[Z] + r[X]*r[X]);
J[Z][Z] -= T0 * (r[X]*r[X] + r[Y]*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[Z][X] = J[X][Z] += T0 * r[Z] * r[X];
J[X][Y] = J[Y][X] += T0 * r[X] * r[Y];
J[Y][Z] = J[Z][Y] += T0 * r[Y] * r[Z];
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);
}
bary/=area;
C.SetZero();
// C as covariance of triangle (0,0,0)(1,0,0)(0,1,0)
vcg::Matrix33<ScalarType> C0;
@ -345,9 +345,15 @@ static void Covariance(const MeshType & m, vcg::Point3<ScalarType> & bary, vcg::
const float da = n.Norm();
n/=da*da;
A.SetColumn(0,P1-P0);
A.SetColumn(1,P2-P0);
A.SetColumn(2,n);
#ifndef VCG_USE_EIGEN
A.SetColumn(0, P1-P0);
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;
/* 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;
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())
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. *
* *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -73,12 +73,12 @@ the vertex
namespace vcg {
namespace tri {
/// \ingroup trimesh
/// \ingroup trimesh
/// \headerfile curvature.h vcg/complex/trimesh/update/curvature.h
/// \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.
*/
@ -98,18 +98,18 @@ public:
typedef typename MeshType::CoordType CoordType;
typedef typename CoordType::ScalarType ScalarType;
private:
typedef struct AdjVertex {
VertexType * vert;
float doubleArea;
bool isBorder;
};
public:
/// \brief Compute principal direction and magniuto of curvature.
/*
Compute principal direction and magniuto of curvature as describe in the paper:
@InProceedings{bb33922,
@ -144,10 +144,10 @@ public:
VertexType* tempV;
float totalDoubleAreaSize = 0.0f;
// compute the area of each triangle around the central vertex as well as their total area
do
// compute the area of each triangle around the central vertex as well as their total area
do
{
// this bring the pos to the next triangle counterclock-wise
// this bring the pos to the next triangle counterclock-wise
pos.FlipF();
pos.FlipE();
@ -157,13 +157,13 @@ public:
AdjVertex v;
v.isBorder = pos.IsBorder();
v.vert = tempV;
v.vert = tempV;
v.doubleArea = vcg::DoubleArea(*pos.F());
totalDoubleAreaSize += v.doubleArea;
vertices.push_back(v);
}
while(tempV != firstV);
vertices.push_back(v);
}
while(tempV != firstV);
// compute the weights for the formula computing matrix M
for (int i = 0; i < vertices.size(); ++i) {
@ -190,8 +190,8 @@ public:
M.SetZero();
for (int i = 0; i < vertices.size(); ++i) {
CoordType edge = (central_vertex->cP() - vertices[i].vert->cP());
float curvature = (2.0f * (central_vertex->cN() * edge) ) / edge.SquaredNorm();
CoordType T = (Tp*edge).Normalize();
float curvature = (2.0f * (central_vertex->cN().dot(edge)) ) / edge.SquaredNorm();
CoordType T = (Tp*edge).normalized();
tempMatrix.ExternalProduct(T,T);
M += tempMatrix * weights[i] * curvature ;
}
@ -201,7 +201,7 @@ public:
CoordType e1(1.0f,0.0f,0.0f);
if ((e1 - central_vertex->cN()).SquaredNorm() > (e1 + central_vertex->cN()).SquaredNorm())
W = e1 - central_vertex->cN();
else
else
W = e1 + central_vertex->cN();
W.Normalize();
@ -282,7 +282,7 @@ public:
float Principal_Curvature2 = (3.0f * StMS[1][1]) - StMS[0][0];
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).PD2() = Principal_Direction2;
@ -291,8 +291,8 @@ public:
}
}
}
class AreaData
@ -301,7 +301,7 @@ public:
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
SGP 2004
If pointVSfaceInt==true the covariance is computed by montecarlo sampling on the mesh (faster)
@ -325,11 +325,11 @@ public:
PointsGridType pGrid;
// Fill the grid used
if(pointVSfaceInt){
if(pointVSfaceInt){
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());
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());
} else{ mGrid.Set(m.face.begin(),m.face.end()); }
@ -340,7 +340,7 @@ public:
// sample the neighborhood
if(pointVSfaceInt)
{
{
vcg::tri::GetInSphereVertex<
MeshType,
PointsGridType,std::vector<VertexType*>,
@ -356,25 +356,25 @@ public:
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
// 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){
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;}
}
(*vi).PD1() = eigenvectors.GetColumn( (best+1)%3).Normalize();
(*vi).PD2() = eigenvectors.GetColumn( (best+2)%3).Normalize();
(*vi).PD1() = eigenvectors.GetColumn( (best+1)%3).normalized();
(*vi).PD2() = eigenvectors.GetColumn( (best+2)%3).normalized();
// project them to the plane identified by the normal
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());
(*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());
(*vi).PD2() = rot*(*vi).PD2();
@ -388,26 +388,26 @@ public:
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
- <em> Discrete Differential-Geometry Operators for Triangulated 2-Manifolds Mark Meyer,
Mathieu Desbrun, Peter Schroder, Alan H. Barr VisMath '02, Berlin </em>
*/
static void MeanAndGaussian(MeshType & m)
*/
static void MeanAndGaussian(MeshType & m)
{
assert(HasFFAdjacency(m));
float area0, area1, area2, angle0, angle1, angle2, e01, e12, e20;
FaceIterator fi;
VertexIterator vi;
VertexIterator vi;
typename MeshType::CoordType e01v ,e12v ,e20v;
SimpleTempData<VertContainer, AreaData> TDAreaPtr(m.vert);
SimpleTempData<VertContainer, typename MeshType::CoordType> TDContr(m.vert);
SimpleTempData<VertContainer, AreaData> TDAreaPtr(m.vert);
SimpleTempData<VertContainer, typename MeshType::CoordType> TDContr(m.vert);
vcg::tri::UpdateNormals<MeshType>::PerVertexNormalized(m);
//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) ));
angle1 = math::Abs(Angle( (*fi).P(0)-(*fi).P(1),(*fi).P(2)-(*fi).P(1) ));
angle2 = M_PI-(angle0+angle1);
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 e12 = SquaredDistance( (*fi).V(2)->cP() , (*fi).V(1)->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;
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;
(TDAreaPtr)[(*fi).V(0)].A += area0;
(TDAreaPtr)[(*fi).V(1)].A += area1;
(TDAreaPtr)[(*fi).V(2)].A += area2;
}
else // obtuse
{
{
(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(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() )
{
{
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) ));
angle2 = M_PI-(angle0+angle1);
e01v = ( (*fi).V(1)->cP() - (*fi).V(0)->cP() ) ;
e12v = ( (*fi).V(2)->cP() - (*fi).V(1)->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(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;
(*fi).V(0)->Kg() -= angle0;
(*fi).V(1)->Kg() -= angle1;
(*fi).V(2)->Kg() -= angle2;
for(int i=0;i<3;i++)
{
if(vcg::face::IsBorder((*fi), i))
@ -475,7 +475,7 @@ public:
CoordType e1,e2;
vcg::face::Pos<FaceType> hp(&*fi, i, (*fi).V(i));
vcg::face::Pos<FaceType> hp1=hp;
hp1.FlipV();
e1=hp1.v->cP() - hp.v->cP();
hp1.FlipV();
@ -485,7 +485,7 @@ public:
}
}
}
for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD() /*&& !(*vi).IsB()*/)
{
if((TDAreaPtr)[*vi].A<=std::numeric_limits<ScalarType>::epsilon())
@ -495,30 +495,30 @@ public:
}
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;
}
}
}
/// \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.
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)
{
// VFAdjacency required!
assert(FaceType::HasVFAdjacency());
assert(VertexType::HasVFAdjacency());
VFIteratorType vfi(v);
float A = 0;
v->Kh() = 0;
v->Kg() = 2 * M_PI;
@ -527,7 +527,7 @@ public:
FacePointer f = vfi.F();
int i = vfi.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 ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() ));
float ang2 = M_PI - ang0 - ang1;
@ -544,22 +544,22 @@ public:
A += (s02 * tan(ang0)) / 8.0;
else // non obctuse triangle
A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0;
// gaussian curvature update
v->Kg() -= ang0;
// mean curvature update
ang1 = math::Abs(Angle(f->N(), v1->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 );
}
++vfi;
}
v->Kh() /= 4.0f;
if(norm) {
if(A <= std::numeric_limits<float>::epsilon()) {
v->Kh() = 0;
@ -597,7 +597,7 @@ public:
assert(FaceType::HasFFAdjacency());
assert(FaceType::HasFaceNormal());
typename MeshType::VertexIterator vi;
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
@ -616,7 +616,7 @@ public:
normalized_edge/=edge_length;
Point3<ScalarType> n1 = p.F()->cN();n1.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);
ScalarType beta = math::Asin(n1n2);
m33[0][0] += beta*edge_length*normalized_edge[0]*normalized_edge[0];
@ -645,7 +645,11 @@ public:
ScalarType normal = std::numeric_limits<ScalarType>::min();
int normI = 0;
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 minI = (normI+1)%3;
if(fabs(lambda[maxI]) < fabs(lambda[minI])) std::swap(maxI,minI);

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -109,16 +109,16 @@ namespace vcg {
namespace math {
template <class SCALAR>
template <class SCALAR>
class MagnitudoComparer
{
public:
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 int v) { return sqrtf((float)v); }
inline float Sqrt(const float v) { return sqrtf(v); }
inline float Abs(const float v) { return fabsf(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 Asin(const double v) { return asin(v); }
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){
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){
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... */
#ifndef M_PI
@ -161,8 +163,8 @@ namespace math {
#ifndef SQRT_TWO
#define SQRT_TWO 1.4142135623730950488
#endif
template <class SCALAR>
template <class SCALAR>
inline SCALAR Clamp( const SCALAR & val, const SCALAR& minval, const SCALAR& maxval)
{
if(val < minval) return minval;
@ -191,7 +193,7 @@ template<class T> int IsNAN(T t)
return t != t;
}
#endif
#endif
} // End math namespace
/// a type that stands for "void". Useful for Parameter type of a point.

View File

@ -24,6 +24,8 @@
#ifndef EIGEN_VCGLIB
#define EIGEN_VCGLIB
// TODO enable the vectorization
#define EIGEN_DONT_VECTORIZE
#define EIGEN_MATRIXBASE_PLUGIN <vcg/math/eigen_vcgaddons.h>
#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()
@ -268,22 +251,36 @@ EIGEN_DEPRECATED void SetIdentity()
* \param j the column index
* \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);
};
/** \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
* Set the elements of the <I>i</I>-th row to v[j]
* \param i the row index
* \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());
};
/** \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
* 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(); }
/** \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 h=A[k][l];
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 .
* On output, elements of the input matrix above the diagonal are destroyed.
* \param d returns the eigenvalues of a.
* \param v is a matrix whose columns contain, the normalized eigenvectors
* \param nrot returns the number of Jacobi rotations that were required.
* On output, elements of the input matrix above the diagonal are destroyed.
* \param d returns the eigenvalues of a.
* \param v is a matrix whose columns contain, the normalized eigenvectors
* \param nrot returns the number of Jacobi rotations that were required.
*/
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;
assert(w.RowsNumber()==w.ColumnsNumber());
int dimension = w.RowsNumber();
int j,iq,ip,i;
int j,iq,ip,i;
//assert(w.IsSymmetric());
typename MATRIX_TYPE::ScalarType tresh, theta, tau, t, sm, s, h, g, c;
POINT_TYPE b, z;
typename MATRIX_TYPE::ScalarType tresh, theta, tau, t, sm, s, h, g, c;
POINT_TYPE b, z;
v.SetIdentity();
for (ip=0;ip<dimension;++ip) //Initialize b and d to the diagonal of a.
{
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).
for (ip=0;ip<dimension;++ip) //Initialize b and d to the diagonal of a.
{
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).
}
nrot=0;
for (i=0;i<50;i++)
{
sm=ScalarType(0.0);
nrot=0;
for (i=0;i<50;i++)
{
sm=ScalarType(0.0);
for (ip=0;ip<dimension-1;++ip) // Sum off diagonal elements
{
for (iq=ip+1;iq<dimension;++iq)
sm += fabs(w[ip][iq]);
}
if (sm == ScalarType(0.0)) //The normal return, which relies on quadratic convergence to machine underflow.
{
return;
}
if (i < 4)
tresh=ScalarType(0.2)*sm/(dimension*dimension); //...on the first three sweeps.
else
tresh=ScalarType(0.0); //...thereafter.
for (ip=0;ip<dimension-1;++ip)
{
for (iq=ip+1;iq<dimension;iq++)
{
g=ScalarType(100.0)*fabs(w[ip][iq]);
//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]))
w[ip][iq]=ScalarType(0.0);
else if (fabs(w[ip][iq]) > tresh)
{
h=d[iq]-d[ip];
if ((float)(fabs(h)+g) == (float)fabs(h))
t=(w[ip][iq])/h; //t =1/(2#)
else
{
theta=ScalarType(0.5)*h/(w[ip][iq]); //Equation (11.1.10).
t=ScalarType(1.0)/(fabs(theta)+sqrt(ScalarType(1.0)+theta*theta));
if (theta < ScalarType(0.0)) t = -t;
}
c=ScalarType(1.0)/sqrt(ScalarType(1.0)+t*t);
s=t*c;
tau=s/(ScalarType(1.0)+c);
h=t*w[ip][iq];
z[ip] -= h;
z[iq] += h;
d[ip] -= h;
d[iq] += h;
w[ip][iq]=ScalarType(0.0);
for (j=0;j<=ip-1;j++) { //Case of rotations 1 <= j < p.
for (iq=ip+1;iq<dimension;++iq)
sm += fabs(w[ip][iq]);
}
if (sm == ScalarType(0.0)) //The normal return, which relies on quadratic convergence to machine underflow.
{
return;
}
if (i < 4)
tresh=ScalarType(0.2)*sm/(dimension*dimension); //...on the first three sweeps.
else
tresh=ScalarType(0.0); //...thereafter.
for (ip=0;ip<dimension-1;++ip)
{
for (iq=ip+1;iq<dimension;iq++)
{
g=ScalarType(100.0)*fabs(w[ip][iq]);
//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]))
w[ip][iq]=ScalarType(0.0);
else if (fabs(w[ip][iq]) > tresh)
{
h=d[iq]-d[ip];
if ((float)(fabs(h)+g) == (float)fabs(h))
t=(w[ip][iq])/h; //t =1/(2#)
else
{
theta=ScalarType(0.5)*h/(w[ip][iq]); //Equation (11.1.10).
t=ScalarType(1.0)/(fabs(theta)+sqrt(ScalarType(1.0)+theta*theta));
if (theta < ScalarType(0.0)) t = -t;
}
c=ScalarType(1.0)/sqrt(ScalarType(1.0)+t*t);
s=t*c;
tau=s/(ScalarType(1.0)+c);
h=t*w[ip][iq];
z[ip] -= h;
z[iq] += h;
d[ip] -= h;
d[iq] += h;
w[ip][iq]=ScalarType(0.0);
for (j=0;j<=ip-1;j++) { //Case of rotations 1 <= j < p.
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);
}
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);
}
for (j=0;j<dimension;j++) {
}
for (j=0;j<dimension;j++) {
JacobiRotate<MATRIX_TYPE>(v,s,tau,j,ip,j,iq);
}
++nrot;
}
}
}
for (ip=0;ip<dimension;ip++)
{
b[ip] += z[ip];
d[ip]=b[ip]; //Update d with the sum of ta_pq ,
z[ip]=0.0; //and reinitialize z.
}
}
}
++nrot;
}
}
}
for (ip=0;ip<dimension;ip++)
{
b[ip] += z[ip];
d[ip]=b[ip]; //Update d with the sum of ta_pq ,
z[ip]=0.0; //and reinitialize z.
}
}
};
/*!
* Given the eigenvectors and the eigenvalues as output from JacobiRotate, sorts the eigenvalues
* into descending order, and rearranges the columns of v correspondinlgy.
* Given the eigenvectors and the eigenvalues as output from JacobiRotate, sorts the eigenvalues
* into descending order, and rearranges the columns of v correspondinlgy.
* \param eigenvalues
* \param eigenvector (in columns)
* \param absComparison sort according to the absolute values of the eigenvalues.
@ -180,7 +180,7 @@ namespace vcg
int dimension = eigenvectors.ColumnsNumber();
int i, j, k;
float p,q;
for (i=0; i<dimension-1; i++)
for (i=0; i<dimension-1; i++)
{
if (absComparison)
{
@ -197,16 +197,16 @@ namespace vcg
{
p = eigenvalues[ k=i ];
for (j=i+1; j<dimension; j++)
if (eigenvalues[j] >= p)
if (eigenvalues[j] >= p)
p = eigenvalues[ k=j ];
}
if (k != i)
if (k != i)
{
eigenvalues[k] = eigenvalues[i]; // i.e.
eigenvalues[i] = p; // swaps the value of the elements i-th and k-th
for (j=0; j<dimension; j++)
eigenvalues[k] = eigenvalues[i]; // i.e.
eigenvalues[i] = p; // swaps the value of the elements i-th and k-th
for (j=0; j<dimension; j++)
{
p = eigenvectors[j][i]; // i.e.
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.
template <typename TYPE>
inline static TYPE pythagora(TYPE a, TYPE b)
{
TYPE abs_a = fabs(a);
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));
else
else
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};
template< typename MATRIX_TYPE >
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,
@ -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 V the matrix <I>V</I> (not the transpose <I>V<SUP>T</SUP></I>)
* \param max_iters max iteration number (default = 30).
* \return
* \return
*/
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)
@ -271,20 +271,20 @@ namespace vcg
bool convergence = true;
rv1 = new ScalarType[n];
g = scale = anorm = 0;
g = scale = anorm = 0;
// Householder reduction to bidiagonal form.
for (i=0; i<n; i++)
for (i=0; i<n; i++)
{
l = i+1;
rv1[i] = scale*g;
g = s = scale = 0.0;
if (i < m)
{
for (k = i; k<m; k++)
for (k = i; k<m; k++)
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;
s += A[k][i]*A[k][i];
@ -293,27 +293,27 @@ namespace vcg
g = -sign<ScalarType>( sqrt(s), f );
h = f*g - s;
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];
f = s/h;
for (k=i; k<m; k++)
for (k=i; k<m; k++)
A[k][j] += f*A[k][i];
}
for (k=i; k<m; k++)
for (k=i; k<m; k++)
A[k][i] *= scale;
}
}
W[i] = scale *g;
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]);
if (scale)
if (scale)
{
for (k=l; k<n; k++)
for (k=l; k<n; k++)
{
A[i][k] /= scale;
s += A[i][k]*A[i][k];
@ -322,40 +322,40 @@ namespace vcg
g = -sign<ScalarType>(sqrt(s),f);
h = f*g - s;
A[i][l] = f-g;
for (k=l; k<n; k++)
for (k=l; k<n; k++)
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];
for (k=l; k<n; k++)
for (k=l; k<n; k++)
A[j][k] += s*rv1[k];
}
for (k=l; k<n; k++)
for (k=l; k<n; k++)
A[i][k] *= scale;
}
}
anorm=math::Max( anorm, (fabs(W[i])+fabs(rv1[i])) );
}
// Accumulation of right-hand transformations.
for (i=(n-1); i>=0; i--)
{
for (i=(n-1); i>=0; i--)
{
//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.
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];
for (k=l; k<n; k++)
for (k=l; k<n; k++)
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][i] = 1.0;
@ -363,60 +363,60 @@ namespace vcg
l = i;
}
// 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;
g = W[i];
for (j=l; j<n; j++)
for (j=l; j<n; j++)
A[i][j]=0.0;
if (g)
if (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];
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];
}
for (j=i; j<m; j++)
for (j=i; j<m; j++)
A[j][i] *= g;
}
else
for (j=i; j<m; j++)
}
else
for (j=i; j<m; j++)
A[j][i] = 0.0;
++A[i][i];
}
// Diagonalization of the bidiagonal form: Loop over
// singular values, and over allowed iterations.
for (k=(n-1); k>=0; k--)
{
for (its=1; its<=max_iters; its++)
for (k=(n-1); k>=0; k--)
{
for (its=1; its<=max_iters; its++)
{
flag=1;
for (l=k; l>=0; l--)
{
for (l=k; l>=0; l--)
{
// Test for splitting.
nm=l-1;
nm=l-1;
// Note that rv1[1] is always zero.
if ((double)(fabs(rv1[l])+anorm) == anorm)
if ((double)(fabs(rv1[l])+anorm) == anorm)
{
flag=0;
break;
}
if ((double)(fabs(W[nm])+anorm) == anorm)
if ((double)(fabs(W[nm])+anorm) == anorm)
break;
}
if (flag)
if (flag)
{
c=0.0; //Cancellation of rv1[l], if l > 1.
s=1.0;
for (i=l ;i<=k; i++)
for (i=l ;i<=k; i++)
{
f = s*rv1[i];
rv1[i] = c*rv1[i];
if ((double)(fabs(f)+anorm) == anorm)
if ((double)(fabs(f)+anorm) == anorm)
break;
g = W[i];
h = pythagora<ScalarType>(f,g);
@ -424,7 +424,7 @@ namespace vcg
h = (ScalarType)1.0/h;
c = g*h;
s = -f*h;
for (j=0; j<m; j++)
for (j=0; j<m; j++)
{
y = A[j][nm];
z = A[j][i];
@ -435,10 +435,10 @@ namespace vcg
}
z = W[k];
if (l == k) //Convergence.
{
{
if (z < 0.0) { // Singular value is made nonnegative.
W[k] = -z;
for (j=0; j<n; j++)
for (j=0; j<n; j++)
V[j][k] = -V[j][k];
}
break;
@ -455,9 +455,9 @@ namespace vcg
f = ((y-z)*(y+z) + (g-h)*(g+h))/((ScalarType)2.0*h*y);
g = pythagora<ScalarType>(f,1.0);
f=((x-z)*(x+z) + h*((y/(f+sign(g,f)))-h))/x;
c=s=1.0;
c=s=1.0;
//Next QR transformation:
for (j=l; j<= nm;j++)
for (j=l; j<= nm;j++)
{
i = j+1;
g = rv1[i];
@ -472,7 +472,7 @@ namespace vcg
g = g*c - x*s;
h = y*s;
y *= c;
for (jj=0; jj<n; jj++)
for (jj=0; jj<n; jj++)
{
x = V[jj][j];
z = V[jj][i];
@ -482,7 +482,7 @@ namespace vcg
z = pythagora<ScalarType>(f,h);
W[j] = z;
// Rotation can be arbitrary if z = 0.
if (z)
if (z)
{
z = (ScalarType)1.0/z;
c = f*z;
@ -490,7 +490,7 @@ namespace vcg
}
f = c*g + s*y;
x = c*y - s*g;
for (jj=0; jj<m; jj++)
for (jj=0; jj<m; jj++)
{
y = A[jj][j];
z = A[jj][i];
@ -518,46 +518,46 @@ namespace vcg
*/
// TODO modify the last parameter 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;
assert(U.ColumnsNumber()==V.ColumnsNumber());
int mu = U.RowsNumber();
int mv = V.RowsNumber();
int mu = U.RowsNumber();
int mv = V.RowsNumber();
int n = U.ColumnsNumber();
//ScalarType* u = &U[0][0];
//ScalarType* u = &U[0][0];
//ScalarType* v = &V[0][0];
for (int i=0; i<n; i++)
{
int k = i;
int k = i;
ScalarType p = W[i];
switch (sorting)
{
case SortAscending:
{
for (int j=i+1; j<n; j++)
{
if (W[j] < p)
{
k = j;
p = W[j];
}
{
if (W[j] < p)
{
k = j;
p = W[j];
}
}
break;
}
case SortDescending:
{
for (int j=i+1; j<n; j++)
{
if (W[j] > p)
{
k = j;
p = W[j];
}
{
if (W[j] > p)
{
k = j;
p = W[j];
}
}
break;
}
@ -572,24 +572,24 @@ namespace vcg
//ScalarType* ujk = u + k; // ujk = &U[0][k]
//ScalarType* vji = v + i; // vji = &V[0][i]
//ScalarType* vjk = v + k; // vjk = &V[0][k]
//if (j)
//{
//if (j)
//{
// for(;;) for( ; j!=0; --j, uji+=n, ujk+=n)
// { {
// p = *uji; p = *uji; // i.e.
// *uji = *ujk; *uji = *ujk; // swap( U[s][i], U[s][k] )
// *ujk = p; *ujk = p; //
// if (!(--j)) }
// break;
// uji += n;
// ujk += n;
// }
//}
// break;
// uji += n;
// ujk += n;
// }
//}
for(int s=0; j!=0; ++s, --j)
std::swap(U[s][i], U[s][k]);
j = mv;
//if (j!=0)
//if (j!=0)
//{
// for(;;) for ( ; j!=0; --j, vji+=n, ujk+=n)
// { {
@ -598,7 +598,7 @@ namespace vcg
// *vjk = p; *vjk = p; //
// if (!(--j)) }
// break;
// vji += n;
// vji += 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>.
* 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>)
@ -630,20 +630,20 @@ namespace vcg
ScalarType s;
ScalarType *tmp = new ScalarType[columns_number];
for (j=0; j<columns_number; j++) //Calculate U^T * B.
{
{
s = 0;
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 /= W[j]; //This is the divide by wj .
}
tmp[j]=s;
}
for (j=0;j<columns_number;j++) //Matrix multiply by V to get answer.
{
{
s = 0;
for (jj=0; jj<columns_number; jj++)
for (jj=0; jj<columns_number; jj++)
s += V[j][jj]*tmp[jj];
x[j]=s;
}

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -41,7 +41,7 @@ namespace vcg {
/**
This class represents the common interface for any linear objects.
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)
moltiplication (for a scalar), and two linear elements of
a given type can be summed.
@ -56,7 +56,7 @@ namespace vcg {
class Linear{
public:
typedef T ScalarType;
inline void Zero();
inline void SetZero();
T operator + ( T const & p) const;
T operator - ( T const & p) const;
T operator * ( const ScalarType );

View File

@ -49,21 +49,6 @@ namespace ndim{
/** \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.
* @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 ?
{
typedef Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> _Base;
public:
_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();
v1.Normalize();
}
S dot=(v0*v1);
S dot=v0.dot(v1);
///control if there is no rotation
if (dot>((S)1-epsilon))
{

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -63,7 +63,7 @@ public:
ScalarType a[6]; // Matrice 3x3 simmetrica: a11 a12 a13 a22 a23 a33
ScalarType b[3]; // Vettore r3
ScalarType c; // Fattore scalare (se -1 quadrica nulla)
inline Quadric() { c = -1; }
// Necessari se si utilizza stl microsoft
@ -155,14 +155,14 @@ template <class ResultScalarType>
/* Versione veloce */
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[2]*p[2]*a[5] + p[2]*b[2] + c);
}
// spostare..risolve un sistema 3x3
template<class FLTYPE>
template<class FLTYPE>
bool Gauss33( FLTYPE x[], FLTYPE C[3][3+1] )
{
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
template <class ReturnScalarType>
bool Minimum(Point3<ReturnScalarType> &x)
{
{
ReturnScalarType C[3][4];
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];
@ -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
// Molto + lento
// Molto + lento
template <class ReturnScalarType>
bool MinimumSVD(Point3<ReturnScalarType> &x)
{
{
Matrix33<ReturnScalarType> C;
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];
@ -259,7 +259,7 @@ bool MinimumSVD(Point3<ReturnScalarType> &x)
bool MinimumNew(Point3<ScalarType> &x) const
{
{
ScalarType c0=-b[0]/2;
ScalarType c1=-b[1]/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)
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,
t41,t42,t44,t45,t50,t52,t54,
t56,t21,t23,t37,t64,lambda;
t1 = a[4]*pb.z();
t1 = a[4]*pb.z();
t2 = t1*pa.y();
t4 = a[1]*pb.y();
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;
x = pa*(1.0-lambda)+pb*lambda;
x = pa*(1.0-lambda)+pb*lambda;
return true;
}
void operator *= ( const ScalarType & w ) // Amplifica una quadirca
{
assert( IsValid() );
a[0] *= w;
a[1] *= 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) {
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){
minDist = h+dev;
q = v.P();

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -84,28 +84,28 @@ namespace vcg {
/**
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
operator overloading (* + - ...) is present.
operator overloading (* + - ...) is present.
*/
template <class T>
template <class T>
class Color4 : public Point4<T>
{
typedef Point4<T> Base;
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.
enum ColorConstant {
Black =0xff000000,
Gray =0xff808080,
White =0xffffffff,
Red =0xff0000ff,
Green =0xff00ff00,
Blue =0xffff0000,
Cyan =0xffffff00,
Yellow =0xff00ffff,
Magenta=0xffff00ff,
LightGray =0xffc0c0c0,
LightRed =0xff8080ff,
LightGreen =0xff80ff80,
@ -116,7 +116,7 @@ public:
DarkGreen =0xff004000,
DarkBlue =0xff400000
};
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 ( const Point4<T> &c) :Point4<T>(c) {};
@ -129,26 +129,26 @@ public:
// TODO make sure the types are the same
}
#endif
template <class Q>
template <class Q>
inline void Import(const Color4<Q> & b )
{
Point4<T>::V()[0] = T(b[0]);
Point4<T>::V()[1] = T(b[1]);
Point4<T>::V()[2] = T(b[2]);
Point4<T>::V()[3] = T(b[3]);
(*this)[0] = T(b[0]);
(*this)[1] = T(b[1]);
(*this)[2] = T(b[2]);
(*this)[3] = T(b[3]);
}
template <class Q>
template <class Q>
inline void Import(const Point4<Q> & b )
{
Point4<T>::V()[0] = T(b[0]);
Point4<T>::V()[1] = T(b[1]);
Point4<T>::V()[2] = T(b[2]);
Point4<T>::V()[3] = T(b[3]);
{
(*this)[0] = T(b[0]);
(*this)[1] = T(b[1]);
(*this)[2] = T(b[2]);
(*this)[3] = T(b[3]);
}
template <class Q>
template <class Q>
static inline Color4 Construct( const Color4<Q> & b )
{
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<unsigned char> &b);
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] );
}
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);
/// 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 5: r=v; g=p; b=q; break;
}
Point4<T>::V()[0]=(unsigned char)(255*r);
Point4<T>::V()[1]=(unsigned char)(255*g);
Point4<T>::V()[2]=(unsigned char)(255*b);
Point4<T>::V()[3]=255;
(*this)[0]=(unsigned char)(255*r);
(*this)[1]=(unsigned char)(255*g);
(*this)[2]=(unsigned char)(255*b);
(*this)[3]=255;
// 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
// params:
// params:
// n is the maximum expected value (max of the range)
// 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;
m >>= 1;
}
else m = (m+1)>>1;
else m = (m+1)>>1;
if (r>n-b) r = n-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)
{
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)[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]);
@ -276,7 +276,7 @@ inline void Color4<T>::lerp(const Color4<T> &c0, const Color4<T> &c1, const Colo
template <class T>
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; }
//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)
template <>
#endif
template <>
template <>
inline void Color4<float>::Import(const Color4<unsigned char> &b)
{
(*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)
template <>
#endif
template <>
template <>
inline Color4<unsigned char> Color4<unsigned char>::Construct( const Color4<float> & b )
{
return Color4<unsigned char>(
@ -347,7 +347,7 @@ inline Color4<unsigned char> Color4<unsigned char>::Construct( const Color4<floa
#if !defined(__GNUC__) || (__GNUC__ > 3)
template <>
#endif
template <>
template <>
inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
{
return Color4<float>(
@ -357,7 +357,7 @@ inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
(float)(b[3])/255.0f);
}
//template <class T,class S>
//template <class T,class S>
//inline void Color4<T>::Import(const Color4<S> &b)
//{
// V()[0] = T(b[0]);
@ -369,13 +369,13 @@ inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
template<>
inline Color4<unsigned char>::Color4(Color4<unsigned char>::ColorConstant cc)
{
*((int *)this )= cc;
*((int *)this )= cc;
}
template<>
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)
@ -389,8 +389,8 @@ inline Color4<float> Clamp(Color4<float> &c)
template<>
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)[1])+int(p[1]),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. *
* *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -68,8 +68,8 @@ namespace vcg {
/*@{*/
/**
The templated class for representing a point in 4D space.
The class is templated over the ScalarType class that is used to represent coordinates.
All the usual operator (* + - ...) are defined.
The class is templated over the ScalarType class that is used to represent coordinates.
All the usual operator (* + - ...) are defined.
*/
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
**/
@ -94,15 +94,15 @@ public:
_v[0] = nx; _v[1] = ny; _v[2] = nz; _v[3] = nw;
}
inline Point4 ( const T p[4] )
{
{
_v[0] = p[0]; _v[1]= p[1]; _v[2] = p[2]; _v[3]= p[3];
}
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];
}
inline void Zero()
{
inline void SetZero()
{
_v[0] = _v[1] = _v[2] = _v[3]= 0;
}
template <class Q>
@ -114,7 +114,7 @@ public:
_v[3] = T(b[3]);
}
/// constuctor that imports from different Point4 types
template <class Q>
template <class Q>
static inline Point4 Construct( const Point4<Q> & b )
{
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)
**/
inline const T & operator [] ( const int i ) const
@ -155,7 +155,7 @@ public:
assert(i>=0 && i<4);
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
inline T Ext( const int i ) const
{
@ -163,12 +163,12 @@ public:
else return 0;
}
//@}
//@{
/** @name Linear operators and the likes
**/
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] );
}
inline Point4 operator - ( const Point4 & p) const
@ -208,7 +208,7 @@ public:
return Point4( -_v[0], -_v[1], -_v[2], -_v[3] );
}
inline Point4 VectProd ( const Point4 &x, const Point4 &z ) const
{
{
Point4 res;
const Point4 &y = *this;
@ -223,7 +223,7 @@ public:
return res;
}
//@}
//@{
/** @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];
}
/// Euclidian normalization
/// Euclidian normalization
inline Point4 & Normalize()
{
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)
**/
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];
}
}
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];
@ -292,7 +292,7 @@ public:
(_v[0]>=p._v[0]);
}
//@}
//@{
/** @name Dot products
**/
@ -326,7 +326,7 @@ public:
if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); }
return ( (k0 + k1) + k2 ) +k3;
}
}
//@}
@ -371,7 +371,7 @@ template<class T>
double StableDot ( Point4<T> const & p0, Point4<T> const & p1 )
{
return p0.StableDot(p1);
}
}
typedef Point4<short> Point4s;
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[2]=res[2][mini];
p.SetOffset(c*d/d.Norm());
p.SetOffset(c.dot(d)/d.Norm());
p.SetDirection(d/d.Norm());
return eval;

View File

@ -271,12 +271,12 @@ namespace vcg {
Point3t p21 = p2-p1;
Point3t p20 = p2-p0;
ScalarType delta0_p01 = p10*p1;
ScalarType delta1_p01 = -p10*p0;
ScalarType delta0_p02 = p20*p2;
ScalarType delta2_p02 = -p20*p0;
ScalarType delta1_p12 = p21*p2;
ScalarType delta2_p12 = -p21*p1;
ScalarType delta0_p01 = p10.dot(p1);
ScalarType delta1_p01 = -p10.dot(p0);
ScalarType delta0_p02 = p20.dot(p2);
ScalarType delta2_p02 = -p20.dot(p0);
ScalarType delta1_p12 = p21.dot(p2);
ScalarType delta2_p12 = -p21.dot(p1);
// 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; }
@ -284,10 +284,10 @@ namespace vcg {
else if (delta0_p02<=ScalarType(0.0) && delta1_p12<=ScalarType(0.0)) { witness = p2; }
else
{
ScalarType temp = p10*p2;
ScalarType temp = p10.dot(p2);
ScalarType delta0_p012 = delta0_p01*delta1_p12 + delta2_p12*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
if (delta0_p012<=ScalarType(0.0))
@ -366,10 +366,10 @@ namespace vcg {
typedef typename SEGMENTTYPE::ScalarType T;
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))
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))
return false;
po = sg.P0()*(1-r)+sg.P1() * r;
@ -404,7 +404,7 @@ namespace vcg {
/// intersection between two triangles
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),
t1.P0(0),t1.P0(1),t1.P0(2));
}

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -25,7 +25,7 @@
#define VCG_SPACE_NORMAL_EXTRAPOLATION_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/disjoint_set.h>
#include <vcg/space/box3.h>
@ -57,7 +57,7 @@ namespace vcg
typedef typename vcg::Matrix33<ScalarType> MatrixType;
enum NormalOrientation {IsCorrect=0, MustBeFlipped=1};
private:
/*************************************************
* Inner class definitions
@ -68,10 +68,10 @@ namespace vcg
// Object functor: compute the distance between a vertex and a point
struct VertPointDistanceFunctor
{
inline bool operator()(const VertexType &v, const CoordType &p, ScalarType &d, CoordType &q) const
{
ScalarType distance = vcg::Distance(p, v.P());
if (distance>d)
inline bool operator()(const VertexType &v, const CoordType &p, ScalarType &d, CoordType &q) const
{
ScalarType distance = vcg::Distance(p, v.P());
if (distance>d)
return false;
d = distance;
@ -95,10 +95,10 @@ namespace vcg
// Object functor: compute the distance between a point and the plane
struct PlanePointDistanceFunctor
{
inline bool operator()(const Plane &plane, const CoordType &p, ScalarType &d, CoordType &q) const
{
ScalarType distance = vcg::Distance(p, plane.center);
if (distance>d)
inline bool operator()(const Plane &plane, const CoordType &p, ScalarType &d, CoordType &q) const
{
ScalarType distance = vcg::Distance(p, plane.center);
if (distance>d)
return false;
d = distance;
@ -134,7 +134,7 @@ namespace vcg
VertexPointer vertex;
std::vector< MSTNode* > sons;
};
typedef std::vector< Plane > PlaneContainer;
typedef typename PlaneContainer::iterator PlaneIterator;
@ -155,7 +155,7 @@ namespace vcg
int percentage;
char message[128];
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;
octree_for_planes.Set( begin, end );
@ -182,8 +182,8 @@ namespace vcg
for (unsigned int n=0; n<k; n++)
{
diff = nearest_points[n] - plane->center;
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
covariance_matrix[i][j]+=diff[i]*diff[j];
}
@ -195,10 +195,10 @@ namespace vcg
for (int d=0; d<3; d++)
plane->normal[d] = eigenvectors[d][2];
plane->normal.Normalize();
iter->N() = plane->normal;
iter->N() = plane->normal;
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.
dataset_bb.SetNull();
PlaneIterator ePlane = tangent_planes.end();
@ -215,7 +215,7 @@ namespace vcg
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);
unsigned int kk = k;
PlanePointDistanceFunctor ppdf;
DummyObjectMarker dom;
@ -224,7 +224,7 @@ namespace vcg
for (unsigned int n=0; n<k; n++)
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)
@ -237,7 +237,7 @@ namespace vcg
std::sort( E.begin(), E.end() );
vcg::DisjointSet<Plane> planeset;
for (typename std::vector< Plane >::iterator iPlane=tangent_planes.begin(); iPlane!=ePlane; iPlane++)
planeset.MakeSet( &*iPlane );
@ -261,7 +261,7 @@ namespace vcg
for ( ; iMSTEdge!=eMSTEdge; iMSTEdge++)
{
if (callback!=NULL && (++progress%step)==0 && (percentage=int((progress*100)/mst_size))<100) (callback)(percentage, message);
int u_index = int(iMSTEdge->u->index);
int v_index = int(iMSTEdge->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
VertexIterator iCurrentVertex, iSonVertex;
std::vector< MSTNode > MST(vertex_count);
typename std::vector< Plane >::iterator iFirstPlane = tangent_planes.begin();
typename std::vector< Plane >::iterator iCurrentPlane, iSonPlane;
MSTNode *mst_root;
int r_index = (root_index!=-1)? root_index : rand()*vertex_count/RAND_MAX;
mst_root = &MST[ r_index ];
mst_root->parent = mst_root; //the parent of the root is the root itself
if (orientation==MustBeFlipped)
{
iCurrentVertex = begin;
@ -304,7 +304,7 @@ namespace vcg
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
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();
for ( ; iSon!=eSon; iSon++)
{
@ -316,7 +316,7 @@ namespace vcg
//std::advance((iSonVertex=begin), *iSon);//retrieve the pointer to the Vertex associated to son
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++)
{
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);
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. *
* *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -62,21 +62,21 @@ Revision 1.1 2004/03/16 03:07:38 tarini
namespace vcg {
namespace ndim{
//template <int N, class S>
//template <int N, class S>
//class Point;
/** \addtogroup 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
of any dimensionality.
of any dimensionality.
*/
template <int N, class S>
template <int N, class S>
class Point
{
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
**/
inline Point () { };
// 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
inline S Ext( const int i ) const
{
@ -127,7 +127,7 @@ public:
return p;
}
/// importer for homogeneous points
/// importer for homogeneous points
template <class S2>
inline void ImportHomo( const Point<N-1,S2> & b )
{
@ -137,7 +137,7 @@ public:
_v[N-1] = 1.0;
}
/// constructor for homogeneus point.
/// constructor for homogeneus point.
template <int N2, class S2>
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)**/
inline S & operator [] ( const int i )
@ -162,10 +162,10 @@ public:
assert(i>=0 && i<N);
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 &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 4D point, W() is a separate component)
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
inline void Zero()
inline void SetZero()
{
for(unsigned int ii = 0; ii < Dimension;++ii)
V(ii) = S();
@ -259,7 +259,7 @@ public:
V(ii) *= s;
return *this;
}
inline PointType operator - () const
{
PointType res;
@ -336,7 +336,7 @@ public:
//@{
/** @name Comparison Operators.
/** @name Comparison Operators.
Lexicographic order.
**/
@ -350,10 +350,10 @@ public:
//@{
/** @name
Glocal to Local and viceversa
/** @name
Glocal to Local and viceversa
(provided for uniformity with other spatial classes. trivial for points)
**/
**/
inline PointType LocalToGlobal(ParamType p) const{
return *this; }
@ -372,9 +372,9 @@ public:
template <class S>
template <class S>
class Point2 : public Point<2,S> {
public:
public:
typedef S ScalarType;
typedef Point2 PointType;
using Point<2,S>::_v;
@ -435,13 +435,13 @@ public:
inline Point2 ( const S nv[2] ){
_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]); }
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]); }
inline Point2 operator * ( const S s ) const {
inline Point2 operator * ( const S s ) const {
return Point2( _v[0]*s, _v[1]*s ); }
inline Point2 operator / ( const S s ) const {
@ -499,7 +499,7 @@ public:
inline Point2 & Normalize() {
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; }
return *this;};
@ -507,10 +507,10 @@ public:
if (_v[2]!=0.0) { _v[0] /= W(); W()=1.0; } return *this;};
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 {
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 {
return _v[0] * p._v[1] - _v[1] * p._v[0]; }
@ -519,10 +519,10 @@ public:
return _v[0]+_v[1];}
inline S Max() const {
return math::Max( _v[0], _v[1] ); }
return math::Max( _v[0], _v[1] ); }
inline S Min() const {
return math::Min( _v[0], _v[1] ); }
return math::Min( _v[0], _v[1] ); }
inline int MaxI() const {
return (_v[0] < _v[1]) ? 1:0; };
@ -539,9 +539,9 @@ public:
};
template <typename S>
template <typename S>
class Point3 : public Point<3,S> {
public:
public:
typedef S ScalarType;
typedef Point3<S> PointType;
using Point<3,S>::_v;
@ -576,13 +576,13 @@ public:
inline Point3 ( const S nv[3] ){
_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]); }
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]); }
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 ); }
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]); }
inline PointType & Normalize() {
S n = Norm();
S n = Norm();
if(n!=0.0) {
n=S(1.0)/n;
_v[0]*=n; _v[1]*=n; _v[2]*=n; }
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; }
return *this;};
@ -658,10 +658,10 @@ public:
inline S NormInfinity() const {
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 {
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 {
S t = (*this)*p; /* Area, general formula */
@ -671,10 +671,10 @@ public:
return _v[0]+_v[1]+_v[2];}
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 {
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 {
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(k1), &exp1 );
frexp( double(k2), &exp2 );
if( exp0<exp1 )
if( exp0<exp1 )
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;
}
//@}
};
template <typename S>
template <typename S>
class Point4 : public Point<4,S> {
public:
typedef S ScalarType;
@ -727,13 +727,13 @@ public:
inline Point4 ( const S nv[4] ){
_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] ); }
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] ); }
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 ); }
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; }
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; }
return *this;};
@ -811,10 +811,10 @@ public:
inline S NormInfinity() const {
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 {
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 {
S t = (*this)*p; /* Area, general formula */
@ -824,10 +824,10 @@ public:
return _v[0]+_v[1]+_v[2]+_v[3];}
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 {
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 {
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 )
{
S w = p1*p2;
if(w>1)
if(w>1)
w = 1;
else if(w<-1)
else if(w<-1)
w=-1;
return (S) acos(w);
}
@ -914,14 +914,14 @@ inline S SquaredDistance( Point<N,S> const & p1,Point<N,S> const & p2 )
//template <typename S>
//struct Point2:public Point<2,S>{
// inline Point2(){};
// inline Point2(){};
// inline Point2(Point<2,S> const & p):Point<2,S>(p){} ;
// inline Point2( const S a, const S b):Point<2,S>(a,b){};
//};
//
//template <typename S>
//struct Point3:public Point3<S> {
// inline Point3(){};
// inline Point3(){};
// 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){};
//};
@ -929,7 +929,7 @@ inline S SquaredDistance( Point<N,S> const & p1,Point<N,S> const & p2 )
//
//template <typename S>
//struct Point4:public Point4<S>{
// inline Point4(){};
// inline Point4(){};
// 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){};
//};
@ -942,7 +942,7 @@ typedef Point2<short> Vector2s;
typedef Point2<int> Vector2i;
typedef Point2<float> Vector2f;
typedef Point2<double> Vector2d;
typedef Point3<short> Point3s;
typedef Point3<int> Point3i;
typedef Point3<float> Point3f;
@ -951,8 +951,8 @@ typedef Point3<short> Vector3s;
typedef Point3<int> Vector3i;
typedef Point3<float> Vector3f;
typedef Point3<double> Vector3d;
typedef Point4<short> Point4s;
typedef Point4<int> Point4i;
typedef Point4<float> Point4f;

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -20,282 +20,166 @@
* 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 VCG_USE_EIGEN
#include "deprecated_point2.h"
#else
#ifndef __VCGLIB_POINT2
#define __VCGLIB_POINT2
#include <assert.h>
#include "../math/eigen.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 {
/** \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.
The class is templated over the Scalar class that is used to represent coordinates.
All the usual operator overloading (* + - ...) is present.
*/
template <class P2ScalarType> class Point2
template <class _Scalar> class Point2 : public Eigen::Matrix<_Scalar,2,1>
{
protected:
/// The only data member. Hidden to user.
P2ScalarType _v[2];
typedef Eigen::Matrix<_Scalar,2,1> _Base;
using _Base::coeff;
using _Base::coeffRef;
using _Base::setZero;
using _Base::data;
using _Base::V;
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};
//@{
/** @name Access to Coords.
/** @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 )
inline const Scalar &X() const {return data()[0];}
inline const Scalar &Y() const {return data()[1];}
inline Scalar &X() {return data()[0];}
inline Scalar &Y() {return data()[1];}
inline Scalar & V( const int i )
{
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);
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];
return data()[i];
}
//@}
/// empty constructor (does nothing)
/// empty constructor (does nothing)
inline Point2 () { }
/// x,y constructor
inline Point2 ( const ScalarType nx, const ScalarType ny )
/// x,y constructor
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)
{
_v[0]= p._v[0]; _v[1]= p._v[1];
}
/// copy
inline Point2 & operator =( Point2 const & p)
inline Point2 & Scale( const Scalar sx, const Scalar sy )
{
_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;
data()[0] *= sx;
data()[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
/// 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]);
return (data()[1]!=p.data()[1])?(data()[1]<p.data()[1]):
(data()[0]<p.data()[0]);
}
/// lexical ordering
/// 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]);
return (data()[1]!=p.data()[1])?(data()[1]>p.data()[1]):
(data()[0]>p.data()[0]);
}
/// lexical ordering
/// 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]);
return (data()[1]!=p.data()[1])?(data()[1]< p.data()[1]):
(data()[0]<=p.data()[0]);
}
/// lexical ordering
/// 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]);
return (data()[1]!=p.data()[1])?(data()[1]> p.data()[1]):
(data()[0]>=p.data()[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]);
/// returns the angle with X axis (radiants, in [-PI, +PI] )
inline Scalar Angle() const {
return math::Atan2(data()[1],data()[0]);
}
/// transform the point in cartesian coords into polar coords
inline Point2 & Cartesian2Polar()
{
ScalarType t = Angle();
_v[0] = Norm();
_v[1] = t;
Scalar t = Angle();
data()[0] = this->norm();
data()[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]));
Scalar l = data()[0];
data()[0] = (Scalar)(l*math::Cos(data()[1]));
data()[1] = (Scalar)(l*math::Sin(data()[1]));
return *this;
}
/// rotates the point of an angle (radiants, counterclockwise)
inline Point2 & Rotate( const ScalarType rad )
inline Point2 & Rotate( const Scalar rad )
{
ScalarType t = _v[0];
ScalarType s = math::Sin(rad);
ScalarType c = math::Cos(rad);
Scalar t = data()[0];
Scalar s = math::Sin(rad);
Scalar c = math::Cos(rad);
_v[0] = _v[0]*c - _v[1]*s;
_v[1] = t *s + _v[1]*c;
data()[0] = data()[0]*c - data()[1]*s;
data()[1] = t *s + data()[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
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;
}
/// 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();
data()[0] = b.X(); data()[1] = b.Y();
}
/// constructs a 2D points from an existing one of different type
template <class T>
@ -303,8 +187,6 @@ public:
{
return Point2(b.X(),b.Y());
}
}; // end class definition
@ -314,41 +196,6 @@ 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;
@ -357,3 +204,5 @@ typedef Point2<double> Point2d;
/*@}*/
} // end namespace
#endif
#endif

View File

@ -38,6 +38,17 @@ template<class Scalar> class Point3;
namespace Eigen{
template<typename Scalar>
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 {

View File

@ -51,13 +51,22 @@ namespace vcg
enum DrawMode {DMUser,DMWire,DMSolid} ;
private:
///used to find right trasformation in case of rotation
static void XAxis( vcg::Point3f zero, vcg::Point3f uno, Matrix44f & tr){
///used to find right transformation in case of rotation
static void XAxis(vcg::Point3f zero, vcg::Point3f uno, Matrix44f & tr)
{
#ifndef VCG_USE_EIGEN
tr.SetZero();
*((vcg::Point3f*)&tr[0][0]) = uno-zero;
GetUV(*((vcg::Point3f*)tr[0]),*((vcg::Point3f*)tr[1]),*((vcg::Point3f*)tr[2]));
tr[3][3] = 1.0;
*((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

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -60,7 +60,7 @@ First working version!
#ifndef 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.
#include <vcg/space/triangle3.h>
@ -108,16 +108,16 @@ namespace vcg {
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 glLight(GLenum light, GLenum pname, Color4b const & c) {
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);
inline void glLight(GLenum light, GLenum pname, Color4b const & c) {
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);
glLightfv(light,pname,cf);
}
template <class T>
inline void glBoxWire(Box3<T> const & b)
{
inline void glBoxWire(Box3<T> const & b)
{
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_LIGHTING);
glBegin(GL_LINE_STRIP);
@ -137,13 +137,13 @@ namespace vcg {
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.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.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.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.max[2]);
glEnd();
@ -151,7 +151,7 @@ namespace vcg {
};
template <class T>
/// 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);
glShadeModel(GL_FLAT);
@ -190,10 +190,10 @@ inline void glBoxFlat(Box3<T> const & b)
template <class T>
/// Setta i sei clip planes di opengl a far vedere solo l'interno del box
inline void glBoxClip(const Box3<T> & b)
/// Setta i sei clip planes di opengl a far vedere solo l'interno del box
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];
glClipPlane(GL_CLIP_PLANE0,eq);
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);
}
template <class T>
inline void glBoxWire(const Box2<T> & b)
{
inline void glBoxWire(const Box2<T> & b)
{
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_LIGHTING);
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.min[0],(float)b.max[1]);
glEnd();
glPopAttrib();
};
template <class T>
@ -280,8 +280,21 @@ template <class TetraType>
#ifdef VCG_USE_EIGEN
#define _WRAP_EIGEN_XPR(FUNC) template<typename Derived> \
inline void FUNC(const Eigen::MatrixBase<Derived>& p) { FUNC(p.eval()); }
template<typename Derived, int Rows=Derived::RowsAtCompileTime, int Cols=Derived::ColsAtCompileTime>
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(glNormal)

View File

@ -8,7 +8,7 @@
* \ *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -123,8 +123,8 @@ first draft: it includes glew !
namespace vcg {
// classe base di glwrap usata solo per poter usare i vari drawmode, normalmode senza dover
// specificare tutto il tipo (a volte lunghissimo)
// classe base di glwrap usata solo per poter usare i vari drawmode, normalmode senza dover
// specificare tutto il tipo (a volte lunghissimo)
// della particolare classe glwrap usata.
class GLW
{
@ -135,17 +135,17 @@ public:
enum TextureMode{TMNone, TMPerVert, TMPerWedge, TMPerWedgeMulti};
enum Hint {
HNUseTriStrip = 0x0001, // ha bisogno che ci sia la fftopology gia calcolata!
// HNUseEdgeStrip = 0x0002, //
HNUseDisplayList = 0x0004,
// HNUseEdgeStrip = 0x0002, //
HNUseDisplayList = 0x0004,
HNCacheDisplayList = 0x0008, // Each mode has its dl;
HNLazyDisplayList = 0x0010, // Display list are generated only when requested
HNIsTwoManifold = 0x0020, // There is no need to make DetachComplex before .
HNUsePerWedgeNormal = 0x0040, //
HNLazyDisplayList = 0x0010, // Display list are generated only when requested
HNIsTwoManifold = 0x0020, // There is no need to make DetachComplex before .
HNUsePerWedgeNormal = 0x0040, //
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
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
HNUseVArray = 0x0800,
HNUseVArray = 0x0800,
HNUseLazyEdgeStrip = 0x1000, // Edge Strip are generated only when requested
HNUseVBO = 0x2000 // Use Vertex Buffer Object
};
@ -160,7 +160,7 @@ public:
CHAll = 0xff
};
enum HintParami {
HNPDisplayListSize =0
HNPDisplayListSize =0
};
enum HintParamf {
HNPCreaseAngle =0, // crease angle in radians
@ -181,16 +181,16 @@ public:
// GL Array Elemet
class GLAElem {
public :
public :
int glmode;
int len;
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
{
public:
@ -207,7 +207,7 @@ public:
// The parameters of hints
int HNParami[8];
float HNParamf[8];
MESH_TYPE *m;
GlTrimesh()
{
@ -217,7 +217,7 @@ public:
cdm=DMNone;
ccm=CMNone;
cnm=NMNone;
SetHintParamf(HNPCreaseAngle,float(M_PI/5));
SetHintParamf(HNPZTwist,0.00005f);
SetHintParamf(HNPPointSize,1.0f);
@ -228,12 +228,12 @@ public:
//Delete the VBOs
if(curr_hints&HNUseVBO)
{
for(int i=0;i<3;++i)
for(int i=0;i<3;++i)
if(glIsBuffer(array_buffers[i]))
glDeleteBuffersARB(1, (GLuint *)(array_buffers+i));
}
}
void SetHintParami(const HintParami hip, const int value)
{
HNParami[hip]=value;
@ -250,16 +250,16 @@ public:
{
return HNParamf[hip];
}
void SetHint(Hint hn)
void SetHint(Hint hn)
{
curr_hints |= hn;
}
void ClearHint(Hint hn)
void ClearHint(Hint hn)
{
curr_hints&=(~hn);
}
unsigned int dl;
unsigned int dl;
std::vector<unsigned int> indices;
DrawMode cdm; // Current DrawMode
@ -269,7 +269,7 @@ public:
void Update(/*Change c=CHAll*/)
{
if(m==0) return;
if(curr_hints&HNUseVArray || curr_hints&HNUseVBO)
{
typename MESH_TYPE::FaceIterator fi;
@ -285,15 +285,15 @@ void Update(/*Change c=CHAll*/)
{
if(!glIsBuffer(array_buffers[1]))
glGenBuffers(2,(GLuint*)array_buffers);
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
(char *)&(m->vert[0].P()), GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
(char *)&(m->vert[0].P()), GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]);
glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]);
glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
(char *)&(m->vert[0].N()), GL_STATIC_DRAW_ARB);
}
glVertexPointer(3,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();
// 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;
// ccm=CMNone;
// cnm=NMNone;
//}
//if((curr_hints&HNUseVArray) && (curr_hints&HNUseTriStrip))
//if((curr_hints&HNUseVArray) && (curr_hints&HNUseTriStrip))
// {
// ConvertTriStrip<MESH_TYPE>(*m,TStrip,TStripF,TStripVED,TStripVEI);
// }
@ -420,14 +420,14 @@ void DrawFill()
typename FACE_POINTER_CONTAINER::iterator fp;
typename MESH_TYPE::FaceIterator fi;
typename std::vector<typename MESH_TYPE::FaceType*>::iterator fip;
short curtexname=-1;
if(cm == CMPerMesh)
glColor(m->C());
if(tm == TMPerWedge || tm == TMPerWedgeMulti )
glDisable(GL_TEXTURE_2D);
@ -441,10 +441,10 @@ void DrawFill()
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);
}
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
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) )
{
@ -469,7 +469,7 @@ void DrawFill()
if (nm==NMPerVert)
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()) );
glDisableClientState (GL_VERTEX_ARRAY);
@ -480,8 +480,8 @@ void DrawFill()
}
}
else
if(curr_hints&HNUseTriStrip)
if(curr_hints&HNUseTriStrip)
{
//if( (nm==NMPerVert) && ((cm==CMNone) || (cm==CMPerMesh)))
// if(curr_hints&HNUseVArray){
@ -492,7 +492,7 @@ void DrawFill()
// std::vector<GLAElem>::iterator vi;
// for(vi=TStripVED.begin();vi!=TStripVED.end();++vi)
// glDrawElements(vi->glmode ,vi->len,GL_UNSIGNED_SHORT,&TStripVEI[vi->start] );
//
//
// glDisableClientState (GL_NORMAL_ARRAY );
// glDisableClientState (GL_VERTEX_ARRAY);
// return;
@ -519,7 +519,7 @@ void DrawFill()
}
else
{
if(partial)
if(partial)
fp = face_pointers.begin();
else
fi = m->face.begin();
@ -537,9 +537,9 @@ void DrawFill()
glDisable(GL_TEXTURE_2D);
}
}
glBegin(GL_TRIANGLES);
while( (partial)?(fp!=face_pointers.end()):(fi!=m->face.end()))
{
typename MESH_TYPE::FaceType & f = (partial)?(*(*fp)): *fi;
@ -551,7 +551,7 @@ void DrawFill()
{
curtexname=(*fi).WT(0).n();
glEnd();
if (curtexname >= 0)
{
glEnable(GL_TEXTURE_2D);
@ -561,10 +561,10 @@ void DrawFill()
{
glDisable(GL_TEXTURE_2D);
}
glBegin(GL_TRIANGLES);
}
if(nm == NMPerFace) glNormal(f.cN());
if(nm == NMPerVert) glNormal(f.V(0)->cN());
if(nm == NMPerWedge)glNormal(f.WN(0));
@ -595,14 +595,14 @@ void DrawFill()
else
++fi;
}
glEnd();
}
}
/// Basic Point drawing fucntion
/// Basic Point drawing fucntion
// works also for mesh with deleted vertices
template<NormalMode nm, ColorMode cm>
void DrawPointsBase()
@ -610,12 +610,12 @@ void DrawPointsBase()
typename MESH_TYPE::VertexIterator vi;
glBegin(GL_POINTS);
if(cm==CMPerMesh) glColor(m->C());
for(vi=m->vert.begin();vi!=m->vert.end();++vi)if(!(*vi).IsD())
{
if(nm==NMPerVert) glNormal((*vi).cN());
if(cm==CMPerVert) glColor((*vi).C());
glVertex((*vi).P());
if(nm==NMPerVert) glNormal((*vi).cN());
if(cm==CMPerVert) glColor((*vi).C());
glVertex((*vi).P());
}
glEnd();
}
@ -628,27 +628,27 @@ double CameraDistance(){
Point3<typename MESH_TYPE::ScalarType> c=m->bbox.Center();
res=mm*c;
return Norm(res);
}
}
template<NormalMode nm, ColorMode cm>
void DrawPoints()
{
glPointSize(GetHintParamf(HNPPointSize));
float camDist=CameraDistance();
float quadratic[] = { 0.0f, 0.0f, 1.0f/(camDist*camDist) };
glPointParameterfv( GL_POINT_DISTANCE_ATTENUATION, quadratic );
glPointParameterf( GL_POINT_SIZE_MAX, 16.0f );
glPointParameterf( GL_POINT_SIZE_MIN, 1.0f );
if(m->vn!=(int)m->vert.size())
glPointParameterf( GL_POINT_SIZE_MIN, 1.0f );
if(m->vn!=(int)m->vert.size())
{
DrawPointsBase<nm,cm>();
return;
}
// Perfect case, no deleted stuff,
// draw the vertices using vertex arrays
if (nm==NMPerVert)
if (nm==NMPerVert)
{
glEnableClientState (GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0]));
@ -658,17 +658,17 @@ void DrawPoints()
glEnableClientState (GL_COLOR_ARRAY);
glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->C()[0]));
}
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()) );
glDrawArrays(GL_POINTS,0,m->vn);
glDisableClientState (GL_VERTEX_ARRAY);
if (nm==NMPerVert) glDisableClientState (GL_NORMAL_ARRAY);
if (cm==CMPerVert) glDisableClientState (GL_COLOR_ARRAY);
return;
}
@ -709,7 +709,7 @@ void DrawFlatWire()
DrawWire<NMPerVert,CMNone>();
glPopAttrib();
//glDepthRange(0,1.0f);
}
}
template <NormalMode nm, ColorMode cm>
void DrawRadar()
@ -720,7 +720,7 @@ void DrawRadar()
glDepthMask(0);
glDepthRange(ZTWIST,1.0f);
if (cm == CMNone)
if (cm == CMNone)
glColor4f(0.2f, 1.0f, 0.4f, 0.2f);
// DrawFill<nm,cm,TMNone>();
Draw<DMFlat,CMNone,TMNone>();
@ -760,12 +760,12 @@ void DrawTexture_NPV_TPW2()
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(0).t(0));
glNormal((*fi).V(0)->N());
glVertex((*fi).V(0)->P());
glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(1).t(0));
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(1).t(0));
glNormal((*fi).V(1)->N());
glVertex((*fi).V(1)->P());
glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(2).t(0));
glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(2).t(0));
glNormal((*fi).V(2)->N());
@ -799,10 +799,10 @@ void DrawWire()
DrawFill<nm,cm,TMNone>();
glPopAttrib();
// }
//else
//else
// {
// if(!HasEdges()) ComputeEdges();
//if(cm==CMPerMesh) glColor(m->C());
//std::vector< MESH_TYPE::VertexType *>::iterator vi;
//glBegin(GL_LINE_STRIP);
@ -818,7 +818,7 @@ void DrawWire()
// }
//}
//glEnd();
// }
// }
}
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!!
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).
foreach face
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<typename MESH_TYPE::VertexType> newvert;
newvert.reserve(m.fn*3);
// indica se un il vertice z della faccia e' stato processato
enum {VISITED_0= MESH_TYPE::FaceType::USER0,
// indica se un il vertice z della faccia e' stato processato
enum {VISITED_0= MESH_TYPE::FaceType::USER0,
VISITED_1= MESH_TYPE::FaceType::USER0<<1,
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();
typename MESH_TYPE::FaceIterator fi;
for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()) (*fi).Supervisor_Flags()&= (~(VISITED_0 | VISITED_1 | VISITED_2));
for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD())
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;
spl.newp=false;
spl.edge=-1;
//Primo giro per trovare un bordo da cui partire
do {
he.FlipF();
@ -897,15 +897,15 @@ void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad)
he.FlipE();
nextf=he.f->F(he.z);
typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N();
if(ps<cosangle) break;
if(ps<cosangle) break;
int vz=0;
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;
assert((he.f->Supervisor_Flags() & vis[vz] )==0);
} while(he!=she);
}
he.FlipE();
he.FlipE();
she=he;
newvert.push_back(*(*fi).V(j));
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+1)%3)) spl.z=(he.z+1)%3;
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 );
assert((spl.f->Supervisor_Flags() & vis[spl.z] )==0);
spl.f->Supervisor_Flags() |= vis[spl.z];
SPL.push_back(spl);
spl.newp=false;
spl.edge=-1;
if(he.IsBorder()) break;
if(he.IsBorder()) break;
nextf=he.f->F(he.z);
if(nextf==she.f) break;
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();
if(spl.newp) spl.edge=he.z;
he.FlipE();
}while(he!=she);
}
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;
if((*vsi).newp){
assert((*vsi).edge>=0 && (*vsi).edge<3);
if(!(*vsi).f->IsBorder( (*vsi).edge) )
if(!(*vsi).f->IsBorder( (*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::FaceIterator fi;
// 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(1)=MESH_TYPE::vectorial_type(0,0,0);
(*fi).WN(2)=MESH_TYPE::vectorial_type(0,0,0);
}
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();
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

View File

@ -352,7 +352,7 @@ void MovableCoordinateFrame::RotateToAlign(const Point3f source, const Point3f d
Point3f axis = dest ^ source;
float sinangle = axis.Norm();
float cosangle = dest * source;
float cosangle = dest.dot(source);
float angle = math::Atan2(sinangle,cosangle);
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.Normalize();
if((raggio * (*fi).N()) < limit)
if((raggio.dot((*fi).N())) < limit)
Allocator<OpenMeshType>::DeleteFace(m,*fi);
}