Commit fb95e191 authored by Sylvain Thery's avatar Sylvain Thery

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

parents 2f7d4461 7af03e77
......@@ -39,11 +39,13 @@ namespace Decimation
enum ApproximatorType
{
A_QEM,
A_QEMhalfEdge,
A_MidEdge,
A_HalfCollapse,
A_CornerCutting,
A_TangentPredict1,
A_TangentPredict2,
A_LightfieldHalf,
A_LightfieldFull
} ;
......
......@@ -25,7 +25,8 @@
#ifndef __DECIMATION_H__
#define __DECIMATION_H__
#include "Algo/Decimation/selector.h"
#include "Algo/Decimation/edgeSelector.h"
#include "Algo/Decimation/halfEdgeSelector.h"
#include "Algo/Decimation/geometryApproximator.h"
#include "Algo/Decimation/lightfieldApproximator.h"
......
......@@ -45,6 +45,9 @@ void decimate(
case A_QEM :
approximators.push_back(new Approximator_QEM<PFP>(map, position)) ;
break ;
case A_QEMhalfEdge :
approximators.push_back(new Approximator_QEMhalfEdge<PFP>(map, position)) ;
break ;
case A_MidEdge :
approximators.push_back(new Approximator_MidEdge<PFP>(map, position)) ;
break ;
......@@ -62,13 +65,44 @@ void decimate(
break ;
case A_LightfieldFull :
{
approximators.push_back(new Approximator_QEM<PFP>(map, position)) ;
approximators.push_back(new Approximator_QEMhalfEdge<PFP>(map, position)) ;
/*
PFP::TVEC3 frame[3] ;
frame[0] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "frame_T") ; // Tangent
frame[1] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "frame_B") ; // Bitangent
frame[2] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "frame_N") ; // Normal
for (unsigned int i = 0 ; i < 3 ; ++i)
if (!frame[i].isValid()) {
std::cerr << "In function decimate : frame[" << i << "] is not valid" << std::endl ;
}
AttributeHandler<typename PFP::VEC3> colorPTM[6] ;
colorPTM[0] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "colorPTM_a") ;
colorPTM[1] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "colorPTM_b") ;
colorPTM[2] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "colorPTM_c") ;
colorPTM[3] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "colorPTM_d") ;
colorPTM[4] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "colorPTM_e") ;
colorPTM[5] = map.template getAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "colorPTM_f") ;
for (unsigned int i = 0 ; i < 6 ; ++i)
if (!colorPTM[i].isValid()) {
std::cerr << "In function decimate : colorPTM[" << i << "] is not valid" << std::endl ;
}
*/
AttributeHandler<Geom::Matrix<3,3,typename PFP::REAL> > frame = map.template getAttribute<Geom::Matrix<3,3,typename PFP::REAL> >(VERTEX_ORBIT, "frame") ;
AttributeHandler<Geom::Matrix<3,6,typename PFP::REAL> > RGBfunctions = map.template getAttribute<Geom::Matrix<3,6,typename PFP::REAL> >(VERTEX_ORBIT, "RGBfunctions") ;
AttributeHandler<Geom::Matrix<3,6,typename PFP::REAL> > RGBfunctions = map.template getAttribute<Geom::Matrix<3,6,typename PFP::REAL> >(VERTEX_ORBIT, "colorPTM") ;
approximators.push_back(new Approximator_Frame<PFP>(map, frame)) ;
approximators.push_back(new Approximator_RGBfunctions<PFP>(map, RGBfunctions)) ;
break ;
}
case A_LightfieldHalf :
{
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, position)) ;
AttributeHandler<Geom::Matrix<3,3,typename PFP::REAL> > frame = map.template getAttribute<Geom::Matrix<3,3,typename PFP::REAL> >(VERTEX_ORBIT, "frame") ;
AttributeHandler<Geom::Matrix<3,6,typename PFP::REAL> > RGBfunctions = map.template getAttribute<Geom::Matrix<3,6,typename PFP::REAL> >(VERTEX_ORBIT, "colorPTM") ;
approximators.push_back(new Approximator_FrameHalf<PFP>(map, frame)) ;
approximators.push_back(new Approximator_RGBfunctionsHalf<PFP>(map, RGBfunctions)) ;
break ;
}
}
switch(s)
......@@ -82,18 +116,24 @@ void decimate(
case S_EdgeLength :
selector = new EdgeSelector_Length<PFP>(map, position, approximators) ;
break ;
case S_QEMml :
selector = new EdgeSelector_QEMml<PFP>(map, position, approximators) ;
break ;
case S_QEM :
selector = new EdgeSelector_QEM<PFP>(map, position, approximators) ;
break ;
case S_Lightfield :
selector = new EdgeSelector_Lightfield<PFP>(map, position, approximators) ;
break ;
case S_Curvature :
selector = new EdgeSelector_Curvature<PFP>(map, position, approximators) ;
break ;
case S_MinDetail :
selector = new EdgeSelector_Random<PFP>(map, position, approximators) ;
break ;
case S_hLightfield :
selector = new HalfEdgeSelector_Lightfield<PFP>(map, position, approximators) ;
break ;
case S_hQEMml :
selector = new HalfEdgeSelector_QEMml<PFP>(map, position, approximators) ;
break ;
}
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
......@@ -105,10 +145,16 @@ void decimate(
unsigned int nbVertices = map.getNbOrbits(VERTEX_ORBIT) ;
bool finished = false ;
Dart d ;
while(!finished)
{
if(!selector->nextEdge(d))
std::cout << "Countdown : " ;
std::cout << std::setprecision(8) << (nbVertices - nbWantedVertices) << "\r" << std::flush;
if(!selector->nextEdge(d)) {
std::cout << std::endl << "out" << std::endl ;
break ;
}
--nbVertices ;
......@@ -130,8 +176,10 @@ void decimate(
selector->updateAfterCollapse(d2, dd2) ;// update selector
if(nbVertices <= nbWantedVertices)
if(nbVertices <= nbWantedVertices) {
finished = true ;
std::cout << std::endl << "done" << std::endl ;
}
}
delete selector ;
......
This diff is collapsed.
......@@ -473,45 +473,34 @@ void EdgeSelector_QEM<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
m_positionApproximator->approximate(d) ;
REAL err = quad(m_positionApproximator->getApprox(d)) ;
REAL err = std::max(REAL(0),REAL(quad(m_positionApproximator->getApprox(d)))) ;
einfo.it = edges.insert(std::make_pair(err, d)) ;
einfo.valid = true ;
}
/************************************************************************************
* EDGESELECTOR LIGHTFIELD *
* QUADRIC ERROR METRIC (Memoryless version) *
************************************************************************************/
template <typename PFP>
bool EdgeSelector_Lightfield<PFP>::init()
bool EdgeSelector_QEMml<PFP>::init()
{
MAP& m = this->m_map ;
// Verify availability of required approximators
char ok = 0 ;
bool ok = false ;
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = this->m_approximators.begin();
it != this->m_approximators.end();
it != this->m_approximators.end() && !ok;
++it)
{
// constraint : 3 approximators in specific order
if(ok == 0 && (*it)->getApproximatedAttributeName() == "position")
{
m_positionApproximator = reinterpret_cast<Approximator<PFP, VEC3>* >(*it) ; // 1) position
++ok ;
}
else if( ok == 1 && (*it)->getApproximatedAttributeName() == "frame")
{
m_frameApproximator = reinterpret_cast<Approximator<PFP, FRAME>* >(*it) ; // 2) frame (needs position)
++ok ;
}
else if(ok == 2 && (*it)->getApproximatedAttributeName() == "RGBfunctions")
if((*it)->getApproximatedAttributeName() == "position")
{
m_RGBfunctionsApproximator = reinterpret_cast<Approximator<PFP, RGBFUNCTIONS>* >(*it) ; // 3) functions (needs frame)
++ok ;
m_positionApproximator = reinterpret_cast<Approximator<PFP, VEC3>* >(*it) ;
ok = true ;
}
}
if(ok != 3)
if(!ok)
return false ;
edges.clear() ;
......@@ -521,24 +510,23 @@ bool EdgeSelector_Lightfield<PFP>::init()
{
if(!vMark.isMarked(d))
{
Quadric<REAL> q ; // create one quadric
quadric[d] = q ; // per vertex
Quadric<REAL> q ; // create one quadric
quadric[d] = q ; // per vertex
vMark.mark(d) ;
}
}
DartMarker mark(m) ;
for(Dart d = m.begin(); d != m.end(); m.next(d)) // init QEM quadrics
for(Dart d = m.begin(); d != m.end(); m.next(d))
{
if(!mark.isMarked(d))
{
Dart d1 = m.phi1(d) ; // for each triangle,
Dart d_1 = m.phi_1(d) ; // initialize the quadric of the triangle
Dart d1 = m.phi1(d) ; // for each triangle,
Dart d_1 = m.phi_1(d) ; // initialize the quadric of the triangle
Quadric<REAL> q(this->m_position[d], this->m_position[d1], this->m_position[d_1]) ;
quadric[d] += q ; // and add the contribution of
quadric[d1] += q ; // this quadric to the ones
quadric[d_1] += q ; // of the 3 incident vertices
quadric[d] += q ; // and add the contribution of
quadric[d1] += q ; // this quadric to the ones
quadric[d_1] += q ; // of the 3 incident vertices
mark.markOrbit(FACE_ORBIT, d) ;
}
}
......@@ -548,7 +536,7 @@ bool EdgeSelector_Lightfield<PFP>::init()
{
if(!eMark.isMarked(d))
{
initEdgeInfo(d) ; // init the edges with their optimal info
initEdgeInfo(d) ; // init the edges with their optimal position
eMark.mark(d) ; // and insert them in the multimap according to their error
}
}
......@@ -559,7 +547,7 @@ bool EdgeSelector_Lightfield<PFP>::init()
}
template <typename PFP>
bool EdgeSelector_Lightfield<PFP>::nextEdge(Dart& d)
bool EdgeSelector_QEMml<PFP>::nextEdge(Dart& d)
{
if(cur == edges.end() || edges.empty())
return false ;
......@@ -568,7 +556,7 @@ bool EdgeSelector_Lightfield<PFP>::nextEdge(Dart& d)
}
template <typename PFP>
void EdgeSelector_Lightfield<PFP>::updateBeforeCollapse(Dart d)
void EdgeSelector_QEMml<PFP>::updateBeforeCollapse(Dart d)
{
MAP& m = this->m_map ;
......@@ -595,39 +583,65 @@ void EdgeSelector_Lightfield<PFP>::updateBeforeCollapse(Dart d)
if(edgeE.valid)
edges.erase(edgeE.it) ;
}
}
tmpQ.zero() ; // compute quadric for the new
tmpQ += quadric[d] ; // vertex as the sum of those
tmpQ += quadric[dd] ; // of the contracted vertices
/**
* Update quadric of a vertex
* Discards quadrics of d and assigns freshly calculated
* quadrics depending on the actual planes surrounding d
* @param dart d
*/
template <typename PFP>
void EdgeSelector_QEMml<PFP>::recomputeQuadric(const Dart d, const bool recomputeNeighbors) {
Dart dFront,dBack ;
Dart dInit = d ;
// Init Front
dFront = dInit ;
quadric[d].zero() ;
do {
// Make step
dBack = this->m_map.phi2(dFront) ;
dFront = this->m_map.alpha1(dFront) ;
if (dBack != dFront) { // if dFront is no border
quadric[d] += Quadric<REAL>(this->m_position[d],this->m_position[this->m_map.phi2(dFront)],this->m_position[dBack]) ;
}
if (recomputeNeighbors)
recomputeQuadric(dBack, false) ;
} while(dFront != dInit) ;
}
template <typename PFP>
void EdgeSelector_Lightfield<PFP>::updateAfterCollapse(Dart d2, Dart dd2)
void EdgeSelector_QEMml<PFP>::updateAfterCollapse(Dart d2, Dart dd2)
{
MAP& m = this->m_map ;
quadric[d2] = tmpQ ;
// for local vertex and neighbors
recomputeQuadric(d2, true) ;
Dart vit = d2 ;
do
{
updateEdgeInfo(m.phi1(vit), false) ; // must recompute some edge infos in the
if(vit == d2 || vit == dd2) // neighborhood of the collapsed edge
{
initEdgeInfo(vit) ; // various optimizations are applied here by
// treating differently :
Dart vit2 = m.alpha_1(m.phi1(vit)) ; // - edges for which the criteria must be recomputed
Dart stop = m.phi2(vit) ; // - edges that must be re-embedded
do // - edges for which only the collapsibility must be re-tested
{
updateEdgeInfo(vit2, false) ;
updateEdgeInfo(m.phi1(vit2), false) ;
vit2 = m.alpha_1(vit2) ;
} while(vit2 != stop) ;
}
else
updateEdgeInfo(m.phi1(vit), true) ; // must recompute some edge infos in the
if(vit == d2 || vit == dd2) // neighborhood of the collapsed edge
initEdgeInfo(vit) ; // various optimizations are applied here by
else // treating differently :
updateEdgeInfo(vit, true) ;
Dart vit2 = m.alpha_1(m.phi1(vit)) ; // - edges for which the criteria must be recomputed
Dart stop = m.phi2(vit) ; // - edges that must be re-embedded
do // - edges for which only the collapsibility must be re-tested
{
updateEdgeInfo(vit2, true) ;
updateEdgeInfo(m.phi1(vit2), false) ;
vit2 = m.alpha_1(vit2) ;
} while(vit2 != stop) ;
vit = m.alpha1(vit) ;
} while(vit != d2) ;
......@@ -635,7 +649,7 @@ void EdgeSelector_Lightfield<PFP>::updateAfterCollapse(Dart d2, Dart dd2)
}
template <typename PFP>
void EdgeSelector_Lightfield<PFP>::initEdgeInfo(Dart d)
void EdgeSelector_QEMml<PFP>::initEdgeInfo(Dart d)
{
MAP& m = this->m_map ;
EdgeInfo einfo ;
......@@ -647,14 +661,14 @@ void EdgeSelector_Lightfield<PFP>::initEdgeInfo(Dart d)
}
template <typename PFP>
void EdgeSelector_Lightfield<PFP>::updateEdgeInfo(Dart d, bool recompute)
void EdgeSelector_QEMml<PFP>::updateEdgeInfo(Dart d, bool recompute)
{
MAP& m = this->m_map ;
EdgeInfo& einfo = edgeInfo[d] ;
if(recompute)
{
if(einfo.valid)
edges.erase(einfo.it) ; // remove the edge from the multimap
edges.erase(einfo.it) ; // remove the edge from the multimap
if(m.edgeCanCollapse(d))
computeEdgeInfo(d, einfo) ;
else
......@@ -664,7 +678,7 @@ void EdgeSelector_Lightfield<PFP>::updateEdgeInfo(Dart d, bool recompute)
{
if(m.edgeCanCollapse(d))
{ // if the edge can be collapsed now
if(!einfo.valid) // but it was not before
if(!einfo.valid) // but it was not before
computeEdgeInfo(d, einfo) ;
}
else
......@@ -679,42 +693,18 @@ void EdgeSelector_Lightfield<PFP>::updateEdgeInfo(Dart d, bool recompute)
}
template <typename PFP>
void EdgeSelector_Lightfield<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
void EdgeSelector_QEMml<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
{
MAP& m = this->m_map ;
Dart dd = m.phi2(d) ;
// New position
Quadric<REAL> quad ;
quad += quadric[d] ; // compute the sum of the
quad += quadric[dd] ; // two vertices quadrics
this->m_positionApproximator->approximate(d) ; // sets newPos
VEC3 newPos = this->m_positionApproximator->getApprox(d) ; // get newPos
// New Frame
this->m_frameApproximator->approximate(d) ; // sets newF
MATRIX33 newFrame = this->m_frameApproximator->getApprox(d) ; // get newF
VEC3 n1,n2 ;
if (! m_frame[d].getSubVectorH(3,1,n1)) { // get the normals
std::cout << "EdgeSelector_LightField::computeEdgeInfo --> getSubVectorH 1 failed " << std::endl;
exit(2) ;
}
if (!m_frame[dd].getSubVectorH(3,1,n2)) { // of the two vertices
std::cout << "EdgeSelector_LightField::computeEdgeInfo --> getSubVectorH 2 failed " << std::endl;
exit(3) ;
}
// New function
this->m_RGBfunctionsApproximator->approximate(d) ; // sets quadricRGBf and newRGBf
MATRIX36 newRGBf = this->m_RGBfunctionsApproximator->getApprox(d) ; // get newRGBf
QuadricRGBfunctions<typename PFP::REAL> quadRGBf = quadricRGBfunctions[d]; // get quadricRGBf
// ?? test if quadRGBf is valid
m_positionApproximator->approximate(d) ;
// Compute error
REAL err = quad(newPos) + (2 * acos (n1 * n2)) + quadRGBf(newRGBf) ;
REAL err = quad(m_positionApproximator->getApprox(d)) ;
einfo.it = edges.insert(std::make_pair(err, d)) ;
einfo.valid = true ;
}
......
......@@ -58,6 +58,28 @@ public:
void approximate(Dart d) ;
} ;
template <typename PFP>
class Approximator_QEMhalfEdge : public Approximator<PFP, typename PFP::VEC3>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
protected:
AttributeHandler<Quadric<REAL> > m_quadric ;
public:
Approximator_QEMhalfEdge(MAP& m, AttributeHandler<VEC3>& pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3>(m, pos, EDGE_ORBIT, pred)
{}
~Approximator_QEMhalfEdge()
{}
ApproximatorType getType() const { return A_QEMhalfEdge ; }
bool init() ;
void approximate(Dart d) ;
} ;
template <typename PFP>
class Approximator_MidEdge : public Approximator<PFP, typename PFP::VEC3>
{
......
......@@ -105,6 +105,69 @@ void Approximator_QEM<PFP>::approximate(Dart d)
this->m_approx[d] = res ;
}
/************************************************************************************
* QUADRIC ERROR METRIC (for half-edge criteria) *
************************************************************************************/
template <typename PFP>
bool Approximator_QEMhalfEdge<PFP>::init()
{
m_quadric = this->m_map.template getAttribute<Quadric<REAL> >(VERTEX_ORBIT, "QEMquadric") ;
if(this->m_predictor)
{
return false ;
}
return true ;
}
template <typename PFP>
void Approximator_QEMhalfEdge<PFP>::approximate(Dart d)
{
MAP& m = this->m_map ;
// get some darts
Dart dd = m.phi2(d) ;
Quadric<REAL> q1, q2 ;
if(!m_quadric.isValid()) // if the selector is not QEM, compute local error quadrics
{
// compute the error quadric associated to v1
Dart it = d ;
do
{
Quadric<REAL> q(this->m_attrV[it], this->m_attrV[m.phi1(it)], this->m_attrV[m.phi_1(it)]) ;
q1 += q ;
it = m.alpha1(it) ;
} while(it != d) ;
// compute the error quadric associated to v2
it = dd ;
do
{
Quadric<REAL> q(this->m_attrV[it], this->m_attrV[m.phi1(it)], this->m_attrV[m.phi_1(it)]) ;
q2 += q ;
it = m.alpha1(it) ;
} while(it != dd) ;
}
else // if the selector is QEM, use the error quadrics computed by the selector
{
q1 = m_quadric[d] ;
q2 = m_quadric[dd] ;
}
Quadric<REAL> quad ;
quad += q1 ; // compute the sum of the
quad += q2 ; // two vertices quadrics
VEC3 res ;
bool opt = quad.findOptimizedPos(res) ; // try to compute an optimized position for the contraction of this edge
if(!opt)
this->m_approx[d] = this->m_attrV[d] ;
else
this->m_approx[d] = res ;
}
/************************************************************************************
* MID EDGE *
************************************************************************************/
......
/*******************************************************************************
* 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 __HALFEDGESELECTOR_H__
#define __HALFEDGESELECTOR_H__
#include "Algo/Decimation/selector.h"
namespace CGoGN
{
namespace Algo
{
namespace Decimation
{
template <typename PFP>
class HalfEdgeSelector_QEMml : 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 "QEMhalfEdgeInfo" ; }
} QEMhalfEdgeInfo ;
typedef NoMathIOAttribute<QEMhalfEdgeInfo> HalfEdgeInfo ;
AttributeHandler<HalfEdgeInfo> halfEdgeInfo ;
AttributeHandler<Quadric<REAL> > quadric ;
std::multimap<float,Dart> halfEdges ;
typename std::multimap<float,Dart>::iterator cur ;
Approximator<PFP, typename PFP::VEC3>* m_positionApproximator ;
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_QEMml(MAP& m, typename PFP::TVEC3& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = SelectorTrue()) :
EdgeSelector<PFP>(m, pos, approx, select)
{
halfEdgeInfo = m.template addAttribute<HalfEdgeInfo>(DART_ORBIT, "halfEdgeInfo") ;
quadric = m.template addAttribute<Quadric<REAL> >(VERTEX_ORBIT, "QEMquadric") ;
}
~HalfEdgeSelector_QEMml()
{
this->m_map.removeAttribute(quadric) ;
this->m_map.removeAttribute(halfEdgeInfo) ;
}
SelectorType getType() { return S_hQEMml ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
} ;
template <typename PFP>
class HalfEdgeSelector_Lightfield : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
typedef Geom::Matrix<3,3,REAL> MATRIX33 ;
typedef Geom::Matrix<3,6,REAL> MATRIX36 ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "LightfieldHalfEdgeInfo" ; }
} LightfieldHalfEdgeInfo ;
typedef NoMathIOAttribute<LightfieldHalfEdgeInfo> HalfEdgeInfo ;
AttributeHandler<MATRIX33 > m_frame ;
AttributeHandler<HalfEdgeInfo> halfEdgeInfo ;
AttributeHandler<Quadric<REAL> > quadric ;
AttributeHandler<QuadricRGBfunctions<REAL> > quadricRGBfunctions ;
std::multimap<float,Dart> halfEdges ;
typename std::multimap<float,Dart>::iterator cur ;
Approximator<PFP, VEC3>* m_positionApproximator ;
Approximator<PFP, MATRIX33 >* m_frameApproximator ;
Approximator<PFP, MATRIX36 >* m_RGBfunctionsApproximator ;
void initHalfEdgeInfo(Dart d) ;
void updateHalfEdgeInfo(Dart d, bool recompute) ;
void computeHalfEdgeInfo(Dart d, HalfEdgeInfo& einfo) ;
void recomputeQuadric(const Dart d, const bool recomputeNeighbors) ;
public:
HalfEdgeSelector_Lightfield(MAP& m, typename PFP::TVEC3& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = SelectorTrue()) :
EdgeSelector<PFP>(m, pos, approx, select)
{
m_frame = m.template getAttribute<MATRIX33>(VERTEX_ORBIT, "frame") ;
halfEdgeInfo = m.template addAttribute<HalfEdgeInfo>(DART_ORBIT, "halfEdgeInfo") ;
quadric = m.template addAttribute<Quadric<REAL> >(VERTEX_ORBIT, "QEMquadric") ;
quadricRGBfunctions = m.template addAttribute<QuadricRGBfunctions<REAL> >(EDGE_ORBIT, "quadricRGBfunctions") ;
}
~HalfEdgeSelector_Lightfield()
{
this->m_map.removeAttribute(quadric) ;
this->m_map.removeAttribute(quadricRGBfunctions) ;
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) ;
} ;
/*
template <typename PFP>
class EdgeSelector_Lightfield : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
typedef Geom::Matrix<3,3,REAL> MATRIX33 ;
typedef MATRIX33 FRAME ;
typedef Geom::Matrix<3,6,REAL> MATRIX36 ;
typedef MATRIX36 RGBFUNCTIONS ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "LightfieldEdgeInfo" ; }
} LightfieldEdgeInfo ;
typedef NoMathIOAttribute<LightfieldEdgeInfo> EdgeInfo ;
AttributeHandler<FRAME > m_frame ;