Commit 0693c89c authored by CGoGN GIT Supervisor's avatar CGoGN GIT Supervisor

Merge branch 'master' of /home/vanhoey/CGoGN

* 'master' of /home/vanhoey/CGoGN:
  qqs modifs :-)
  added new dependency to package uuid-dev in README
  added howto (in README_ECLIPSE) install CMake Editor in Eclipse
  corrections dans AHEM : _CELL et _ORBIT
  added tests to vector_gen and updated frame
  new naming convention for frames : XYZ instead of TBN
  rename localFrame -> Frame ; move from Utils to Geom namespace
  localFrame.hpp : handling cross product of orthogonal vectors
  Euler angle name conventions used in localFrame
  updated comment for localFrame
parents ab864c18 e00b0f46
Dépendences Linux:
installer les paquets suivants:
cmake libXi-dev libXmu-dev freeglut3-dev libdevil-dev libglew-dev libgmp3-dev libxml2-dev libboost-dev libboost-thread-dev libzip-dev libqt4-help qt4-designer qt4-dev-tools
cmake libXi-dev libXmu-dev freeglut3-dev libdevil-dev libglew-dev libgmp3-dev libxml2-dev libboost-dev libboost-thread-dev libzip-dev libqt4-help qt4-designer qt4-dev-tools uuid-dev
Pour compiler CGoGN:
- aller dans ThirdParty et taper "cmake .", puis make
......
......@@ -52,3 +52,8 @@ Eclipse reconnaîtra désormais les fichiers .frag et .vert.
Pour associer d'autres fichiers au programme GLSLeditor :
- Preferences -> General -> Editors -> File Associations
Dans Preferences -> Shaders Preferences, on peut désormais configurer certaines options liées au shaders.
* Coloration syntaxique des fichiers CMake
- Installer CMakeEditor pour Eclipse en ajoutant l'URL dans Help -> Install New Software ... : http://cmakeed.sourceforge.net/eclipse/
- Installer et redémarrer
- Dans Preferences -> General -> Editors -> File Associations il est possible d'associer les CMakeLists.txt à ce logiciel d'édition
......@@ -149,7 +149,7 @@ void decimate(
while(!finished)
{
CGoGNout << "Countdown : " ;
CGoGNout << std::setprecision(8) << (nbVertices - nbWantedVertices) << "\r" /* flush */ ;
CGoGNout << std::setprecision(8) << (nbVertices - nbWantedVertices) << "\r" << CGoGNflush ;
if(!selector->nextEdge(d)) {
CGoGNout << CGoGNendl << "out" << CGoGNendl ;
......
......@@ -74,15 +74,13 @@ bool exportCTM(typename PFP::MAP& the_map, const typename PFP::TVEC3& position,
/**
* export the map into a PLYPTM file
* @param the_map map to be exported
* @param map map to be exported
* @param filename filename of ply file
* @param position the position container
* @param frame[3] table of 3 vectors representing the local frame
* @param colorPTM[6] function coefficients (6) for each color channel (3)
* @return true
*/
template <typename PFP>
bool exportPLYPTM(typename PFP::MAP& map, const char* filename, const typename PFP::TVEC3& position, const typename PFP::TVEC3 frame[3], const typename PFP::TVEC3 colorPTM[6], const typename PFP::TREAL errL2 = AttributeHandler<typename PFP::REAL>(), const typename PFP::TREAL errLmax = AttributeHandler<typename PFP::REAL>(), const typename PFP::TREAL stdDev = AttributeHandler<typename PFP::REAL>(), const FunctorSelect& good = SelectorTrue()) ;
bool exportPlyPTMgeneric(typename PFP::MAP& map, const char* filename, const typename PFP::TVEC3& position, const FunctorSelect& good = SelectorTrue()) ;
/**
......
This diff is collapsed.
......@@ -222,7 +222,7 @@ void AHEMImporter<PFP>::LoadTopology()
{
// Allocate vertices
AttributeContainer& vxContainer = map->getAttributeContainer(VERTEX_CELL);
AttributeContainer& vxContainer = map->getAttributeContainer(VERTEX);
verticesId = new unsigned int[hdr.meshHdr.vxCount];
......@@ -234,10 +234,10 @@ void AHEMImporter<PFP>::LoadTopology()
// Ensure vertices are created by querying the position attribute
AttributeHandler<typename PFP::VEC3> position = map->template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
AttributeHandler<typename PFP::VEC3> position = map->template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
if (!position.isValid())
position = map->template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
position = map->template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
......@@ -272,7 +272,7 @@ void AHEMImporter<PFP>::LoadTopology()
addedHE[heId].vxIdFrom = prevVx;
addedHE[heId].vxIdTo = verticesId[*ix];
map->setDartEmbedding(VERTEX_ORBIT, d, prevVx);
map->setDartEmbedding(VERTEX, d, prevVx);
d = map->phi1(d);
prevVx = *ix++;
......@@ -286,7 +286,7 @@ void AHEMImporter<PFP>::LoadTopology()
addedHE[heId].vxIdFrom = prevVx;
addedHE[heId].vxIdTo = firstVx;
map->setDartEmbedding(VERTEX_ORBIT, d, prevVx);
map->setDartEmbedding(VERTEX, d, prevVx);
heId++;
}
......@@ -315,10 +315,10 @@ void AHEMImporter<PFP>::LoadTopology()
template <typename PFP>
void AHEMImporter<PFP>::LoadPosition(AHEMAttributeDescriptor* posDescr)
{
AttributeHandler<typename PFP::VEC3> position = map->template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
AttributeHandler<typename PFP::VEC3> position = map->template getAttribute<typename PFP::VEC3>(VERTEX, "position") ;
if (!position.isValid())
position = map->template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
position = map->template addAttribute<typename PFP::VEC3>(VERTEX, "position") ;
f.seekg(posDescr->fileStartOffset, std::ios_base::beg);
......
......@@ -78,10 +78,10 @@ void UniversalLoader<MapType, AttrTypeLoader>::ImportAttribute( MapType& map,
template<typename MapType, typename AttrTypeLoader>
void UniversalLoader<MapType, AttrTypeLoader>::UnpackOnVertex(MapType& map, const unsigned int* verticesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const
{
AttributeHandler<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE>(VERTEX_ORBIT, attrName);
AttributeHandler<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE>(VERTEX, attrName);
if (!attr.isValid())
attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE>(VERTEX_ORBIT, attrName);
attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE>(VERTEX, attrName);
char* p = (char*)buffer;
......@@ -97,10 +97,10 @@ void UniversalLoader<MapType, AttrTypeLoader>::UnpackOnVertex(MapType& map, cons
template<typename MapType, typename AttrTypeLoader>
void UniversalLoader<MapType, AttrTypeLoader>:: UnpackOnFace(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const
{
AttributeHandler<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE>(FACE_ORBIT, attrName);
AttributeHandler<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE>(FACE, attrName);
if (!attr.isValid())
attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE>(FACE_ORBIT, attrName);
attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE>(FACE, attrName);
......@@ -117,10 +117,10 @@ void UniversalLoader<MapType, AttrTypeLoader>:: UnpackOnFace(MapType& map, const
template<typename MapType, typename AttrTypeLoader>
void UniversalLoader<MapType, AttrTypeLoader>:: UnpackOnHE(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const
{
AttributeHandler<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE>(DART_ORBIT, attrName);
AttributeHandler<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE>(DART, attrName);
if (!attr.isValid())
attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE>(DART_ORBIT, attrName);
attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE>(DART, attrName);
......@@ -145,10 +145,10 @@ void UniversalLoader<MapType, AttrTypeLoader>:: UnpackOnHE(MapType& map, const D
template<typename MapType, typename AttrTypeLoader>
void UniversalLoader<MapType, AttrTypeLoader>:: UnpackOnHEFC(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const
{
AttributeHandler<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE>(DART_ORBIT, attrName);
AttributeHandler<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE>(DART, attrName);
if (!attr.isValid())
attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE>(DART_ORBIT, attrName);
attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE>(DART, attrName);
char* p = (char*)buffer;
......
......@@ -24,124 +24,144 @@
namespace CGoGN {
namespace Utils {
namespace Geom {
template<typename PFP>
LocalFrame<PFP>::LocalFrame(const VEC3& T, const VEC3& B, const VEC3& N)
Frame<PFP>::Frame(const VEC3& X, const VEC3& Y, const VEC3& Z)
{
m_T = T ;
m_B = B ;
m_N = N ;
const VEC3 refX(Xx,Xy,Xz) ;
const VEC3 refY(Yx,Yy,Yz) ;
const VEC3 refZ(Zx,Zy,Zz) ;
if (!isDirectOrthoNormalFrame<PFP>(X,Y,Z))
return ;
REAL& alpha = m_EulerAngles[0] ;
REAL& beta = m_EulerAngles[1] ;
REAL& gamma = m_EulerAngles[2] ;
VEC3 lineOfNodes = refZ ^ Z ;
if (lineOfNodes.norm2() < 1e-5) // if Z ~= m_Z
{
lineOfNodes = refX ; // = reference T
alpha = 0 ;
gamma = 0 ;
}
else
{
lineOfNodes.normalize() ;
// angle between reference T and line of nodes
alpha = (refY*lineOfNodes > 0 ? 1 : -1) * std::acos(std::max(std::min(REAL(1.0), refX*lineOfNodes ),REAL(-1.0))) ;
// angle between reference normal and normal
gamma = std::acos(std::max(std::min(REAL(1.0), refZ*Z ),REAL(-1.0))) ; // gamma is always positive because the direction of vector lineOfNodes=(reference normal)^(normal) (around which a rotation of angle beta is done later on) changes depending on the side on which they lay w.r.t eachother.
}
// angle between line of nodes and T
beta = (Y*lineOfNodes > 0 ? -1 : 1) * std::acos(std::max(std::min(REAL(1.0), X*lineOfNodes ),REAL(-1.0))) ;
}
template<typename PFP>
LocalFrame<PFP>::LocalFrame(const VEC3& compressedFrame)
Frame<PFP>::Frame(const VEC3& EulerAngles)
{
const VEC3 T(Tx,Ty,Tz) ;
const VEC3 N(Nx,Ny,Nz) ;
// get known data
const REAL& theta1 = compressedFrame[0] ;
const REAL& phi = compressedFrame[1] ;
const REAL& theta2 = compressedFrame[2] ;
const VEC3 Tprime = rotate<REAL>(N,theta1,T) ;
m_N = rotate<REAL>(Tprime,phi,N) ;
m_T = rotate<REAL>(m_N,theta2,Tprime) ;
m_B = m_N ^ m_T ;
m_EulerAngles = EulerAngles ;
}
template<typename PFP>
typename Geom::Vector<3,typename PFP::REAL> LocalFrame<PFP>::getCompressed() const
void Frame<PFP>::getFrame(VEC3& X, VEC3& Y, VEC3& Z) const
{
VEC3 res ;
const VEC3 T(Tx,Ty,Tz) ;
const VEC3 B(Bx,By,Bz) ;
const VEC3 N(Nx,Ny,Nz) ;
REAL& theta1 = res[0] ;
REAL& phi = res[1] ;
REAL& theta2 = res[2] ;
VEC3 Tprime = N ^ m_N ;
Tprime.normalize() ;
theta1 = (B*Tprime > 0 ? 1 : -1) * std::acos(std::max(std::min(REAL(1.0), T*Tprime ),REAL(-1.0))) ;
phi = std::acos(std::max(std::min(REAL(1.0), N*m_N ),REAL(-1.0))) ; // phi1 is always positive because the direction of vector Tp=N^N1 (around which a rotation of angle phi is done later on) changes depending on the side on which they lay w.r.t eachother.
theta2 = (m_B*Tprime > 0 ? -1 : 1) * std::acos(std::max(std::min(REAL(1.0), m_T*Tprime ),REAL(-1.0))) ;
const VEC3 refX(Xx,Xy,Xz) ;
const VEC3 refZ(Zx,Zy,Zz) ;
return res ;
// get known data
const REAL& alpha = m_EulerAngles[0] ;
const REAL& beta = m_EulerAngles[1] ;
const REAL& gamma = m_EulerAngles[2] ;
const VEC3 lineOfNodes = rotate<REAL>(refZ,alpha,refX) ; // rotation around reference normal of vector T
Z = rotate<REAL>(lineOfNodes,gamma,refZ) ; // rotation around line of nodes of vector N
X = rotate<REAL>(Z,beta,lineOfNodes) ; // rotation around new normal of vector represented by line of nodes
Y = Z ^ X ;
}
template<typename PFP>
bool LocalFrame<PFP>::equals(const Utils::LocalFrame<PFP>& lf, REAL epsilon) const
bool Frame<PFP>::equals(const Geom::Frame<PFP>& lf, REAL epsilon) const
{
VEC3 dT = m_T - lf.getT() ;
VEC3 dB = m_B - lf.getB() ;
VEC3 dN = m_N - lf.getN() ;
return dT.norm2() < epsilon && dB.norm2() < epsilon && dN.norm2() < epsilon ;
return (m_EulerAngles - lf.m_EulerAngles).norm2() < epsilon ;
}
template<typename PFP>
bool LocalFrame<PFP>::operator==(const LocalFrame<PFP>& lf) const
bool Frame<PFP>::operator==(const Frame<PFP>& lf) const
{
return this->equals(lf) ;
}
template<typename PFP>
bool LocalFrame<PFP>::operator!=(const LocalFrame<PFP>& lf) const
bool Frame<PFP>::operator!=(const Frame<PFP>& lf) const
{
return !(this->equals(lf)) ;
}
template<typename PFP>
bool LocalFrame<PFP>::isDirect(REAL epsilon) const
bool isNormalizedFrame(const typename PFP::VEC3& X, const typename PFP::VEC3& Y, const typename PFP::VEC3& Z, typename PFP::REAL epsilon)
{
VEC3 new_B = m_N ^ m_T ; // direct
VEC3 diffs = new_B - m_B ; // differences with existing B
REAL diffNorm = diffs.norm2() ; // Norm of this differences vector
return (diffNorm < epsilon) ; // Verify that this difference is very small
return X.isNormalized(epsilon) && Y.isNormalized(epsilon) && Z.isNormalized(epsilon) ;
}
template<typename PFP>
bool LocalFrame<PFP>::isOrthogonal(REAL epsilon) const
bool isOrthogonalFrame(const typename PFP::VEC3& X, const typename PFP::VEC3& Y, const typename PFP::VEC3& Z, typename PFP::REAL epsilon)
{
return (fabs(m_T * m_B) < epsilon) && (fabs(m_N * m_B) < epsilon) && (fabs(m_T * m_N) < epsilon) ;
return X.isOrthogonal(Y,epsilon) && X.isOrthogonal(Z,epsilon) && Y.isOrthogonal(Z,epsilon) ;
}
template<typename PFP>
bool LocalFrame<PFP>::isNormalized(REAL epsilon) const
bool isDirectFrame(const typename PFP::VEC3& X, const typename PFP::VEC3& Y, const typename PFP::VEC3& Z, typename PFP::REAL epsilon)
{
return (1-epsilon < m_N.norm2() && m_N.norm2() < 1+epsilon)
&& (1-epsilon < m_T.norm2() && m_T.norm2() < 1+epsilon)
&& (1-epsilon < m_B.norm2() && m_B.norm2() < 1+epsilon) ;
typename PFP::VEC3 new_Y = Z ^ X ; // direct
typename PFP::VEC3 diffs = new_Y - Y ; // differences with existing B
typename PFP::REAL diffNorm = diffs.norm2() ; // Norm of this differences vector
return (diffNorm < epsilon) ; // Verify that this difference is very small
}
template<typename PFP>
bool LocalFrame<PFP>::isOrthoNormalDirect(REAL epsilon) const
bool isDirectOrthoNormalFrame(const typename PFP::VEC3& X, const typename PFP::VEC3& Y, const typename PFP::VEC3& Z, typename PFP::REAL epsilon)
{
return isOrthogonal(epsilon) && isNormalized(epsilon) && isDirect(epsilon) ;
if (!isNormalizedFrame<PFP>(X,Y,Z,epsilon))
{
CGoGNerr << "The Frame you want to create and compress is not normalized" << CGoGNendl ;
return false ;
}
if (!isOrthogonalFrame<PFP>(X,Y,Z,epsilon))
{
CGoGNerr << "The Frame you want to create and compress is not orthogonal" << CGoGNendl ;
return false ;
}
if (!isDirectFrame<PFP>(X,Y,Z,epsilon))
{
CGoGNerr << "The Frame you want to create and compress is not direct" << CGoGNendl ;
return false ;
}
return true ;
}
template<typename REAL>
Geom::Vector<3,REAL> carthToSpherical (const Geom::Vector<3,REAL>& carth)
Geom::Vector<3,REAL> cartToSpherical (const Geom::Vector<3,REAL>& cart)
{
Geom::Vector<3,REAL> res ;
const REAL& x = carth[0] ;
const REAL& y = carth[1] ;
const REAL& z = carth[2] ;
const REAL& x = cart[0] ;
const REAL& y = cart[1] ;
const REAL& z = cart[2] ;
REAL& rho = res[0] ;
REAL& theta = res[1] ;
REAL& phi = res[2] ;
rho = carth.norm() ;
rho = cart.norm() ;
theta = ((y < 0) ? -1 : 1) * std::acos(x / REAL(sqrt(x*x + y*y)) ) ;
if (isnan(theta))
theta = 0.0 ;
......@@ -151,7 +171,7 @@ Geom::Vector<3,REAL> carthToSpherical (const Geom::Vector<3,REAL>& carth)
}
template<typename REAL>
Geom::Vector<3,REAL> sphericalToCarth (const Geom::Vector<3,REAL>& sph)
Geom::Vector<3,REAL> sphericalToCart (const Geom::Vector<3,REAL>& sph)
{
Geom::Vector<3,REAL> res ;
......@@ -203,6 +223,6 @@ Geom::Vector<3,REAL> rotate (Geom::Vector<3,REAL> axis, REAL angle, Geom::Vector
return res ;
}
} // Utils
} // Geom
} // CGoGN
......@@ -137,6 +137,22 @@ public:
bool hasNan() const ;
/**
* Tests if the vector is normalized
* @param epsilon tolerated error
* @return true if the given vector has a unit norm +/- epsilon
*/
bool isNormalized(const T& epsilon) const ;
/**
* Tests if current and given vectors are orthogonal
* @param V a vector
* @param epsilon tolerated error
* @return true if orthogonal
*/
bool isOrthogonal(const Vector<DIM,T>& V, const T& epsilon = 1e-5) const ;
/**********************************************/
/* STREAM OPERATORS */
/**********************************************/
......
......@@ -295,6 +295,18 @@ inline bool Vector<DIM,T>::hasNan() const
return false ;
}
template <unsigned int DIM, typename T>
inline bool Vector<DIM,T>::isNormalized(const T& epsilon) const
{
return (1-epsilon < norm2() && norm2() < 1+epsilon) ;
}
template <unsigned int DIM, typename T>
inline bool Vector<DIM,T>::isOrthogonal(const Vector<DIM,T>& V, const T& epsilon) const
{
return (fabs(V * (*this)) < epsilon) ;
}
/**********************************************/
/* STREAM OPERATORS */
/**********************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment