Commit 0d36fdf8 authored by Kenneth Vanhoey's avatar Kenneth Vanhoey

Cleanup and reorganisation of decimation

parent 60bae45d
......@@ -48,9 +48,9 @@ enum ApproximatorType
// note: the following "h" prefix means that half-edges are prioritized instead of edges.
A_hHalfCollapse,
A_hQEM,
A_hLightfieldHalf/*,
A_LightfieldHalf_deprecated,
A_LightfieldFull_deprecated*/
A_hLightfieldHalf,
A_hLightfield
} ;
template <typename PFP>
......@@ -131,7 +131,6 @@ public:
{
for (unsigned int i = 0 ; i < m_attrV.size() ; ++i)
{
std::cout << "delete " << m_approx[i].name() << std::endl ;
this->m_map.template removeAttribute(m_approx[i]) ;
if(m_predictor)
this->m_map.template removeAttribute(m_detail[i]) ;
......
......@@ -45,7 +45,7 @@ void decimate(
typename PFP::MAP& map,
SelectorType s,
ApproximatorType a,
VertexAttribute<typename PFP::VEC3>& position,
std::vector<VertexAttribute<typename PFP::VEC3> *>& position,
unsigned int nbWantedVertices,
const FunctorSelect& selected = allDarts,
void (*callback_wrapper)(void*, const void*) = NULL, void *callback_object = NULL
......
......@@ -34,10 +34,14 @@ namespace Decimation
template <typename PFP>
void decimate(
typename PFP::MAP& map, SelectorType s, ApproximatorType a,
VertexAttribute<typename PFP::VEC3>& position, unsigned int nbWantedVertices, const FunctorSelect& selected,
std::vector<VertexAttribute<typename PFP::VEC3>* >& attribs, unsigned int nbWantedVertices, const FunctorSelect& selected,
void (*callback_wrapper)(void*, const void*), void* callback_object
)
{
assert(attribs.size() >= 1 || !"Decimate: not enough attribs provided") ;
assert(attribs[0]->name() == "position" || !"Decimate: first attribute is not position") ;
VertexAttribute<typename PFP::VEC3> position = *(attribs[0]) ;
std::vector<ApproximatorGen<PFP>*> approximators ;
EdgeSelector<PFP>* selector = NULL ;
......@@ -46,185 +50,85 @@ void decimate(
switch(a)
{
case A_QEM :
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
v_approx[0].push_back(&position) ;
approximators.push_back(new Approximator_QEM<PFP>(map, v_approx[0])) ;
approximators.push_back(new Approximator_QEM<PFP>(map, attribs)) ;
break ;
case A_MidEdge :
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
v_approx[0].push_back(&position) ;
approximators.push_back(new Approximator_MidEdge<PFP>(map, v_approx[0])) ;
approximators.push_back(new Approximator_MidEdge<PFP>(map, attribs)) ;
break ;
case A_CornerCutting :
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
v_approx[0].push_back(&position) ;
approximators.push_back(new Approximator_CornerCutting<PFP>(map, v_approx[0])) ;
approximators.push_back(new Approximator_CornerCutting<PFP>(map, attribs)) ;
break ;
case A_TangentPredict1 :
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
v_approx[0].push_back(&position) ;
approximators.push_back(new Approximator_MidEdge<PFP>(map, v_approx[0])) ;
approximators.push_back(new Approximator_MidEdge<PFP>(map, attribs)) ;
break ;
case A_TangentPredict2 :
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
v_approx[0].push_back(&position) ;
approximators.push_back(new Approximator_MidEdge<PFP>(map, v_approx[0])) ;
approximators.push_back(new Approximator_MidEdge<PFP>(map, attribs)) ;
break ;
case A_hHalfCollapse :
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
v_approx[0].push_back(&position) ;
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, v_approx[0])) ;
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, attribs)) ;
break ;
case A_ColorNaive :
{
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[2] ;
// pos
v_approx[0].push_back(&position) ;
v_approx[0].push_back(attribs[0]) ;
approximators.push_back(new Approximator_QEM<PFP>(map, v_approx[0])) ;
// col
VertexAttribute<typename PFP::VEC3> *colors = new VertexAttribute<typename PFP::VEC3>() ;
*colors = map.template getAttribute<typename PFP::VEC3, VERTEX>("color") ;
v_approx[1].push_back(colors) ;
assert(attribs.size() >= 2 || !"Decimate: A_ColorNaive --> not enough attribs provided") ;
v_approx[1].push_back(attribs[1]) ;
approximators.push_back(new Approximator_ColorNaive<PFP>(map, v_approx[1])) ;
}
break ;
case A_ColorQEMext :
{
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
// pos + col
v_approx[0].push_back(&position) ; // pos
VertexAttribute<typename PFP::VEC3> *colors = new VertexAttribute<typename PFP::VEC3>() ;
*colors = map.template getAttribute<typename PFP::VEC3, VERTEX>("color") ;
v_approx[0].push_back(colors) ; // col
approximators.push_back(new Approximator_ColorQEMext<PFP>(map, v_approx[0])) ;
assert(attribs.size() >= 2 || !"Decimate: A_ColorQEMext --> not enough attribs provided") ;
approximators.push_back(new Approximator_ColorQEMext<PFP>(map, attribs)) ;
}
break;
case A_hQEM :
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
// pos
v_approx[0].push_back(&position) ;
approximators.push_back(new Approximator_QEMhalfEdge<PFP>(map, v_approx[0])) ;
approximators.push_back(new Approximator_QEMhalfEdge<PFP>(map, attribs)) ;
break ;
case A_hLightfieldHalf :
// case A_hLightfieldHalf:
// v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[3] ;
//
// // pos
// v_approx[0].push_back(attribs[0]) ;
// approximators.push_back(new Approximator_HalfCollapse<PFP>(map, v_approx[0])) ;
//
// // frame
// assert(attribs.size() >= 4 || !"Decimate: A_LightfieldHalf --> not enough attribs provided") ;
// for (unsigned int i = 0 ; i < 3 ; ++i)
// v_approx[1].push_back(attribs[i+1]) ;
// approximators.push_back(new Approximator_FrameHalf<PFP>(map, v_approx[1])) ;
//
// // hemifunction
// assert(attribs.size() >= 5 || !"Decimate: A_LightfieldHalf --> not enough attribs provided") ;
// for (unsigned int i = 0 ; i < attribs.size() - 4 ; ++i)
// v_approx[2].push_back(attribs[i+4]) ;
// approximators.push_back(new Approximator_LightfieldCoefsHalf<PFP>(map, v_approx[2])) ;
// break ;
case A_hLightfield :
{
v_approx = new std::vector<VertexAttribute<typename PFP::VEC3>* >[1] ;
// pos
v_approx[0].push_back(&position) ;
// frame
VertexAttribute<typename PFP::VEC3> *FT = new VertexAttribute<typename PFP::VEC3>() ;
VertexAttribute<typename PFP::VEC3> *FB = new VertexAttribute<typename PFP::VEC3>() ;
VertexAttribute<typename PFP::VEC3> *FN = new VertexAttribute<typename PFP::VEC3>() ;
*FT = map.template getAttribute<typename PFP::VEC3, VERTEX>("frameT") ;
*FB = map.template getAttribute<typename PFP::VEC3, VERTEX>("frameB") ;
*FN = map.template getAttribute<typename PFP::VEC3, VERTEX>("frameN") ;
v_approx[0].push_back(FT) ;
v_approx[0].push_back(FB) ;
v_approx[0].push_back(FN) ;
// function coefs
unsigned int k = 0 ;
do
{
std::stringstream s ; s << "PBcoefs" << k ;
VertexAttribute<typename PFP::VEC3> *attr = new VertexAttribute<typename PFP::VEC3>() ;
*attr = map.template getAttribute<typename PFP::VEC3, VERTEX>(s.str()) ;
v_approx[0].push_back(attr) ;
} while(v_approx[0][4 + k++]->isValid()) ;
v_approx[0].pop_back() ; --k ;
// const bool& sh = v_all.size() < 5 ; // sh or pb
do
{
std::stringstream s ; s << "SHcoefs" << k ;
VertexAttribute<typename PFP::VEC3> *attr = new VertexAttribute<typename PFP::VEC3>() ;
*attr = map.template getAttribute<typename PFP::VEC3, VERTEX>(s.str()) ;
v_approx[0].push_back(attr) ;
} while(v_approx[0][4 + k++]->isValid()) ;
v_approx[0].pop_back() ;
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, v_approx[0])) ;
// pos + frame + hemifunction
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, attribs)) ;
}
break ;
/*case A_LightfieldHalf:
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, position)) ;
// Get all frame embeddings
std::vector<VertexAttribute<PFP::VEC3>* > vertexAttributesFrame ;
VertexAttribute<PFP::VEC3> frame0 = myMap.getAttribute<PFP::VEC3, VERTEX>("frameT") ; vertexAttributesFrame.push_back(&frame0) ;
VertexAttribute<PFP::VEC3> frame1 = myMap.getAttribute<PFP::VEC3, VERTEX>("frameB") ; vertexAttributesFrame.push_back(&frame1) ;
VertexAttribute<PFP::VEC3> frame2 = myMap.getAttribute<PFP::VEC3, VERTEX>("frameN") ; vertexAttributesFrame.push_back(&frame2) ;
approximators.push_back(new Approximator_FrameHalf<PFP>(map, vertexAttributesFrame)) ; // TODO
// Get all coefficient embeddings
const unsigned int K = 200 ;
std::vector<VertexAttribute<PFP::VEC3>* > vertexAttributesCoefs ;
VertexAttribute<PFP::VEC3> *PBcoefs = new VertexAttribute<PFP::VEC3>[K] ;
for (unsigned int k = 0 ; k < K ; ++k)
{
std::stringstream s ;
s << "PBcoefs" << k ;
PBcoefs[k] = myMap.getAttribute<PFP::VEC3, VERTEX>(s.str()) ;
if (!PBcoefs[k].isValid())
break ;
vertexAttributesCoefs.push_back(&PBcoefs[k]) ;
}
const bool& sh = vertexAttributesCoefs.empty() ; // sh or pb
VertexAttribute<PFP::VEC3> *SHcoefs = new VertexAttribute<PFP::VEC3>[K] ;
for (unsigned int k = 0 ; k < K ; ++k)
{
std::stringstream s ;
s << "SHcoefs" << k ;
SHcoefs[k] = myMap.getAttribute<PFP::VEC3, VERTEX>(s.str()) ;
if (!SHcoefs[k].isValid())
break ;
vertexAttributesCoefs.push_back(&SHcoefs[k]) ;
}
approximators.push_back(new Approximator_LightfieldCoefsHalf<PFP>(map, vertexAttributesCoefs, sh)) ; // TODO
break ;
/*
case A_LightfieldFull_deprecated :
{
approximators.push_back(new Approximator_QEMhalfEdge<PFP>(map, position)) ;
/ *
PFP::TVEC3 frame[3] ;
frame[0] = map.template getAttribute<typename PFP::VEC3, VERTEX>("frame_T") ; // Tangent
frame[1] = map.template getAttribute<typename PFP::VEC3, VERTEX>("frame_B") ; // Bitangent
frame[2] = map.template getAttribute<typename PFP::VEC3, VERTEX>("frame_N") ; // Normal
for (unsigned int i = 0 ; i < 3 ; ++i)
if (!frame[i].isValid()) {
CGoGNerr << "In function decimate : frame[" << i << "] is not valid" << CGoGNendl ;
}
VertexAttribute<typename PFP::VEC3> colorPTM[6] ;
colorPTM[0] = map.template getAttribute<typename PFP::VEC3, VERTEX>("colorPTM_a") ;
colorPTM[1] = map.template getAttribute<typename PFP::VEC3, VERTEX>("colorPTM_b") ;
colorPTM[2] = map.template getAttribute<typename PFP::VEC3, VERTEX>("colorPTM_c") ;
colorPTM[3] = map.template getAttribute<typename PFP::VEC3, VERTEX>("colorPTM_d") ;
colorPTM[4] = map.template getAttribute<typename PFP::VEC3, VERTEX>("colorPTM_e") ;
colorPTM[5] = map.template getAttribute<typename PFP::VEC3, VERTEX>("colorPTM_f") ;
for (unsigned int i = 0 ; i < 6 ; ++i)
if (!colorPTM[i].isValid()) {
CGoGNerr << "In function decimate : colorPTM[" << i << "] is not valid" << CGoGNendl ;
}
*
VertexAttribute<Geom::Matrix<3,3,typename PFP::REAL> > frame = map.template getAttribute<Geom::Matrix<3,3,typename PFP::REAL>, VERTEX>("frame") ;
VertexAttribute<Geom::Matrix<3,6,typename PFP::REAL> > RGBfunctions = map.template getAttribute<Geom::Matrix<3,6,typename PFP::REAL>, VERTEX>("colorPTM") ;
approximators.push_back(new Approximator_Frame_deprecated<PFP>(map, frame)) ;
approximators.push_back(new Approximator_RGBfunctions_deprecated<PFP>(map, RGBfunctions)) ;
break ;
}
case A_LightfieldHalf_deprecated :
{
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, position)) ;
VertexAttribute<Geom::Matrix<3,3,typename PFP::REAL> > frame = map.template getAttribute<Geom::Matrix<3,3,typename PFP::REAL>, VERTEX>("frame") ;
VertexAttribute<Geom::Matrix<3,6,typename PFP::REAL> > RGBfunctions = map.template getAttribute<Geom::Matrix<3,6,typename PFP::REAL>, VERTEX>("colorPTM") ;
approximators.push_back(new Approximator_FrameHalf_deprecated<PFP>(map, frame)) ;
approximators.push_back(new Approximator_RGBfunctionsHalf_deprecated<PFP>(map, RGBfunctions)) ;
break ;
}*/
*/
}
switch(s)
......@@ -271,11 +175,11 @@ void decimate(
{
delete selector ;
delete[] v_approx ;
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
delete (*it) ;
delete[] v_approx ;
return ;
}
......@@ -323,10 +227,10 @@ void decimate(
delete selector ;
delete[] v_approx ;
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
delete (*it) ;
delete[] v_approx ;
}
} //namespace Decimation
......
......@@ -82,7 +82,9 @@ private:
public:
EdgeSelector_Random(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
EdgeSelector<PFP>(m, pos, approx, select)
EdgeSelector<PFP>(m, pos, approx, select),
cur(0),
allSkipped(false)
{}
~EdgeSelector_Random()
{}
......@@ -400,15 +402,17 @@ private:
typedef NoMathIOAttribute<ColorNaiveedgeInfo> EdgeInfo ;
EdgeAttribute<EdgeInfo> edgeInfo ;
VertexAttribute<VEC3> m_color ;
VertexAttribute<Quadric<REAL> > m_quadric ;
VertexAttribute<VEC3> m_pos, m_color ;
int m_approxindex_pos, m_attrindex_pos ;
int m_approxindex_color, m_attrindex_color ;
std::vector<Approximator<PFP, typename PFP::VEC3>* > m_approx ;
std::multimap<float,Dart> edges ;
typename std::multimap<float,Dart>::iterator cur ;
Approximator<PFP, typename PFP::VEC3>* m_positionApproximator ;
Approximator<PFP, typename PFP::VEC3>* m_colorApproximator ;
void initEdgeInfo(Dart d) ;
void updateEdgeInfo(Dart d, bool recompute) ;
void computeEdgeInfo(Dart d,EdgeInfo& einfo) ;
......@@ -417,14 +421,13 @@ private:
public:
EdgeSelector_ColorNaive(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = allDarts) :
EdgeSelector<PFP>(m, pos, approx, select),
m_positionApproximator(NULL),
m_colorApproximator(NULL)
m_approxindex_pos(-1),
m_attrindex_pos(-1),
m_approxindex_color(-1),
m_attrindex_color(-1)
{
edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
m_quadric = m.template addAttribute<Quadric<REAL>, VERTEX>("QEMquadric") ;
m_color = m.template getAttribute<VEC3, VERTEX>("color") ;
assert(m_color.isValid() || !"EdgeSelector_ColorNaive: Color atrribute to select is not valid") ;
}
~EdgeSelector_ColorNaive()
{
......@@ -463,11 +466,9 @@ private:
VertexAttribute<QuadricNd<REAL,6> > m_quadric ;
VertexAttribute<VEC3> m_pos, m_color ;
//VertexAttribute<VEC3> *m_HF ;
int m_approxindex_pos, m_attrindex_pos ;
int m_approxindex_color, m_attrindex_color ;
// Approximator<PFP, typename PFP::VEC3>* m_poscolApproximator ;
std::vector<Approximator<PFP, typename PFP::VEC3>* > m_approx ;
std::multimap<float,Dart> edges ;
......@@ -481,7 +482,6 @@ private:
public:
EdgeSelector_QEMextColor(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = allDarts) :
EdgeSelector<PFP>(m, pos, approx, select),
// m_poscolApproximator(NULL),
m_approxindex_pos(-1),
m_attrindex_pos(-1),
m_approxindex_color(-1),
......
......@@ -1104,27 +1104,43 @@ bool EdgeSelector_ColorNaive<PFP>::init()
{
MAP& m = this->m_map ;
assert(this->m_approximators[0]->getType() != A_hQEM || !"Approximator(hQEM) and selector (ColorNaive) are not compatible") ;
assert(this->m_approximators[0]->getType() != A_hHalfCollapse || !"Approximator(hHalfCollapse) and selector (ColorNaive) are not compatible") ;
assert(this->m_approximators[0]->getType() != A_hLightfieldHalf || !"Approximator(hLightfieldHalf) and selector (ColorNaive) are not compatible") ;
// Verify availability of required approximators
char ok = 0 ;
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = this->m_approximators.begin();
it != this->m_approximators.end();
++it)
unsigned int ok = 0 ;
for (unsigned int approxindex = 0 ; approxindex < this->m_approximators.size() ; ++approxindex)
{
// constraint : 2 approximators in specific order
if(ok == 0 && (*it)->getApproximatedAttributeName(0) == "position")
{
m_positionApproximator = reinterpret_cast<Approximator<PFP, VEC3>* >(*it) ; // 1) position
// check incompatibilities
assert(m_positionApproximator->getType() != A_hQEM || !"Approximator(hQEM) and selector (ColorNaive) are not compatible") ;
assert(m_positionApproximator->getType() != A_hHalfCollapse || !"Approximator(hHalfCollapse) and selector (ColorNaive) are not compatible") ;
assert(m_positionApproximator->getType() != A_hLightfieldHalf || !"Approximator(hLightfieldHalf) and selector (ColorNaive) are not compatible") ;
++ok ;
}
else if( ok == 1 && (*it)->getApproximatedAttributeName(0) == "color")
bool saved = false ;
for (unsigned int attrindex = 0 ; attrindex < this->m_approximators[approxindex]->getNbApproximated() ; ++ attrindex)
{
m_colorApproximator = reinterpret_cast<Approximator<PFP, VEC3>* >(*it) ; // 2) color (needs position)
++ok ;
// constraint : 2 approximators in specific order
if(ok == 0 && this->m_approximators[approxindex]->getApproximatedAttributeName(attrindex) == "position")
{
++ok ;
m_approxindex_pos = approxindex ;
m_attrindex_pos = attrindex ;
m_pos = this->m_position ;
if (!saved)
{
m_approx.push_back(reinterpret_cast<Approximator<PFP, VEC3>* >(this->m_approximators[approxindex])) ;
saved = true ;
}
}
else if(ok == 1 && this->m_approximators[approxindex]->getApproximatedAttributeName(attrindex) == "color")
{
++ok ;
m_approxindex_color = approxindex ;
m_attrindex_color = attrindex ;
m_color = m.template getAttribute<typename PFP::VEC3, VERTEX>("color") ;
assert(m_color.isValid() || !"EdgeSelector_ColorNaive: color attribute is not valid") ;
if (!saved)
{
m_approx.push_back(reinterpret_cast<Approximator<PFP, VEC3>* >(this->m_approximators[approxindex])) ;
saved = true ;
}
}
}
}
......@@ -1320,23 +1336,28 @@ void EdgeSelector_ColorNaive<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
quad += m_quadric[d] ; // compute the sum of the
quad += m_quadric[dd] ; // two vertices quadrics
this->m_positionApproximator->approximate(d) ; // sets newPos
VEC3 newPos = this->m_positionApproximator->getApprox(d) ; // get newPos
// compute all approximated attributes
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = this->m_approximators.begin() ;
it != this->m_approximators.end() ;
++it)
{
(*it)->approximate(d) ;
}
// New color
this->m_colorApproximator->approximate(d) ; // sets new color
const VEC3& newColor = this->m_colorApproximator->getApprox(d) ; // get new color
// get pos
const VEC3& newPos = this->m_approx[m_approxindex_pos]->getApprox(d,m_attrindex_pos) ; // get newPos
// get col
const VEC3& newCol = this->m_approx[m_approxindex_color]->getApprox(d,m_attrindex_color) ; // get newPos
// Compute error
VEC3 colDiff1 = newColor ;
VEC3 colDiff2 = newColor ;
const VEC3& oldCol1 = m_color[d] ;
const VEC3& oldCol2 = m_color[dd] ;
colDiff1 -= oldCol1 ;
colDiff2 -= oldCol2 ;
// compute error
VEC3 colDiff1 = newCol ;
VEC3 colDiff2 = newCol ;
colDiff1 -= m_color[d] ;
colDiff2 -= m_color[dd] ;
const VEC3& colDiff = colDiff1 + colDiff2 ;
// sum of QEM metric and squared difference between new color and old colors
REAL err = quad(newPos) + colDiff1.norm() + colDiff2.norm() ;
REAL err = quad(newPos) + colDiff.norm() ;
einfo.it = edges.insert(std::make_pair(err, d)) ;
einfo.valid = true ;
......@@ -1350,6 +1371,10 @@ bool EdgeSelector_QEMextColor<PFP>::init()
{
MAP& m = this->m_map ;
assert(this->m_approximators[0]->getType() != A_hQEM || !"Approximator(hQEM) and selector (ColorNaive) are not compatible") ;
assert(this->m_approximators[0]->getType() != A_hHalfCollapse || !"Approximator(hHalfCollapse) and selector (ColorNaive) are not compatible") ;
assert(this->m_approximators[0]->getType() != A_hLightfieldHalf || !"Approximator(hLightfieldHalf) and selector (ColorNaive) are not compatible") ;
// Verify availability of required approximators
unsigned int ok = 0 ;
for (unsigned int approxindex = 0 ; approxindex < this->m_approximators.size() ; ++approxindex)
......
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