Commit 3f75f814 authored by untereiner's avatar untereiner

Merge cgogn:~vanhoey/CGoGN

parents ff85b800 4769013a
......@@ -166,6 +166,8 @@ void Viewer::cb_Open()
{
std::string filters("all (*.*);; trian (*.trian);; ctm (*.ctm);; off (*.off);; ply (*.ply)") ;
std::string filename = selectFile("Open Mesh", "", filters) ;
if (filename.empty())
return ;
importMesh(filename) ;
updateGL() ;
......
Pour utiliser Eclipse (testé avec la version Helios & Galileo)
Pour utiliser Eclipse (testé avec la version Helios, Galileo & Indigo)
Faire un nouveau projet C++
Choisir Makefile project -> Empty Project
Choisir Comme "Location": la racine de NewCGoGN
Choisir Toolchains: Linux GCC
* Configurer un projet dans Eclipse :
- Faire un nouveau projet C++
- Choisir Makefile project -> Empty Project
- Choisir Comme "Location": la racine de NewCGoGN
- Choisir Toolchains: Linux GCC
* Compilation avec le petit marteau ;) (l'icone)
Dans les propriétés du projet:
-> C/C++ Build:
Dans la configuration Default | Active:
......@@ -12,14 +14,41 @@ Dans les propriétés du projet:
on peut ensuite ajouter des configurations pour compiler ce que l'on veut
en changeant juste le Build directory:
CGoGNRelease: build/Release (compile la lib en release)
CGoGNDebug: build/Debug (compile la lib en debug)
Apps: build/Apps (compile les exemples et les tutos)
CGoGNRelease: build/Release (compile la lib en release)
CGoGNDebug: build/Debug (compile la lib en debug)
Apps: build/Apps (compile les exemples et les tutos)
Tuto: build/Apps/Tuto (compile les tutos)
etc..
On peut alors compiler avec le petit marteau ;) (l'icone) et choisir avec le bouton droit ce que l'on
veut compiler.
Ceci ajoute dans le repertoire de CGoGN un .project et un .cproject.
* Dépendances inter-projets et autocomplétion
Si le projet X dépend d'un autre projet, alors :
Projet X -> Properties -> Project references : cocher le projet dont il dépend.
* Dépendances de Qt :
Afin d'éviter qu'Eclipse ne rejette les syntaxes Qt (les includes de Qt, les Q_OBJECT, les callbacks) :
- Télécharger le plugin Qt "eclipse-integration" http://qt.nokia.com/developer/eclipse-integration/
- Décompresser l'archive et copier son contenu dans le répertoire d'installation d'Eclipse (plugins et features)
- Relancer Eclipse au moins une fois avec l'option --clean (relecture des répertoires locaux)
Normalement, dans Window->Preferences de Eclipse, Qt apparait dans le menu.
- Y ajouter le répertoire de Qt (/usr/bin sur Debian/Ubuntu) et le répertoire d'include (/usr/include/qt4).
Ensuite, pour chaque projet, ajouter les includes suivants dans Properties -> C/C++ general -> Paths and Symbols
parmi les includes de C++ :
- /usr/include/qt4
- /usr/include/qt4/Qt
- /usr/include/qt4/QtCore
- /usr/include/qt4/QtGui
- /usr/include/qt4/QtOpenGL
REMARQUE : en bas de cette fenêtre, le bouton "Export Settings" permet d'exporter en XML la configuration afin
de l'importer dans les autres projets.
- Pour finir, un petit clic-droit sur le projet -> Index -> Freshen all files et le tour est joué.
* Coloration syntaxique des shaders
- Télécharger et décompresser EclipseShaders : http://sourceforge.net/projects/glshaders/
- Copier les répertoires plugins et features dans le répertoire d'installation eclipse
- Relancer Eclipse au moins une fois avec l'option --clean (relecture des répertoires locaux)
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.
......@@ -674,9 +674,8 @@ bool MeshTablesSurface<PFP>::importPlyPTMgeneric(const std::string& filename, st
* @param attrNames : reference that will be filled with the attribute names ;
* - 1 attrName for geometric position (VEC3)
* - 3 attrNames for local frame (3xVEC3) : Tangent, Bitangent and Normal vector
* - 6 attrNames for the function coefficients (6xVEC3) : 6 RGB coefficients being successively the constants, the linears (v then u) and the quadratics : a0 + a1*v + a2*u + a3*u*v + a4*v^2 + a5*u^2.
* @return bool : success.
* @return bool : success.
* - 6 attrNames for the function coefficients (6xVEC3) : 6 RGB coefficients being successively the quadratic members, the linears and the constants (u then v) : a*u^2 + b*v^2 + c*uv + d*u + e*v +f.
* @return bool : success.
*/
template <typename PFP>
bool MeshTablesSurface<PFP>::importPlyPTM(const std::string& filename, std::vector<std::string>& attrNames)
......
......@@ -114,6 +114,7 @@ bool importMesh(typename PFP::MAP& map, MeshTablesSurface<PFP>& mts)
}
else
{
m.unmark(d);
++nbnm;
}
}
......
......@@ -25,19 +25,48 @@
#ifndef LOCALFRAME_H_
#define LOCALFRAME_H_
#include <cmath>
namespace CGoGN {
namespace Utils {
/**
* Util for rotation of a 3D point (or vector) around a given line (going through the origin) and of a given angle
* @param axis the rotation axis direction
* @param angle the rotation angle
* @param p the point to rotate
*/
template <typename REAL>
Geom::Vector<3,REAL> rotate (Geom::Vector<3,REAL> axis, REAL angle, Geom::Vector<3,REAL> p) ;
/**
* Util for conversion from spherical to carthesian coordinates.
* The spherical coordinates are in radius-longitude-latitude
* @param sph the spherical coordinates
* @return the carthesian coordinates
*/
template<typename REAL>
Geom::Vector<3,REAL> sphericalToCarth (const Geom::Vector<3,REAL>& sph) ;
/**
* Util for conversion from carthesian to spherical coordinates.
* The spherical coordinates are in radius-longitude-latitude
* @param carth the carthesian coordinates
* @return the spherical coordinates
*/
template<typename REAL>
Geom::Vector<3,REAL> carthToSpherical (const Geom::Vector<3,REAL>& carth) ;
/**
* Class for representing a direct local frame composed of 3 orthonormal vectors T (tangent), B (bitangent) and N (normal).
* This class can compress/decompress a local frame, switching from its explicit representation (3 vectors) to its compressed representation (1 vector).
* Usage :
* VEC3 T,B,N ; // current set of orthonormal vectors composing the direct frame.
* LocalFrame<PFP::VEC3> lf(T,B,N) ; // Constructor from explicit expression.
* LocalFrame<PFP> lf(T,B,N) ; // Constructor from explicit expression.
* if (lf.isOrthoNormalDirect()) // test if the frame is Orthogonal, Normalized and Direct
* VEC3 compressed = lf.getCompressed() ; // Extract compressed frame
* LocalFrame<PFP::VEC3> decompressed(compressed) ; // Constructor from implicit (compressed) expression.
* LocalFrame<PFP> decompressed(compressed) ; // Constructor from implicit (compressed) expression.
*
* All formulae were provided by "Représentation compacte d'un repère local", june 14th, 2011 by K. Vanhoey
*/
......@@ -46,7 +75,7 @@ class LocalFrame
{
typedef typename PFP::REAL REAL ;
typedef typename Geom::Vector<2,REAL> VEC2 ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename Geom::Vector<3,REAL> VEC3 ;
private: // fields
/**
......@@ -62,17 +91,20 @@ public: // methods
* @param N the normal vector
*/
LocalFrame(const VEC3& T, const VEC3& B, const VEC3& N) ;
/**
* Constructor from implicit (compressed representation)
* @param compressedFrame an implicit (compressed) version of the local frame
* @param compressedFrame an implicit (compressed) version of the local frame (can be produced by localFrame.getCompressed())
*/
LocalFrame(const VEC3& compressedFrame) ;
~LocalFrame() {} ;
/**
* Returns a compressed version of the current local frame
* A VEC3 is not sufficient to completely define a local frame (if phiN=0, the decompression is not unique).
*/
VEC3 getCompressed() ;
VEC3 getCompressed() const ;
/**
* Tests if the frames are identical
......@@ -80,7 +112,7 @@ public: // methods
* @param epsilon the authorized deviation
* @return true if frames are identical (or deviate less than epsilon)
*/
bool equals(const LocalFrame<PFP>& lf, REAL epsilon = 1e-5) const ;
bool equals(const LocalFrame<PFP>& lf, REAL epsilon = 1e-6) const ;
/**
* Equality of frames
......@@ -100,25 +132,25 @@ public: // methods
* Tests if the frame is direct
* @return true if the frame is direct
*/
bool isDirect() const ;
bool isDirect(REAL epsilon = 1e-7) const ;
/**
* Tests if the frame is orthogonal
* @return true if the frame is orthogonal
*/
bool isOrthogonal() const ;
bool isOrthogonal(REAL epsilon = 1e-5) const ;
/**
* Tests if the frame is normalized
* @return true if the frame is normalized
*/
bool isNormalized() const ;
bool isNormalized(REAL epsilon = 1e-5) const ;
/**
* Tests if the frame is direct, normalized and orthogonal
* @return true if the frame is direct, normalized and orthogonal
*/
bool isOrthoNormalDirect() const ;
bool isOrthoNormalDirect(REAL epsilon = 1e-5) const ;
/**
* @return current tangent vector
......@@ -141,13 +173,33 @@ public: // methods
friend std::ostream& operator<< (std::ostream &out, const LocalFrame& lf) {
out << "T : " << lf.m_T << std::endl ;
out << "B : " << lf.m_B << std::endl ;
out << "N : " << lf.m_N << std::endl ;
out << "N : " << lf.m_N ;
return out ;
} ;
private : // methods
VEC2 carthToSpherical(const VEC3& carth) const ;
VEC3 sphericalToCarth(const VEC2& sph) const ;
private : // private constants
// (T,B,N) can be any orthonormal direct frame
// zeros are not recommended since they can
// generate zero vectors after a dot product
// static const REAL Tx = 0.267261 ;
// static const REAL Ty = 0.534522 ;
// static const REAL Tz = 0.801784 ;
// static const REAL Bx = 0.844416 ;
// static const REAL By = -0.530776 ;
// static const REAL Bz = 0.0723785 ;
// static const REAL Nx = 0.464255 ;
// static const REAL Ny = 0.657695 ;
// static const REAL Nz = -0.593215 ;
static const REAL Tx = 0.0766965 ;
static const REAL Ty = 0.383483 ;
static const REAL Tz = 0.920358 ;
static const REAL Bx = -0.760734 ;
static const REAL By = 0.619202 ;
static const REAL Bz = -0.194606 ;
static const REAL Nx = -0.644516 ;
static const REAL Ny = -0.685222 ;
static const REAL Nz = 0.339219 ;
} ;
} // Utils
......
......@@ -38,47 +38,39 @@ LocalFrame<PFP>::LocalFrame(const VEC3& T, const VEC3& B, const VEC3& N)
template<typename PFP>
LocalFrame<PFP>::LocalFrame(const VEC3& compressedFrame)
{
VEC2 Nspher ;
VEC2 Tspher ;
REAL& thetaN = Nspher[0] ; // known
REAL& phiN = Nspher[1] ; // known
REAL& thetaT = Tspher[0] ; // known
REAL& phiT = Tspher[1] ; // to be decoded
// compute phiT
REAL Den,Nom ;
Den = sin(phiN)*(cos(thetaN)*cos(thetaT) + sin(thetaN)*sin(thetaT)) ; // Based on orthogonality
Nom = cos(phiN) ;
phiT = -atan(Nom/Den) ; // if A==0, atan returns Pi/2
if (phiT < 0.0)
phiT = M_PI + phiT ; // = Pi - |phiT|
// convert to carthesian
m_N = sphericalToCarth(Nspher) ;
m_T = sphericalToCarth(Tspher) ;
// compute B
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 ;
}
template<typename PFP>
typename PFP::VEC3 LocalFrame<PFP>::getCompressed()
typename Geom::Vector<3,typename PFP::REAL> LocalFrame<PFP>::getCompressed() const
{
VEC3 res ;
REAL& thetaN = res[0] ;
REAL& phiN = res[1] ;
REAL& thetaT = res[2] ;
const VEC3 T(Tx,Ty,Tz) ;
const VEC3 B(Bx,By,Bz) ;
const VEC3 N(Nx,Ny,Nz) ;
// convert to spherical coordinates
VEC2 Nspher = carthToSpherical(m_N) ;
VEC2 Tspher = carthToSpherical(m_T) ;
REAL& theta1 = res[0] ;
REAL& phi = res[1] ;
REAL& theta2 = res[2] ;
// extract the three scalars
thetaN = Nspher[0] ;
phiN = Nspher[1] ;
thetaT = Tspher[0] ;
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))) ;
return res ;
}
......@@ -106,77 +98,74 @@ bool LocalFrame<PFP>::operator!=(const LocalFrame<PFP>& lf) const
}
template<typename PFP>
bool LocalFrame<PFP>::isDirect() const
bool LocalFrame<PFP>::isDirect(REAL epsilon) const
{
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 < 1e-10) ; // Verify that this difference is very small
return (diffNorm < epsilon) ; // Verify that this difference is very small
}
template<typename PFP>
bool LocalFrame<PFP>::isOrthogonal() const
bool LocalFrame<PFP>::isOrthogonal(REAL epsilon) const
{
return (fabs(m_T * m_B) < 1e-5) && (fabs(m_N * m_B) < 1e-5) && (fabs(m_T * m_N) < 1e-5) ;
return (fabs(m_T * m_B) < epsilon) && (fabs(m_N * m_B) < epsilon) && (fabs(m_T * m_N) < epsilon) ;
}
template<typename PFP>
bool LocalFrame<PFP>::isNormalized() const
bool LocalFrame<PFP>::isNormalized(REAL epsilon) const
{
return (1-1e-5 < m_N.norm2() && m_N.norm2() < 1+1e-5)
&& (1-1e-5 < m_T.norm2() && m_T.norm2() < 1+1e-5)
&& (1-1e-5 < m_B.norm2() && m_B.norm2() < 1+1e-5) ;
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) ;
}
template<typename PFP>
bool LocalFrame<PFP>::isOrthoNormalDirect() const
bool LocalFrame<PFP>::isOrthoNormalDirect(REAL epsilon) const
{
return isOrthogonal() && isNormalized() && isDirect() ;
return isOrthogonal(epsilon) && isNormalized(epsilon) && isDirect(epsilon) ;
}
template<typename PFP>
typename Geom::Vector<2,typename PFP::REAL> LocalFrame<PFP>::carthToSpherical (const VEC3& carth) const
template<typename REAL>
Geom::Vector<3,REAL> carthToSpherical (const Geom::Vector<3,REAL>& carth)
{
VEC2 res ;
Geom::Vector<3,REAL> res ;
const REAL& x = carth[0] ;
const REAL& y = carth[1] ;
const REAL& z = carth[2] ;
REAL& theta = res[0] ;
REAL& phi = res[1] ;
REAL& rho = res[0] ;
REAL& theta = res[1] ;
REAL& phi = res[2] ;
phi = acos(z) ;
const REAL sinphi = sin(phi) ;
if (sinphi == 0.0)
rho = carth.norm() ;
theta = ((y < 0) ? -1 : 1) * std::acos(x / REAL(sqrt(x*x + y*y)) ) ;
if (isnan(theta))
theta = 0.0 ;
else
theta = ((y > 0) ? 1 : -1) * acos(std::min(REAL(1.0),std::max(REAL(-1.0),x / sinphi))) ;
assert (-(M_PI+0.000001) <= theta && theta <= M_PI+0.000001) ;
assert (-0.000001 < phi && phi <= M_PI+0.000001) ;
assert (!isnan(theta) || !"carthToSpherical : Theta is NaN !") ;
assert (!isnan(phi) || !"carthToSpherical : Phi is NaN !") ;
phi = std::asin(z) ;
return res ;
}
template<typename PFP>
typename PFP::VEC3 LocalFrame<PFP>::sphericalToCarth (const VEC2& sph) const
template<typename REAL>
Geom::Vector<3,REAL> sphericalToCarth (const Geom::Vector<3,REAL>& sph)
{
VEC3 res ;
Geom::Vector<3,REAL> res ;
const REAL& theta = sph[0] ;
const REAL& phi = sph[1] ;
const REAL& rho = sph[0] ;
const REAL& theta = sph[1] ;
const REAL& phi = sph[2] ;
REAL& x = res[0] ;
REAL& y = res[1] ;
REAL& z = res[2] ;
x = cos(theta)*sin(phi) ;
y = sin(theta)*sin(phi) ;
z = cos(phi) ;
x = rho*cos(theta)*cos(phi) ;
y = rho*sin(theta)*cos(phi) ;
z = rho*sin(phi) ;
assert(-1.000001 < x && x < 1.000001) ;
assert(-1.000001 < y && y < 1.000001) ;
......@@ -185,6 +174,35 @@ typename PFP::VEC3 LocalFrame<PFP>::sphericalToCarth (const VEC2& sph) const
return res ;
}
template <typename REAL>
Geom::Vector<3,REAL> rotate (Geom::Vector<3,REAL> axis, REAL angle, Geom::Vector<3,REAL> vector)
{
axis.normalize() ;
const REAL& u = axis[0] ;
const REAL& v = axis[1] ;
const REAL& w = axis[2] ;
const REAL& x = vector[0] ;
const REAL& y = vector[1] ;
const REAL& z = vector[2] ;
Geom::Vector<3,REAL> res ;
REAL& xp = res[0] ;
REAL& yp = res[1] ;
REAL& zp = res[2] ;
const REAL tmp1 = u*x+v*y+w*z ;
const REAL cos = std::cos(angle) ;
const REAL sin = std::sin(angle) ;
xp = u*tmp1*(1-cos) + x*cos+(v*z-w*y)*sin ;
yp = v*tmp1*(1-cos) + y*cos-(u*z-w*x)*sin ;
zp = w*tmp1*(1-cos) + z*cos+(u*y-v*x)*sin ;
return res ;
}
} // Utils
} // CGoGN
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