Commit f1c7acec authored by Sylvain Thery's avatar Sylvain Thery
Browse files

Merge branch 'master' of cgogn:~sauvage/CGoGN

Conflicts:
	include/Algo/Selection/collector.hpp
parents 9b8f3e9d 6041d67d
......@@ -46,6 +46,7 @@ enum ApproximatorType
A_CornerCutting,
A_TangentPredict1,
A_TangentPredict2,
A_NormalArea,
A_ColorNaive,
A_ColorQEMext,
A_Lightfield,
......
......@@ -68,6 +68,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 ;
......@@ -160,6 +163,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 ;
......@@ -181,6 +190,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
{
......@@ -271,6 +274,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>
{
......@@ -369,6 +427,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
{
......@@ -147,6 +149,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
}
......
......@@ -371,6 +371,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
}
......
......@@ -177,7 +177,7 @@ public:
} ;
/*****************************************************************************************************************
* HALF-EDGE QEMextColor METRIC *
* HALF-EDGE LIGHTFIELD METRIC *
*****************************************************************************************************************/
template <typename PFP>
class HalfEdgeSelector_Lightfield : public EdgeSelector<PFP>
......@@ -269,6 +269,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
}
......
......@@ -116,33 +116,33 @@ void HalfEdgeSelector_QEMml<PFP>::updateBeforeCollapse(Dart d)
{
MAP& m = this->m_map ;
HalfEdgeInfo& edgeE = halfEdgeInfo[d] ;
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
HalfEdgeInfo* edgeE = &(halfEdgeInfo[d]) ;
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
edgeE = halfEdgeInfo[m.phi1(d)] ;
if(edgeE.valid) // remove all
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[m.phi1(d)]) ;
if(edgeE->valid) // remove all
halfEdges.erase(edgeE->it) ;
edgeE = halfEdgeInfo[m.phi_1(d)] ; // the halfedges that will disappear
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[m.phi_1(d)]) ; // the halfedges that will disappear
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
// from the multimap
Dart dd = m.phi2(d) ;
assert(dd != d) ;
if(dd != d)
{
edgeE = halfEdgeInfo[dd] ;
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[dd]) ;
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
edgeE = halfEdgeInfo[m.phi1(dd)] ;
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[m.phi1(dd)]) ;
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
edgeE = halfEdgeInfo[m.phi_1(dd)] ;
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[m.phi_1(dd)]) ;
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
}
}
......@@ -392,33 +392,33 @@ void HalfEdgeSelector_QEMextColor<PFP>::updateBeforeCollapse(Dart d)
{
MAP& m = this->m_map ;
HalfEdgeInfo& edgeE = halfEdgeInfo[d] ;
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
HalfEdgeInfo* edgeE = &(halfEdgeInfo[d]) ;
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
edgeE = halfEdgeInfo[m.phi1(d)] ;
if(edgeE.valid) // remove all
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[m.phi1(d)]) ;
if(edgeE->valid) // remove all
halfEdges.erase(edgeE->it) ;
edgeE = halfEdgeInfo[m.phi_1(d)] ; // the halfedges that will disappear
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[m.phi_1(d)]) ; // the halfedges that will disappear
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
// from the multimap
Dart dd = m.phi2(d) ;
assert(dd != d) ;
if(dd != d)
{
edgeE = halfEdgeInfo[dd] ;
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[dd]) ;
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
edgeE = halfEdgeInfo[m.phi1(dd)] ;
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[m.phi1(dd)]) ;
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
edgeE = halfEdgeInfo[m.phi_1(dd)] ;
if(edgeE.valid)
halfEdges.erase(edgeE.it) ;
edgeE = &(halfEdgeInfo[m.phi_1(dd)]) ;
if(edgeE->valid)
halfEdges.erase(edgeE->it) ;
}
}
......@@ -609,6 +609,7 @@ bool HalfEdgeSelector_Lightfield<PFP>::init()
// Verify availability of required approximators
unsigned int ok = 0 ;
unsigned int k = 0 ;
for (unsigned int approxindex = 0 ; approxindex < this->m_approximators.size() ; ++approxindex)
{
assert(this->m_approximators[approxindex]->getType() == A_hQEM
......@@ -616,7 +617,6 @@ bool HalfEdgeSelector_Lightfield<PFP>::init()
|| this->m_approximators[approxindex]->getType() != A_Lightfield
|| !"Approximator for selector (HalfEdgeSelector_Lightfield) must be of a half-edge approximator") ;
unsigned int k = 0 ;
bool saved = false ;
for (unsigned int attrindex = 0 ; attrindex < this->m_approximators[approxindex]->getNbApproximated() ; ++ attrindex)
{
......@@ -642,7 +642,7 @@ bool HalfEdgeSelector_Lightfield<PFP>::init()
if (!saved)
{
m_approx.push_back(reinterpret_cast<Approximator<PFP, VEC3, DART>* >(this->m_approximators[approxindex])) ;
assert(m_frameT.isValid() || !"EdgeSelector_QEMextColor: frameT attribute is not valid") ;
assert(m_frameT.isValid() || !"HalfEdgeSelector_Lightfield: frameT attribute is not valid") ;
saved = true ;
}
}
......@@ -652,7 +652,7 @@ bool HalfEdgeSelector_Lightfield<PFP>::init()
// m_approxindex_FB = approxindex ;
// m_attrindex_FB = attrindex ;
m_frameB = m.template getAttribute<typename PFP::VEC3, VERTEX>("frameB") ;
assert(m_frameB.isValid() || !"EdgeSelector_QEMextColor: frameB attribute is not valid") ;
assert(m_frameB.isValid() || !"HalfEdgeSelector_Lightfield: frameB attribute is not valid") ;
if (!saved)
{
m_approx.push_back(reinterpret_cast<Approximator<PFP, VEC3, DART>* >(this->m_approximators[approxindex])) ;
......@@ -665,7 +665,7 @@ bool HalfEdgeSelector_Lightfield<PFP>::init()
m_approxindex_FN = approxindex ;
m_attrindex_FN = attrindex ;
m_frameN = m.template getAttribute<typename PFP::VEC3, VERTEX>("frameN") ;
assert(m_frameN.isValid() || !"EdgeSelector_QEMextColor: frameN attribute is not valid") ;
assert(m_frameN.isValid() || !"HalfEdgeSelector_Lightfield: frameN attribute is not valid") ;
if (!saved)
{
m_approx.push_back(reinterpret_cast<Approximator<PFP, VEC3, DART>* >(this->m_approximators[approxindex])) ;
......@@ -693,8 +693,9 @@ bool HalfEdgeSelector_Lightfield<PFP>::init()
}
}
}
m_K = k ;
}
m_K = k ;
std::cout << m_K << std::endl ;
if(ok < 5)