Commit 58d48034 authored by Pierre Kraemer's avatar Pierre Kraemer

Merge cgogn:~sauvage/CGoGN

parents e6f05a9c c6662a5f
......@@ -43,6 +43,7 @@ enum ApproximatorType
A_CornerCutting,
A_TangentPredict1,
A_TangentPredict2,
A_NormalArea,
A_ColorNaive,
A_ColorQEMext,
A_Lightfield,
......
......@@ -65,6 +65,9 @@ void decimate(
case A_TangentPredict2 :
approximators.push_back(new Approximator_MidEdge<PFP>(map, attribs)) ;
break ;
case A_NormalArea :
approximators.push_back(new Approximator_NormalArea<PFP>(map, attribs)) ;
break ;
case A_hHalfCollapse :
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, attribs)) ;
break ;
......@@ -157,6 +160,12 @@ void decimate(
case S_Curvature :
selector = new EdgeSelector_Curvature<PFP>(map, position, approximators, selected) ;
break ;
case S_NormalArea :
selector = new EdgeSelector_NormalArea<PFP>(map, position, approximators, selected) ;
break ;
case S_CurvatureTensor :
selector = new EdgeSelector_CurvatureTensor<PFP>(map, position, approximators, selected) ;
break ;
case S_MinDetail :
selector = new EdgeSelector_MinDetail<PFP>(map, position, approximators, selected) ;
break ;
......@@ -178,6 +187,9 @@ void decimate(
case S_hLightfield :
selector = new HalfEdgeSelector_Lightfield<PFP>(map, position, approximators, selected) ;
break ;
case S_hLightfieldExp :
selector = new HalfEdgeSelector_LightfieldExp<PFP>(map, position, approximators, selected) ;
break ;
}
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
......
......@@ -31,7 +31,10 @@
#include "Container/fakeAttribute.h"
#include "Utils/qem.h"
#include "Utils/quadricRGBfunctions.h"
#include "Algo/Geometry/normal.h"
#include "Algo/Selection/collector.h"
#include "Algo/Geometry/curvature.h"
#include "Algo/Geometry/area.h"
namespace CGoGN
{
......@@ -268,6 +271,61 @@ public:
void updateWithoutCollapse();
} ;
template <typename PFP>
class EdgeSelector_NormalArea : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "NormalAreaEdgeInfo" ; }
} NormalAreaEdgeInfo ;
typedef NoMathIOAttribute<NormalAreaEdgeInfo> EdgeInfo ;
EdgeAttribute<EdgeInfo> edgeInfo ;
EdgeAttribute<Geom::Matrix<3,3,REAL> > edgeMatrix ;
std::multimap<float,Dart> edges ;
typename std::multimap<float,Dart>::iterator cur ;
Approximator<PFP, typename PFP::VEC3, EDGE>* m_positionApproximator ;
void initEdgeInfo(Dart d) ;
void updateEdgeInfo(Dart d) ;
void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;
void computeEdgeMatrix(Dart d) ;
// void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
public:
EdgeSelector_NormalArea(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
EdgeSelector<PFP>(m, pos, approx, select),
m_positionApproximator(NULL)
{
edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
edgeMatrix = m.template addAttribute<Geom::Matrix<3,3,REAL>, EDGE>("NormalAreaMatrix") ;
}
~EdgeSelector_NormalArea()
{
this->m_map.removeAttribute(edgeMatrix) ;
this->m_map.removeAttribute(edgeInfo) ;
}
SelectorType getType() { return S_NormalArea ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
} ;
template <typename PFP>
class EdgeSelector_Curvature : public EdgeSelector<PFP>
{
......@@ -366,6 +424,66 @@ public:
void updateWithoutCollapse();
} ;
template <typename PFP>
class EdgeSelector_CurvatureTensor : public EdgeSelector<PFP>
{
// TODO : this selector still needs to be tested
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "CurvatureTensorEdgeInfo" ; }
} CurvatureTensorEdgeInfo ;
typedef NoMathIOAttribute<CurvatureTensorEdgeInfo> EdgeInfo ;
EdgeAttribute<EdgeInfo> edgeInfo ;
EdgeAttribute<REAL> edgeangle ;
std::multimap<float,Dart> edges ;
typename std::multimap<float,Dart>::iterator cur ;
Approximator<PFP, VEC3,EDGE>* m_positionApproximator ;
void initEdgeInfo(Dart d) ;
void updateEdgeInfo(Dart d) ; // TODO : usually has a 2nd arg (, bool recompute) : why ??
void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;
public:
EdgeSelector_CurvatureTensor(MAP& m, VertexAttribute<VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
EdgeSelector<PFP>(m, pos, approx, select),
m_positionApproximator(NULL)
{
edgeangle = m.template getAttribute<REAL, EDGE>("edgeangle") ;
if(!edgeangle.isValid())
{
edgeangle = m.template addAttribute<REAL, EDGE>("edgeangle") ;
Algo::Geometry::computeAnglesBetweenNormalsOnEdges<PFP>(m, pos, edgeangle) ;
}
edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
}
~EdgeSelector_CurvatureTensor()
{
this->m_map.removeAttribute(edgeangle) ; // TODO : pas malin s'il existait avant
this->m_map.removeAttribute(edgeInfo) ;
}
SelectorType getType() { return S_CurvatureTensor ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() {};
} ;
template <typename PFP>
class EdgeSelector_MinDetail : public EdgeSelector<PFP>
{
......
This diff is collapsed.
......@@ -26,6 +26,8 @@
#define __GEOMETRY_APPROXIMATOR_H__
#include "Algo/Decimation/approximator.h"
#include "Utils/convertType.h"
#include <Eigen/Dense>
namespace CGoGN
{
......@@ -144,6 +146,32 @@ public:
void approximate(Dart d) ;
} ;
template <typename PFP>
class Approximator_NormalArea : public Approximator<PFP, typename PFP::VEC3, EDGE>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
protected:
// VertexAttribute<Utils::Quadric<REAL> > m_quadric ;
EdgeAttribute<Geom::Matrix<3,3,REAL> > edgeMatrix ;
public:
Approximator_NormalArea(MAP& m, std::vector<VertexAttribute<VEC3>* > pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3, EDGE>(m, pos, pred)
{
assert(pos.size() > 0 || !"Approximator_NormalArea: attribute vector is empty") ;
}
~Approximator_NormalArea()
{}
ApproximatorType getType() const { return A_NormalArea ; }
bool init() ;
void approximate(Dart d) ;
} ;
} //namespace Decimation
} //namespace Algo
......
......@@ -368,6 +368,89 @@ void Approximator_CornerCutting<PFP>::approximate(Dart d)
}
}
/************************************************************************************
* NORMAL AREA METRIC *
************************************************************************************/
template <typename PFP>
bool Approximator_NormalArea<PFP>::init()
{
edgeMatrix = this->m_map.template getAttribute<Geom::Matrix<3,3,REAL>, EDGE>("NormalAreaMatrix") ;
assert(edgeMatrix.isValid());
// m_quadric = this->m_map.template getAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
// Does not require to be valid (if it is not, altenatives will be used).
if(this->m_predictor)
{
return false ;
}
return true ;
}
template <typename PFP>
void Approximator_NormalArea<PFP>::approximate(Dart d)
{
typedef typename PFP::REAL REAL;
typedef Geom::Matrix<3,3,REAL> MATRIX;
typedef Eigen::Matrix<REAL,3,1> E_VEC3;
typedef Eigen::Matrix<REAL,3,3> E_MATRIX;
MAP& m = this->m_map ;
Dart dd = m.phi2(d);
MATRIX M1; // init zero included
MATRIX M2; // init zero included
assert(! m.isBoundaryEdge(d));
Traversor2VF<MAP> td (m,d);
Dart it = td.begin();
it = td.next();
Dart it2 = td.next();
while( it2 != td.end())
{
M1 += edgeMatrix[m.phi1(it)];
it = it2;
it2 = td.next();
}
Traversor2VF<MAP> tdd (m,dd);
it = tdd.begin();
it = tdd.next();
it2 = tdd.next();
while( it2 != tdd.end())
{
M2 += edgeMatrix[m.phi1(it)];
it = it2;
it2 = tdd.next();
}
const VEC3 & v1 = (*this->m_attrV[0])[d] ;
const VEC3 & v2 = (*this->m_attrV[0])[dd] ;
/* version plus sûre : sans cast avec recopie
E_MATRIX A ;
A << M1(0,0)+M2(0,0) , M1(0,1)+M2(0,1) , M1(0,2)+M2(0,2) , M1(1,0)+M2(1,0) , M1(1,1)+M2(1,1) , M1(1,2)+M2(1,2) , M1(2,0)+M2(2,0) , M1(2,1)+M2(2,1) , M1(2,2)+M2(2,2) ;
VEC3 mb = M1*v1 + M2*v2 ;
E_VEC3 b (mb[0],mb[1],mb[2]);
Eigen::LDLT<E_MATRIX> decompo (A);
E_VEC3 x = decompo.solve(b);
this->m_approx[0][d] = VEC3 (x(0),x(1),x(2)) ;
*/
/* version legerement moins gourmande et plus risquee : avec cast sans recopie */
VEC3 mb = M1*v1 + M2*v2 ;
M1 += M2;
Eigen::LDLT<E_MATRIX> decompo (Utils::convertRef<E_MATRIX>(M1));
E_VEC3 x = decompo.solve(Utils::convertRef<E_VEC3>(mb));
this->m_approx[0][d] = Utils::convertRef<VEC3>(x) ;
}
} //namespace Decimation
} //namespace Algo
......
......@@ -174,7 +174,7 @@ public:
} ;
/*****************************************************************************************************************
* HALF-EDGE QEMextColor METRIC *
* HALF-EDGE LIGHTFIELD METRIC *
*****************************************************************************************************************/
template <typename PFP>
class HalfEdgeSelector_Lightfield : public EdgeSelector<PFP>
......@@ -266,6 +266,105 @@ public:
}
} ;
/*****************************************************************************************************************
* HALF-EDGE LIGHTFIELD METRIC experimental *
*****************************************************************************************************************/
template <typename PFP>
class HalfEdgeSelector_LightfieldExp : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::REAL REAL ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename Geom::Vector<6,REAL> VEC6 ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "QEMextColorHalfEdgeInfo" ; }
} QEMextColorHalfEdgeInfo ;
typedef NoMathIOAttribute<QEMextColorHalfEdgeInfo> HalfEdgeInfo ;
DartAttribute<HalfEdgeInfo> halfEdgeInfo ;
VertexAttribute<Utils::Quadric<REAL> > m_quadricGeom ;
DartAttribute<Utils::QuadricHF<REAL> > m_quadricHF ;
VertexAttribute<VEC3> m_pos, m_frameT, m_frameB, m_frameN, m_avgColor ;
std::vector<VertexAttribute<VEC3> > m_HF ;
int m_approxindex_pos, m_attrindex_pos ;
int m_approxindex_FN, m_attrindex_FN ;
std::vector<unsigned int> m_approxindex_HF, m_attrindex_HF ;
unsigned int m_K ;
int m_approxindex_color, m_attrindex_color ;
std::vector<Approximator<PFP, typename PFP::VEC3, DART>* > m_approx ;
std::multimap<float,Dart> halfEdges ;
typename std::multimap<float,Dart>::iterator cur ;
void initHalfEdgeInfo(Dart d) ;
void updateHalfEdgeInfo(Dart d, bool recompute) ;
void computeHalfEdgeInfo(Dart d, HalfEdgeInfo& einfo) ;
void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
public:
HalfEdgeSelector_LightfieldExp(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = allDarts) :
EdgeSelector<PFP>(m, pos, approx, select),
m_approxindex_pos(-1),
m_attrindex_pos(-1),
m_approxindex_FN(-1),
m_attrindex_FN(-1),
m_K(0),
m_approxindex_color(-1),
m_attrindex_color(-1)
{
halfEdgeInfo = m.template addAttribute<HalfEdgeInfo, DART>("halfEdgeInfo") ;
m_quadricGeom = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
m_quadricHF = m.template getAttribute<Utils::QuadricHF<REAL>, DART>("HFquadric") ;
m_avgColor = m.template getAttribute<typename PFP::VEC3, VERTEX>("color") ;
assert(m_avgColor.isValid()) ;
}
~HalfEdgeSelector_LightfieldExp()
{
this->m_map.removeAttribute(m_quadricGeom) ;
this->m_map.removeAttribute(halfEdgeInfo) ;
}
SelectorType getType() { return S_hLightfield ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors)
{
assert(errors != NULL || !"EdgeSelector::setColorMap requires non null vertexattribute argument") ;
if (!errors->isValid())
std::cerr << "EdgeSelector::setColorMap requires valid edgeattribute argument" << std::endl ;
assert(halfEdgeInfo.isValid()) ;
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[dd].valid && halfEdgeInfo[d].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
}
}
} ;
} // namespace Decimation
} // namespace Algo
......
......@@ -43,13 +43,16 @@ enum SelectorType
S_QEMml,
S_MinDetail,
S_Curvature,
S_NormalArea,
S_CurvatureTensor,
S_ColorNaive,
S_QEMextColor,
S_Lightfield,
// note: the following "h" prefix means that half-edges are prioritized instead of edges.
S_hQEMextColor,
S_hQEMml,
S_hLightfield
S_hLightfield,
S_hLightfieldExp
} ;
template <typename PFP> class ApproximatorGen ;
......
......@@ -27,6 +27,10 @@
#include "Geometry/basic.h"
#include "Algo/Selection/collector.h"
#include "Utils/convertType.h"
#include "OpenNL/linear_solver.h"
#include "OpenNL/sparse_matrix.h"
#include "OpenNL/full_vector.h"
......@@ -92,6 +96,7 @@ template <typename PFP>
void cubicFittingAddVertexNormal(typename PFP::VEC3& v, typename PFP::VEC3& n, typename PFP::VEC3& p, typename PFP::MATRIX33& localFrame) ;
*/
/* normal cycles by [ACDLD03] : useful for parallel computing*/
template <typename PFP>
void computeCurvatureVertices_NormalCycles(
typename PFP::MAP& map,
......@@ -120,6 +125,111 @@ void computeCurvatureVertex_NormalCycles(
VertexAttribute<typename PFP::VEC3>& Kmin,
VertexAttribute<typename PFP::VEC3>& Knormal, unsigned int thread=0) ;
template <typename PFP>
void normalCycles_SortAndSetEigenComponents(
const typename PFP::VEC3& e_val,
const Geom::Matrix<3,3,typename PFP::REAL> & e_vec,
typename PFP::REAL& kmax,
typename PFP::REAL& kmin,
typename PFP::VEC3& Kmax,
typename PFP::VEC3& Kmin,
typename PFP::VEC3& Knormal,
const typename PFP::VEC3& normal,
unsigned int thread=0) ;
template <typename PFP>
void normalCycles_SortTensor( Geom::Matrix<3,3,typename PFP::REAL> & tensor, unsigned int thread=0) ;
template <typename PFP>
void normalCycles_ProjectTensor( Geom::Matrix<3,3,typename PFP::REAL> & tensor, const typename PFP::VEC3& normal_vector, unsigned int thread=0) ;
template <typename PFP>
void computeCurvatureVertices_NormalCycles_Projected(
typename PFP::MAP& map,
typename PFP::REAL radius,
const VertexAttribute<typename PFP::VEC3>& position,
const VertexAttribute<typename PFP::VEC3>& normal,
const EdgeAttribute<typename PFP::REAL>& edgeangle,
VertexAttribute<typename PFP::REAL>& kmax,
VertexAttribute<typename PFP::REAL>& kmin,
VertexAttribute<typename PFP::VEC3>& Kmax,
VertexAttribute<typename PFP::VEC3>& Kmin,
VertexAttribute<typename PFP::VEC3>& Knormal,
const FunctorSelect& select = allDarts, unsigned int thread=0) ;
template <typename PFP>
void computeCurvatureVertex_NormalCycles_Projected(
typename PFP::MAP& map,
Dart dart,
typename PFP::REAL radius,
const VertexAttribute<typename PFP::VEC3>& position,
const VertexAttribute<typename PFP::VEC3>& normal,
const EdgeAttribute<typename PFP::REAL>& edgeangle,
VertexAttribute<typename PFP::REAL>& kmax,
VertexAttribute<typename PFP::REAL>& kmin,
VertexAttribute<typename PFP::VEC3>& Kmax,
VertexAttribute<typename PFP::VEC3>& Kmin,
VertexAttribute<typename PFP::VEC3>& Knormal, unsigned int thread=0) ;
/* normal cycles with collector as a parameter : not usable in parallel */
template <typename PFP>
void computeCurvatureVertices_NormalCycles(
typename PFP::MAP& map,
Algo::Selection::Collector<PFP> & neigh,
const VertexAttribute<typename PFP::VEC3>& position,
const VertexAttribute<typename PFP::VEC3>& normal,
const EdgeAttribute<typename PFP::REAL>& edgeangle,
VertexAttribute<typename PFP::REAL>& kmax,
VertexAttribute<typename PFP::REAL>& kmin,
VertexAttribute<typename PFP::VEC3>& Kmax,
VertexAttribute<typename PFP::VEC3>& Kmin,
VertexAttribute<typename PFP::VEC3>& Knormal,
const FunctorSelect& select = allDarts, unsigned int thread=0) ;
template <typename PFP>
void computeCurvatureVertex_NormalCycles(
typename PFP::MAP& map,
Dart dart,
Algo::Selection::Collector<PFP> & neigh,
const VertexAttribute<typename PFP::VEC3>& position,
const VertexAttribute<typename PFP::VEC3>& normal,
const EdgeAttribute<typename PFP::REAL>& edgeangle,
VertexAttribute<typename PFP::REAL>& kmax,
VertexAttribute<typename PFP::REAL>& kmin,
VertexAttribute<typename PFP::VEC3>& Kmax,
VertexAttribute<typename PFP::VEC3>& Kmin,
VertexAttribute<typename PFP::VEC3>& Knormal, unsigned int thread=0) ;
template <typename PFP>
void computeCurvatureVertices_NormalCycles_Projected(
typename PFP::MAP& map,
Algo::Selection::Collector<PFP> & neigh,
const VertexAttribute<typename PFP::VEC3>& position,
const VertexAttribute<typename PFP::VEC3>& normal,
const EdgeAttribute<typename PFP::REAL>& edgeangle,
VertexAttribute<typename PFP::REAL>& kmax,
VertexAttribute<typename PFP::REAL>& kmin,
VertexAttribute<typename PFP::VEC3>& Kmax,
VertexAttribute<typename PFP::VEC3>& Kmin,
VertexAttribute<typename PFP::VEC3>& Knormal,
const FunctorSelect& select = allDarts, unsigned int thread=0) ;
template <typename PFP>
void computeCurvatureVertex_NormalCycles_Projected(
typename PFP::MAP& map,
Dart dart,
Algo::Selection::Collector<PFP> & neigh,
const VertexAttribute<typename PFP::VEC3>& position,
const VertexAttribute<typename PFP::VEC3>& normal,
const EdgeAttribute<typename PFP::REAL>& edgeangle,
VertexAttribute<typename PFP::REAL>& kmax,
VertexAttribute<typename PFP::REAL>& kmin,
VertexAttribute<typename PFP::VEC3>& Kmax,
VertexAttribute<typename PFP::VEC3>& Kmin,
VertexAttribute<typename PFP::VEC3>& Knormal, unsigned int thread=0) ;
namespace Parallel
......
This diff is collapsed.
......@@ -81,7 +81,7 @@ void computeNormalFaces(typename PFP::MAP& map, const VertexAttribute<typename P
template <typename PFP>
typename PFP::REAL computeAngleBetweenNormalsOnEdge(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3>& position) ;
typename PFP::REAL computeAngleBetweenNormalsOnEdge(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position) ;
template <typename PFP>
void computeAnglesBetweenNormalsOnEdges(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, EdgeAttribute<typename PFP::REAL>& angles, const FunctorSelect& select = allDarts, unsigned int thread = 0) ;
......
......@@ -25,6 +25,7 @@
#ifndef _COLOR_PER_FACE_RENDER
#define _COLOR_PER_FACE_RENDER
#include <GL/glew.h>
#include "Topology/generic/dart.h"
#include "Topology/generic/attributeHandler.h"
......@@ -46,7 +47,7 @@ namespace GL2
{
/**
* Class that update VBO to allow the rendering of per face color rendering
* Class that update VBO to allow the rendering of per face colors
* Use with ColorPerVertexShader
*/
class ColorPerFaceRender
......@@ -69,9 +70,9 @@ public:
* @param colorPerXXX attribute of color (per face, per vertex per face, per what you want)
* @param good selector
*/
template<typename PFP, typename ATTRIB>
template<typename PFP, unsigned int ORBIT>