From 0d36fdf885d34c55ab45498b51fc20c8d7b48b5e Mon Sep 17 00:00:00 2001 From: Kenneth Vanhoey Date: Mon, 24 Sep 2012 15:00:29 +0200 Subject: [PATCH] Cleanup and reorganisation of decimation --- include/Algo/Decimation/approximator.h | 7 +- include/Algo/Decimation/decimation.h | 2 +- include/Algo/Decimation/decimation.hpp | 188 ++++++----------------- include/Algo/Decimation/edgeSelector.h | 26 ++-- include/Algo/Decimation/edgeSelector.hpp | 87 +++++++---- 5 files changed, 119 insertions(+), 191 deletions(-) diff --git a/include/Algo/Decimation/approximator.h b/include/Algo/Decimation/approximator.h index 646f0b5d..00860198 100644 --- a/include/Algo/Decimation/approximator.h +++ b/include/Algo/Decimation/approximator.h @@ -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 @@ -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]) ; diff --git a/include/Algo/Decimation/decimation.h b/include/Algo/Decimation/decimation.h index 0aef4964..402bcc12 100644 --- a/include/Algo/Decimation/decimation.h +++ b/include/Algo/Decimation/decimation.h @@ -45,7 +45,7 @@ void decimate( typename PFP::MAP& map, SelectorType s, ApproximatorType a, - VertexAttribute& position, + std::vector *>& position, unsigned int nbWantedVertices, const FunctorSelect& selected = allDarts, void (*callback_wrapper)(void*, const void*) = NULL, void *callback_object = NULL diff --git a/include/Algo/Decimation/decimation.hpp b/include/Algo/Decimation/decimation.hpp index f23350bb..4709cbbe 100644 --- a/include/Algo/Decimation/decimation.hpp +++ b/include/Algo/Decimation/decimation.hpp @@ -34,10 +34,14 @@ namespace Decimation template void decimate( typename PFP::MAP& map, SelectorType s, ApproximatorType a, - VertexAttribute& position, unsigned int nbWantedVertices, const FunctorSelect& selected, + std::vector* >& 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 position = *(attribs[0]) ; + std::vector*> approximators ; EdgeSelector* selector = NULL ; @@ -46,185 +50,85 @@ void decimate( switch(a) { case A_QEM : - v_approx = new std::vector* >[1] ; - v_approx[0].push_back(&position) ; - approximators.push_back(new Approximator_QEM(map, v_approx[0])) ; + approximators.push_back(new Approximator_QEM(map, attribs)) ; break ; case A_MidEdge : - v_approx = new std::vector* >[1] ; - v_approx[0].push_back(&position) ; - approximators.push_back(new Approximator_MidEdge(map, v_approx[0])) ; + approximators.push_back(new Approximator_MidEdge(map, attribs)) ; break ; case A_CornerCutting : - v_approx = new std::vector* >[1] ; - v_approx[0].push_back(&position) ; - approximators.push_back(new Approximator_CornerCutting(map, v_approx[0])) ; + approximators.push_back(new Approximator_CornerCutting(map, attribs)) ; break ; case A_TangentPredict1 : - v_approx = new std::vector* >[1] ; - v_approx[0].push_back(&position) ; - approximators.push_back(new Approximator_MidEdge(map, v_approx[0])) ; + approximators.push_back(new Approximator_MidEdge(map, attribs)) ; break ; case A_TangentPredict2 : - v_approx = new std::vector* >[1] ; - v_approx[0].push_back(&position) ; - approximators.push_back(new Approximator_MidEdge(map, v_approx[0])) ; + approximators.push_back(new Approximator_MidEdge(map, attribs)) ; break ; case A_hHalfCollapse : - v_approx = new std::vector* >[1] ; - v_approx[0].push_back(&position) ; - approximators.push_back(new Approximator_HalfCollapse(map, v_approx[0])) ; + approximators.push_back(new Approximator_HalfCollapse(map, attribs)) ; break ; case A_ColorNaive : { v_approx = new std::vector* >[2] ; // pos - v_approx[0].push_back(&position) ; + v_approx[0].push_back(attribs[0]) ; approximators.push_back(new Approximator_QEM(map, v_approx[0])) ; // col - VertexAttribute *colors = new VertexAttribute() ; - *colors = map.template getAttribute("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(map, v_approx[1])) ; } break ; case A_ColorQEMext : { - v_approx = new std::vector* >[1] ; - // pos + col - v_approx[0].push_back(&position) ; // pos - VertexAttribute *colors = new VertexAttribute() ; - *colors = map.template getAttribute("color") ; - v_approx[0].push_back(colors) ; // col - approximators.push_back(new Approximator_ColorQEMext(map, v_approx[0])) ; + assert(attribs.size() >= 2 || !"Decimate: A_ColorQEMext --> not enough attribs provided") ; + approximators.push_back(new Approximator_ColorQEMext(map, attribs)) ; } break; case A_hQEM : - v_approx = new std::vector* >[1] ; - // pos - v_approx[0].push_back(&position) ; - approximators.push_back(new Approximator_QEMhalfEdge(map, v_approx[0])) ; + approximators.push_back(new Approximator_QEMhalfEdge(map, attribs)) ; break ; - case A_hLightfieldHalf : +// case A_hLightfieldHalf: +// v_approx = new std::vector* >[3] ; +// +// // pos +// v_approx[0].push_back(attribs[0]) ; +// approximators.push_back(new Approximator_HalfCollapse(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(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(map, v_approx[2])) ; +// break ; + case A_hLightfield : { - v_approx = new std::vector* >[1] ; - - // pos - v_approx[0].push_back(&position) ; - - // frame - VertexAttribute *FT = new VertexAttribute() ; - VertexAttribute *FB = new VertexAttribute() ; - VertexAttribute *FN = new VertexAttribute() ; - *FT = map.template getAttribute("frameT") ; - *FB = map.template getAttribute("frameB") ; - *FN = map.template getAttribute("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 *attr = new VertexAttribute() ; - *attr = map.template getAttribute(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 *attr = new VertexAttribute() ; - *attr = map.template getAttribute(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(map, v_approx[0])) ; + // pos + frame + hemifunction + approximators.push_back(new Approximator_HalfCollapse(map, attribs)) ; } break ; - /*case A_LightfieldHalf: - approximators.push_back(new Approximator_HalfCollapse(map, position)) ; - - // Get all frame embeddings - std::vector* > vertexAttributesFrame ; - VertexAttribute frame0 = myMap.getAttribute("frameT") ; vertexAttributesFrame.push_back(&frame0) ; - VertexAttribute frame1 = myMap.getAttribute("frameB") ; vertexAttributesFrame.push_back(&frame1) ; - VertexAttribute frame2 = myMap.getAttribute("frameN") ; vertexAttributesFrame.push_back(&frame2) ; - approximators.push_back(new Approximator_FrameHalf(map, vertexAttributesFrame)) ; // TODO - - // Get all coefficient embeddings - const unsigned int K = 200 ; - std::vector* > vertexAttributesCoefs ; - VertexAttribute *PBcoefs = new VertexAttribute[K] ; - for (unsigned int k = 0 ; k < K ; ++k) - { - std::stringstream s ; - s << "PBcoefs" << k ; - PBcoefs[k] = myMap.getAttribute(s.str()) ; - if (!PBcoefs[k].isValid()) - break ; - vertexAttributesCoefs.push_back(&PBcoefs[k]) ; - } - const bool& sh = vertexAttributesCoefs.empty() ; // sh or pb - VertexAttribute *SHcoefs = new VertexAttribute[K] ; - for (unsigned int k = 0 ; k < K ; ++k) - { - std::stringstream s ; - s << "SHcoefs" << k ; - SHcoefs[k] = myMap.getAttribute(s.str()) ; - if (!SHcoefs[k].isValid()) - break ; - vertexAttributesCoefs.push_back(&SHcoefs[k]) ; - } - approximators.push_back(new Approximator_LightfieldCoefsHalf(map, vertexAttributesCoefs, sh)) ; // TODO - break ; + /* case A_LightfieldFull_deprecated : { approximators.push_back(new Approximator_QEMhalfEdge(map, position)) ; - / * - PFP::TVEC3 frame[3] ; - frame[0] = map.template getAttribute("frame_T") ; // Tangent - frame[1] = map.template getAttribute("frame_B") ; // Bitangent - frame[2] = map.template getAttribute("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 colorPTM[6] ; - colorPTM[0] = map.template getAttribute("colorPTM_a") ; - colorPTM[1] = map.template getAttribute("colorPTM_b") ; - colorPTM[2] = map.template getAttribute("colorPTM_c") ; - colorPTM[3] = map.template getAttribute("colorPTM_d") ; - colorPTM[4] = map.template getAttribute("colorPTM_e") ; - colorPTM[5] = map.template getAttribute("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 > frame = map.template getAttribute, VERTEX>("frame") ; VertexAttribute > RGBfunctions = map.template getAttribute, VERTEX>("colorPTM") ; approximators.push_back(new Approximator_Frame_deprecated(map, frame)) ; approximators.push_back(new Approximator_RGBfunctions_deprecated(map, RGBfunctions)) ; break ; } - case A_LightfieldHalf_deprecated : - { - approximators.push_back(new Approximator_HalfCollapse(map, position)) ; - VertexAttribute > frame = map.template getAttribute, VERTEX>("frame") ; - VertexAttribute > RGBfunctions = map.template getAttribute, VERTEX>("colorPTM") ; - approximators.push_back(new Approximator_FrameHalf_deprecated(map, frame)) ; - approximators.push_back(new Approximator_RGBfunctionsHalf_deprecated(map, RGBfunctions)) ; - break ; - }*/ + */ } switch(s) @@ -271,11 +175,11 @@ void decimate( { delete selector ; - delete[] v_approx ; - for(typename std::vector*>::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*>::iterator it = approximators.begin(); it != approximators.end(); ++it) delete (*it) ; + + delete[] v_approx ; } } //namespace Decimation diff --git a/include/Algo/Decimation/edgeSelector.h b/include/Algo/Decimation/edgeSelector.h index f8da52ed..26299b30 100644 --- a/include/Algo/Decimation/edgeSelector.h +++ b/include/Algo/Decimation/edgeSelector.h @@ -82,7 +82,9 @@ private: public: EdgeSelector_Random(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : - EdgeSelector(m, pos, approx, select) + EdgeSelector(m, pos, approx, select), + cur(0), + allSkipped(false) {} ~EdgeSelector_Random() {} @@ -400,15 +402,17 @@ private: typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; - VertexAttribute m_color ; VertexAttribute > m_quadric ; + VertexAttribute m_pos, m_color ; + int m_approxindex_pos, m_attrindex_pos ; + int m_approxindex_color, m_attrindex_color ; + + std::vector* > m_approx ; + std::multimap edges ; typename std::multimap::iterator cur ; - Approximator* m_positionApproximator ; - Approximator* 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& pos, std::vector*>& approx, const FunctorSelect& select = allDarts) : EdgeSelector(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") ; m_quadric = m.template addAttribute, VERTEX>("QEMquadric") ; - - m_color = m.template getAttribute("color") ; - assert(m_color.isValid() || !"EdgeSelector_ColorNaive: Color atrribute to select is not valid") ; } ~EdgeSelector_ColorNaive() { @@ -463,11 +466,9 @@ private: VertexAttribute > m_quadric ; VertexAttribute m_pos, m_color ; - //VertexAttribute *m_HF ; int m_approxindex_pos, m_attrindex_pos ; int m_approxindex_color, m_attrindex_color ; - // Approximator* m_poscolApproximator ; std::vector* > m_approx ; std::multimap edges ; @@ -481,7 +482,6 @@ private: public: EdgeSelector_QEMextColor(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select = allDarts) : EdgeSelector(m, pos, approx, select), -// m_poscolApproximator(NULL), m_approxindex_pos(-1), m_attrindex_pos(-1), m_approxindex_color(-1), diff --git a/include/Algo/Decimation/edgeSelector.hpp b/include/Algo/Decimation/edgeSelector.hpp index 07a804eb..b490f30a 100644 --- a/include/Algo/Decimation/edgeSelector.hpp +++ b/include/Algo/Decimation/edgeSelector.hpp @@ -1104,27 +1104,43 @@ bool EdgeSelector_ColorNaive::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*>::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* >(*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* >(*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* >(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("color") ; + assert(m_color.isValid() || !"EdgeSelector_ColorNaive: color attribute is not valid") ; + if (!saved) + { + m_approx.push_back(reinterpret_cast* >(this->m_approximators[approxindex])) ; + saved = true ; + } + } } } @@ -1320,23 +1336,28 @@ void EdgeSelector_ColorNaive::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*>::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::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) -- GitLab