Commit 4e5e69b1 authored by Kenneth Vanhoey's avatar Kenneth Vanhoey

Merge cgogn:~cgogn/CGoGN

parents 4268ecf1 947fe6a0
......@@ -185,13 +185,9 @@ void Viewer::importMesh(std::string& filename)
m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::LINES) ;
m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::TRIANGLES) ;
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
gPosObj = bb.center() ;
float tailleX = bb.size(0) ;
float tailleY = bb.size(1) ;
float tailleZ = bb.size(2) ;
gWidthObj = std::max<float>(std::max<float>(tailleX, tailleY), tailleZ) ;
normalBaseSize = std::min<float>(std::min<float>(tailleX,tailleY),tailleZ) / 50.0f ;
normalBaseSize = bb.diagSize() / 100.0f ;
vertexBaseSize = normalBaseSize * 2.0f ;
if(!normal.isValid())
......@@ -202,7 +198,7 @@ void Viewer::importMesh(std::string& filename)
m_positionVBO->updateData(position) ;
m_normalVBO->updateData(normal) ;
setParamObject(gWidthObj, gPosObj.data()) ;
setParamObject(bb.maxSize(), gPosObj.data()) ;
updateGLMatrices() ;
}
......
......@@ -77,8 +77,8 @@ public:
float shininess ;
Geom::BoundingBox<PFP::VEC3> bb ;
Geom::Vec3f gPosObj ;
float gWidthObj ;
float normalBaseSize ;
float normalScaleFactor ;
float vertexBaseSize ;
......
......@@ -43,30 +43,29 @@ namespace Geometry
typedef CPULinearSolverTraits< SparseMatrix<double>, FullVector<double> > CPUSolverTraits ;
template <typename PFP>
void computeCurvatureVertices(
void computeCurvatureVertices_QuadraticFitting(
typename PFP::MAP& map,
const typename PFP::TVEC3& position,
const typename PFP::TVEC3& normal,
typename PFP::TREAL& k1,
typename PFP::TREAL& k2,
typename PFP::TVEC3& K1,
typename PFP::TVEC3& K2,
typename PFP::TREAL& kmax,
typename PFP::TREAL& kmin,
typename PFP::TVEC3& Kmax,
typename PFP::TVEC3& Kmin,
const FunctorSelect& select = SelectorTrue()) ;
template <typename PFP>
void computeCurvatureVertex(
void computeCurvatureVertex_QuadraticFitting(
typename PFP::MAP& map,
Dart dart,
const typename PFP::TVEC3& position,
const typename PFP::TVEC3& normal,
typename PFP::TREAL& k1,
typename PFP::TREAL& k2,
typename PFP::TVEC3& K1,
typename PFP::TVEC3& K2) ;
typename PFP::TREAL& kmax,
typename PFP::TREAL& kmin,
typename PFP::TVEC3& Kmax,
typename PFP::TVEC3& Kmin) ;
template <typename PFP>
void vertexQuadricFitting(
void vertexQuadraticFitting(
typename PFP::MAP& map,
Dart dart,
typename PFP::MATRIX33& localFrame,
......@@ -75,10 +74,10 @@ void vertexQuadricFitting(
float& a, float& b, float& c, float& d, float& e) ;
template <typename PFP>
void quadricFittingAddVertexPos(typename PFP::VEC3& v, typename PFP::VEC3& p, typename PFP::MATRIX33& localFrame, LinearSolver<CPUSolverTraits>& solver) ;
void quadraticFittingAddVertexPos(typename PFP::VEC3& v, typename PFP::VEC3& p, typename PFP::MATRIX33& localFrame, LinearSolver<CPUSolverTraits>& solver) ;
template <typename PFP>
void quadricFittingAddVertexNormal(typename PFP::VEC3& v, typename PFP::VEC3& n, typename PFP::VEC3& p, typename PFP::MATRIX33& localFrame, LinearSolver<CPUSolverTraits>& solver) ;
void quadraticFittingAddVertexNormal(typename PFP::VEC3& v, typename PFP::VEC3& n, typename PFP::VEC3& p, typename PFP::MATRIX33& localFrame, LinearSolver<CPUSolverTraits>& solver) ;
/*
template <typename PFP>
void vertexCubicFitting(Dart dart, typename PFP::VEC3& normal, float& a, float& b, float& c, float& d, float& e, float& f, float& g, float& h, float& i) ;
......@@ -90,7 +89,35 @@ template <typename PFP>
void cubicFittingAddVertexNormal(typename PFP::VEC3& v, typename PFP::VEC3& n, typename PFP::VEC3& p, typename PFP::MATRIX33& localFrame) ;
*/
} // namespace Geoemtry
template <typename PFP>
void computeCurvatureVertices_NormalCycles(
typename PFP::MAP& map,
typename PFP::REAL radius,
const typename PFP::TVEC3& position,
const typename PFP::TVEC3& normal,
const typename PFP::TREAL& angles,
typename PFP::TREAL& kmax,
typename PFP::TREAL& kmin,
typename PFP::TVEC3& Kmax,
typename PFP::TVEC3& Kmin,
typename PFP::TVEC3& Knormal,
const FunctorSelect& select = SelectorTrue()) ;
template <typename PFP>
void computeCurvatureVertex_NormalCycles(
typename PFP::MAP& map,
Dart dart,
typename PFP::REAL radius,
const typename PFP::TVEC3& position,
const typename PFP::TVEC3& normal,
const typename PFP::TREAL& angles,
typename PFP::TREAL& kmax,
typename PFP::TREAL& kmin,
typename PFP::TVEC3& Kmax,
typename PFP::TVEC3& Kmin,
typename PFP::TVEC3& Knormal) ;
} // namespace Geometry
} // namespace Algo
......
This diff is collapsed.
......@@ -37,16 +37,16 @@ namespace Geometry
{
template <typename PFP>
typename PFP::VEC3 triangleNormal(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position);
typename PFP::VEC3 triangleNormal(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position) ;
template <typename PFP>
typename PFP::VEC3 faceNormal(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position);
typename PFP::VEC3 faceNormal(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position) ;
template <typename PFP>
typename PFP::VEC3 vertexNormal(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position);
typename PFP::VEC3 vertexNormal(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position) ;
template <typename PFP>
void computeNormalFaces(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& face_normal, const FunctorSelect& select = SelectorTrue(), unsigned int thread=0) ;
void computeNormalFaces(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& face_normal, const FunctorSelect& select = SelectorTrue(), unsigned int thread = 0) ;
/**
* compute normals of vertices
......@@ -57,7 +57,13 @@ void computeNormalFaces(typename PFP::MAP& map, const typename PFP::TVEC3& posit
* @ param th the thread number
*/
template <typename PFP>
void computeNormalVertices(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue(), unsigned int thread=0) ;
void computeNormalVertices(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue(), unsigned int thread = 0) ;
template <typename PFP>
typename PFP::REAL computeAngleBetweenNormalsOnEdge(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position) ;
template <typename PFP>
void computeAnglesBetweenNormalsOnEdges(typename PFP::MAP& map, typename PFP::TVEC3& position, typename PFP::TREAL& angles, const FunctorSelect& select = SelectorTrue(), unsigned int thread = 0) ;
} // namespace Geometry
......
......@@ -112,7 +112,7 @@ void computeNormalFaces(typename PFP::MAP& map, const typename PFP::TVEC3& posit
}
template <typename PFP>
class computeNormalVerticesFunctor: public FunctorMap<typename PFP::MAP>
class computeNormalVerticesFunctor : public FunctorMap<typename PFP::MAP>
{
protected:
typename PFP::MAP& m_map;
......@@ -120,8 +120,8 @@ protected:
typename PFP::TVEC3& m_normal;
public:
computeNormalVerticesFunctor(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& normal):
m_map(map), m_position(position), m_normal(normal) {}
m_map(map), m_position(position), m_normal(normal)
{}
bool operator()(Dart d)
{
m_normal[d] = vertexNormal<PFP>(m_map, d, m_position) ;
......@@ -129,12 +129,10 @@ public:
}
};
template <typename PFP>
void computeNormalVertices(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& normal, const FunctorSelect& select, unsigned int thread)
{
CellMarker marker(map, VERTEX,thread);
CellMarker marker(map, VERTEX, thread);
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
if(select(d) && !marker.isMarked(d))
......@@ -145,6 +143,46 @@ void computeNormalVertices(typename PFP::MAP& map, const typename PFP::TVEC3& po
}
}
template <typename PFP>
typename PFP::REAL computeAngleBetweenNormalsOnEdge(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position)
{
typedef typename PFP::VEC3 VEC3 ;
Dart dd = map.phi2(d) ;
const VEC3 n1 = faceNormal<PFP>(map, d, position) ;
const VEC3 n2 = faceNormal<PFP>(map, dd, position) ;
VEC3 e = position[dd] - position[d] ;
e.normalize() ;
typename PFP::REAL s = e * (n1 ^ n2) ;
typename PFP::REAL c = n1 * n2 ;
typename PFP::REAL a(0) ;
// the following trick is useful for avoiding NaNs (due to floating point errors)
if (c > 0.5) a = asin(s) ;
else
{
if(c < -1) c = -1 ;
if (s >= 0) a = acos(c) ;
else a = -acos(c) ;
}
if (isnan(a))
std::cerr<< "Warning : computeAngleBetweenNormalsOnEdge returns NaN on edge " << d << "-" << dd << std::endl ;
return a ;
}
template <typename PFP>
void computeAnglesBetweenNormalsOnEdges(typename PFP::MAP& map, typename PFP::TVEC3& position, typename PFP::TREAL& angles, const FunctorSelect& select, unsigned int thread)
{
CellMarker me(map, EDGE, thread) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
if(select(d) && !me.isMarked(d))
{
me.mark(d) ;
angles[d] = computeAngleBetweenNormalsOnEdge<PFP>(map, d, position) ;
}
}
}
} // namespace Geometry
} // namespace Algo
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library 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 Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: https://iggservis.u-strasbg.fr/CGoGN/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __COLLECTOR_H__
#define __COLLECTOR_H__
/*****************************************
* Class hierarchy :
* Collector (virtual)
* - Collector_WithinSphere
* - Collector_OneRing
****************************************/
namespace CGoGN
{
namespace Algo
{
namespace Selection
{
/*********************************************************
* Collector
*********************************************************/
template <typename PFP>
class Collector
{
protected:
typedef typename PFP::VEC3 VEC3;
typedef typename PFP::REAL REAL;
typename PFP::MAP& map;
const typename PFP::TVEC3& position;
Dart centerDart;
REAL radius;
std::vector<Dart> insideVertices;
std::vector<Dart> insideEdges;
std::vector<Dart> insideFaces;
std::vector<Dart> border;
public:
Collector(typename PFP::MAP& mymap, const typename PFP::TVEC3& myposition);
virtual void init(Dart d, REAL r = 0) = 0;
virtual void collect() = 0;
void sort()
{
std::sort(insideVertices.begin(), insideVertices.end());
std::sort(insideEdges.begin(), insideEdges.end());
std::sort(insideFaces.begin(), insideFaces.end());
std::sort(border.begin(), border.end());
}
typename PFP::MAP& getMap() { return map; }
const AttributeHandler<typename PFP::VEC3>& getPosition() const { return position; }
Dart getCenter() const { return centerDart; }
REAL getRadius() const { return radius; }
const std::vector<Dart>& getInsideVertices() const { return insideVertices; }
const std::vector<Dart>& getInsideEdges() const { return insideEdges; }
const std::vector<Dart>& getInsideFaces() const { return insideFaces; }
const std::vector<Dart>& getBorder() const { return border; }
unsigned int getNbInsideVertices() const { return insideVertices.size(); }
unsigned int getNbInsideEdges() const { return insideEdges.size(); }
unsigned int getNbInsideFaces() const { return insideFaces.size(); }
unsigned int getNbBorder() const { return border.size(); }
template <typename PPFP>
friend std::ostream& operator<<(std::ostream &out, const Collector<PPFP>& c);
};
/*********************************************************
* Collector One Ring
*********************************************************/
/*
* insideVertices = centerDart
* insideEdges = star (edges incident to centerDart)
* insideFaces = triangles incident to centerDart
* border = vertices of 1-ring
* = edges of 1-ring
*/
template <typename PFP>
class Collector_OneRing : public Collector<PFP>
{
public:
Collector_OneRing(typename PFP::MAP& mymap, const typename PFP::TVEC3& myposition) :
Collector<PFP>(mymap, myposition)
{}
void init(Dart d, typename PFP::REAL r = 0);
void collect();
};
/*********************************************************
* Collector Within Sphere
*********************************************************/
/*
* collect all primitives of the connected component containing "centerDart"
* within the sphere of radius "radius" and center "position[centerDart]"
* (hopefully) it defines a 2-manifold (if inserting border-vertices along the border-edges)
*/
template <typename PFP>
class Collector_WithinSphere : public Collector<PFP>
{
protected:
typename PFP::REAL radius_2;
typename PFP::VEC3 centerPosition;
typename PFP::REAL area;
public:
Collector_WithinSphere(typename PFP::MAP& mymap, const typename PFP::TVEC3& myposition) :
Collector<PFP>(mymap,myposition)
{}
void init(Dart d, typename PFP::REAL r = 0);
void collect();
bool isInside(Dart d)
{
return (this->position[d] - centerPosition).norm2() < radius_2;
}
// alpha = coef d'interpolation dans [0 ,1] tel que v= (1-alpha)*pin + alpha*pout
// est le point d'intersection entre la sphère et le segment [pin, pout]
// avec pin = position[din] à l'intérieur de la sphère
// avec pout = position[dout] à l'extérieur de la sphère
typename PFP::REAL intersect_SphereEdge(const Dart din, const Dart dout);
void computeArea();
typename PFP::REAL getArea() const { return area; }
};
} // namespace Selection
} // namespace Algo
} // namespace CGoGN
#include "Algo/Selection/collector.hpp"
#endif
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library 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 Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: https://iggservis.u-strasbg.fr/CGoGN/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
namespace CGoGN
{
namespace Algo
{
namespace Selection
{
/********************************************
* GENERIC COLLECTOR
********************************************/
template <typename PFP>
Collector<PFP>::Collector(typename PFP::MAP& mymap, const typename PFP::TVEC3& myposition):
map(mymap),
position(myposition)
{}
template <typename PPFP>
std::ostream& operator<<(std::ostream &out, const Collector<PPFP>& c)
{
out << "Collector around " << c.centerDart << std::endl;
out << "insideVertices (" << c.insideVertices.size() << ") = {";
for (unsigned int i=0; i< c.insideVertices.size(); ++i) out << c.insideVertices[i] << " ";
out << "}" << std::endl ;
out << "insideEdges (" << c.insideEdges.size() << ") = {";
for (unsigned int i=0; i< c.insideEdges.size(); ++i) out << c.insideEdges[i] << " ";
out << "}" << std::endl ;
out << "insideFaces (" << c.insideFaces.size() << ") = {";
for (unsigned int i=0; i< c.insideFaces.size(); ++i) out << c.insideFaces[i] << " ";
out << "}" << std::endl ;
out << "border (" << c.border.size() << ") = {";
for (unsigned int i=0; i< c.border.size(); ++i) out << c.border[i] << " ";
out << "}" << std::endl;
return out;
}
/*********************************************************
* Collector One Ring
*********************************************************/
template <typename PFP>
void Collector_OneRing<PFP>::init(Dart d, typename PFP::REAL r)
{
this->centerDart = d;
this->radius = r;
this->insideVertices.clear();
this->insideEdges.clear();
this->insideFaces.clear();
this->border.clear();
}
template <typename PFP>
void Collector_OneRing<PFP>::collect()
{
const Dart end = this->centerDart;
this->insideVertices.push_back(end);
Dart dd = end;
do
{
this->insideEdges.push_back(dd);
this->insideFaces.push_back(dd);
this->border.push_back(this->map.phi1(dd));
dd = this->map.alpha1(dd);
} while(dd != end);
}
/*********************************************************
* Collector Within Sphere
*********************************************************/
template <typename PFP>
void Collector_WithinSphere<PFP>::init(Dart d, typename PFP::REAL r)
{
this->centerDart = d;
this->radius = r;
this->insideVertices.clear();
this->insideEdges.clear();
this->insideFaces.clear();
this->border.clear();
radius_2 = r * r;
centerPosition = this->position[d];
area = 0;
}
template <typename PFP>
void Collector_WithinSphere<PFP>::collect()
{
typedef typename PFP::VEC3 VEC3;
typedef typename PFP::REAL REAL;
CellMarkerStore vm(this->map,VERTEX); // mark the collected inside-vertices
CellMarkerStore em(this->map,EDGE); // mark the collected inside-edges + border-edges
CellMarkerStore fm(this->map,FACE); // mark the collected inside-faces + border-faces
this->insideVertices.push_back(this->centerDart);
vm.mark(this->centerDart);
unsigned int i = 0;
while (i < this->insideVertices.size())
{
Dart end = this->insideVertices[i];
Dart e = end;
do
{
if (! em.isMarked(e) || ! fm.isMarked(e)) // are both tests useful ?
{
const Dart f = this->map.phi1(e);
const Dart g = this->map.phi1(f);
if (!this->isInside(f))
{
this->border.push_back(e); // add to border
em.mark(e);
fm.mark(e); // is it useful ?
}
else
{
if (! vm.isMarked(f))
{
this->insideVertices.push_back(f);
vm.mark(f);
}
if (! em.isMarked(e))
{
this->insideEdges.push_back(e);
em.mark(e);
}
if (! fm.isMarked(e) && this->isInside(g))
{
this->insideFaces.push_back(e);
fm.mark(e);
}
}
}
e = this->map.alpha1(e);
} while (e != end);
++i;
}
}
template <typename PFP>
typename PFP::REAL Collector_WithinSphere<PFP>::intersect_SphereEdge(const Dart din, const Dart dout)
{
typedef typename PFP::VEC3 VEC3;
typedef typename PFP::REAL REAL;
VEC3 p = this->position[din] - this->centerPosition;
VEC3 qminusp = this->position[dout] - this->centerPosition - p;
REAL s = p*qminusp;
REAL n2 = qminusp.norm2();
return (- s + sqrt (s*s + n2*(this->radius_2 - p.norm2())))/(n2);
}
template <typename PFP>
void Collector_WithinSphere<PFP>::computeArea()
{
for (std::vector<Dart>::const_iterator it = this->insideFaces.begin(); it != this->insideFaces.end(); ++it)
{
this->area += Algo::Geometry::triangleArea<PFP>(this->map, *it, this->position);
}
for (std::vector<Dart>::const_iterator it = this->border.begin(); it != this->border.end(); ++it)
{
const Dart f = this->map.phi1(*it); // we know that f is outside
const Dart g = this->map.phi1(f);
if (this->isInside(g))
{ // only f is outside
typename PFP::REAL alpha = this->intersect_SphereEdge (*it, f);
typename PFP::REAL beta = this->intersect_SphereEdge (g, f);
this->area += (alpha+beta - alpha*beta) * Algo::Geometry::triangleArea<PFP>(this->map, *it, this->position);
}
else
{ // f and g are outside
typename PFP::REAL alpha = this->intersect_SphereEdge (*it, f);
typename PFP::REAL beta = this->intersect_SphereEdge (*it, g);
this->area += alpha * beta * Algo::Geometry::triangleArea<PFP>(this->map, *it, this->position);
}
}
}
} // namespace Selection