/******************************************************************************* * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * version 0.1 * * Copyright (C) 2009-2012, 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: http://cgogn.unistra.fr/ * * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ namespace CGoGN { namespace Algo { namespace Surface { namespace Decimation { template void decimate( typename PFP::MAP& map, SelectorType s, ApproximatorType a, std::vector* >& attribs, unsigned int nbWantedVertices, EdgeAttribute *edgeErrors, 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 ; std::vector* > *v_approx = NULL ; switch(a) { case A_QEM : approximators.push_back(new Approximator_QEM(map, attribs)) ; break ; case A_MidEdge : approximators.push_back(new Approximator_MidEdge(map, attribs)) ; break ; case A_CornerCutting : approximators.push_back(new Approximator_CornerCutting(map, attribs)) ; break ; case A_TangentPredict1 : approximators.push_back(new Approximator_MidEdge(map, attribs)) ; break ; case A_TangentPredict2 : approximators.push_back(new Approximator_MidEdge(map, attribs)) ; break ; case A_NormalArea : approximators.push_back(new Approximator_NormalArea(map, attribs)) ; break ; case A_hHalfCollapse : approximators.push_back(new Approximator_HalfCollapse(map, attribs)) ; break ; case A_ColorNaive : { v_approx = new std::vector* >[2] ; // pos v_approx[0].push_back(attribs[0]) ; approximators.push_back(new Approximator_QEM(map, v_approx[0])) ; // col 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 : { // pos + col assert(attribs.size() >= 2 || !"Decimate: A_ColorQEMext --> not enough attribs provided") ; approximators.push_back(new Approximator_ColorQEMext(map, attribs)) ; } break; case A_hQEM : // pos approximators.push_back(new Approximator_QEMhalfEdge(map, attribs)) ; break ; 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_hLightfieldHalf --> 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_FrameInterpolationHalfEdge(map, v_approx[1])) ; // hemifunction assert(attribs.size() >= 5 || !"Decimate: A_hLightfieldHalf --> 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_HemiFuncCoefsHalfEdge(map, v_approx[2])) ; } break ; case A_Lightfield : { v_approx = new std::vector* >[3] ; // pos v_approx[0].push_back(attribs[0]) ; approximators.push_back(new Approximator_QEM(map, v_approx[0])) ; // frame assert(attribs.size() >= 4 || !"Decimate: A_Lightfield --> 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_FrameInterpolation(map, v_approx[1])) ; // hemifunction assert(attribs.size() >= 5 || !"Decimate: A_Lightfield --> 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_HemiFuncCoefs(map, v_approx[2])) ; } break ; } switch(s) { case S_MapOrder : selector = new EdgeSelector_MapOrder(map, position, approximators) ; break ; case S_Random : selector = new EdgeSelector_Random(map, position, approximators) ; break ; case S_EdgeLength : selector = new EdgeSelector_Length(map, position, approximators) ; break ; case S_QEMml : selector = new EdgeSelector_QEMml(map, position, approximators) ; break ; case S_QEM : selector = new EdgeSelector_QEM(map, position, approximators) ; break ; case S_Curvature : selector = new EdgeSelector_Curvature(map, position, approximators) ; break ; case S_NormalArea : selector = new EdgeSelector_NormalArea(map, position, approximators) ; break ; case S_CurvatureTensor : selector = new EdgeSelector_CurvatureTensor(map, position, approximators) ; break ; case S_MinDetail : selector = new EdgeSelector_MinDetail(map, position, approximators) ; break ; case S_ColorNaive : selector = new EdgeSelector_ColorNaive(map, position, approximators) ; break ; case S_QEMextColor : selector = new EdgeSelector_QEMextColor(map, position, approximators) ; break ; case S_hQEMextColor : selector = new HalfEdgeSelector_QEMextColor(map, position, approximators) ; break ; case S_hQEMml : selector = new HalfEdgeSelector_QEMml(map, position, approximators) ; break ; case S_Lightfield : selector = new EdgeSelector_Lightfield(map, position, approximators) ; break ; case S_hLightfield : selector = new HalfEdgeSelector_Lightfield(map, position, approximators) ; break ; case S_hLightfieldExp : selector = new HalfEdgeSelector_LightfieldExp(map, position, approximators) ; break ; case S_hLightfieldKCL : selector = new HalfEdgeSelector_LightfieldKCL(map, position, approximators) ; break ; case S_hColorExperimental: selector = new HalfEdgeSelector_ColorExperimental(map, position, approximators, selected) ; break ; case S_hLFexperimental: selector = new HalfEdgeSelector_LFexperimental(map, position, approximators, selected) ; break ; case S_hColorPerFace: selector = new HalfEdgeSelector_ColorPerFace(map, position, approximators, selected) ; break ; case S_hLFperFace: selector = new HalfEdgeSelector_LFperFace(map, position, approximators, selected) ; break ; } for(typename std::vector*>::iterator it = approximators.begin(); it != approximators.end(); ++it) (*it)->init() ; if(!selector->init()) { delete selector ; for(typename std::vector*>::iterator it = approximators.begin(); it != approximators.end(); ++it) delete (*it) ; delete[] v_approx ; return ; } unsigned int nbVertices = map.template getNbOrbits() ; bool finished = false ; Dart d ; while(!finished) { if(!selector->nextEdge(d)) { break ; } --nbVertices ; Dart d2 = map.phi2(map.phi_1(d)) ; Dart dd2 = map.phi2(map.phi_1(map.phi2(d))) ; for(typename std::vector*>::iterator it = approximators.begin(); it != approximators.end(); ++it) { (*it)->approximate(d) ; // compute approximated attributes (*it)->saveApprox(d) ; } selector->updateBeforeCollapse(d) ; // update selector map.collapseEdge(d) ; // collapse edge for(typename std::vector*>::iterator it = approximators.begin(); it != approximators.end(); ++it) (*it)->affectApprox(d2); // affect data to the resulting vertex selector->updateAfterCollapse(d2, dd2) ;// update selector if(nbVertices <= nbWantedVertices) { finished = true ; } // Progress bar support if (callback_wrapper != NULL && callback_object != NULL) callback_wrapper(callback_object, &nbVertices) ; } if (edgeErrors != NULL) selector->getEdgeErrors(edgeErrors) ; delete selector ; for(typename std::vector*>::iterator it = approximators.begin(); it != approximators.end(); ++it) delete (*it) ; delete[] v_approx ; } } //namespace Decimation } } //namespace Algo } //namespace CGoGN