/******************************************************************************* * 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 * * * *******************************************************************************/ #ifndef __HALFEDGESELECTOR_H__ #define __HALFEDGESELECTOR_H__ #include "Algo/Decimation/selector.h" namespace CGoGN { namespace Algo { namespace Decimation { /***************************************************************************************************************** * HALF-EDGE MEMORYLESS QEM METRIC * *****************************************************************************************************************/ template class HalfEdgeSelector_QEMml : public EdgeSelector { public: typedef typename PFP::MAP MAP ; typedef typename PFP::VEC3 VEC3 ; typedef typename PFP::REAL REAL ; private: typedef struct { typename std::multimap::iterator it ; bool valid ; static std::string CGoGNnameOfType() { return "QEMhalfEdgeInfo" ; } } QEMhalfEdgeInfo ; typedef NoMathIOAttribute HalfEdgeInfo ; DartAttribute halfEdgeInfo ; VertexAttribute > quadric ; std::multimap halfEdges ; typename std::multimap::iterator cur ; Approximator* 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, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select = allDarts) : EdgeSelector(m, pos, approx, select), m_positionApproximator(NULL) { halfEdgeInfo = m.template addAttribute("halfEdgeInfo") ; quadric = m.template addAttribute, VERTEX>("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) ; void updateWithoutCollapse() { } } ; /***************************************************************************************************************** * HALF-EDGE QEMextColor METRIC * *****************************************************************************************************************/ template class HalfEdgeSelector_QEMextColor : public EdgeSelector { 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::iterator it ; bool valid ; static std::string CGoGNnameOfType() { return "QEMextColorHalfEdgeInfo" ; } } QEMextColorHalfEdgeInfo ; typedef NoMathIOAttribute HalfEdgeInfo ; DartAttribute halfEdgeInfo ; 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 halfEdges ; typename std::multimap::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_QEMextColor(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select = allDarts) : EdgeSelector(m, pos, approx, select), m_approxindex_pos(-1), m_attrindex_pos(-1), m_approxindex_color(-1), m_attrindex_color(-1) { halfEdgeInfo = m.template addAttribute("halfEdgeInfo") ; m_quadric = m.template addAttribute, VERTEX>("hQEMext-quadric") ; } ~HalfEdgeSelector_QEMextColor() { this->m_map.removeAttribute(m_quadric) ; this->m_map.removeAttribute(halfEdgeInfo) ; } SelectorType getType() { return S_hQEMextColor ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse() { } void getEdgeErrors(EdgeAttribute *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 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[dd].it->first < (*errors)[d]) { (*errors)[d] = halfEdgeInfo[dd].it->first ; } } } } ; /***************************************************************************************************************** * HALF-EDGE LIGHTFIELD METRIC * *****************************************************************************************************************/ template class HalfEdgeSelector_Lightfield : public EdgeSelector { 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::iterator it ; bool valid ; static std::string CGoGNnameOfType() { return "LightfieldHalfEdgeInfo" ; } } LightfieldHalfEdgeInfo ; typedef NoMathIOAttribute HalfEdgeInfo ; DartAttribute halfEdgeInfo ; VertexAttribute > m_quadricGeom ; DartAttribute > m_quadricHF ; VertexAttribute m_pos, m_frameT, m_frameB, m_frameN ; std::vector > m_HF ; int m_approxindex_pos, m_attrindex_pos ; int m_approxindex_FN, m_attrindex_FN ; std::vector m_approxindex_HF, m_attrindex_HF ; unsigned int m_K ; std::vector* > m_approx ; std::multimap halfEdges ; typename std::multimap::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_Lightfield(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select = allDarts) : EdgeSelector(m, pos, approx, select), m_approxindex_pos(-1), m_attrindex_pos(-1), m_approxindex_FN(-1), m_attrindex_FN(-1), m_K(0) { halfEdgeInfo = m.template addAttribute("halfEdgeInfo") ; m_quadricGeom = m.template addAttribute, VERTEX>("QEMquadric") ; m_quadricHF = m.template getAttribute, DART>("HFquadric") ; } ~HalfEdgeSelector_Lightfield() { 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 *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 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[dd].it->first < (*errors)[d]) { (*errors)[d] = halfEdgeInfo[dd].it->first ; } } } } ; /***************************************************************************************************************** * HALF-EDGE LIGHTFIELD METRIC experimental * *****************************************************************************************************************/ template class HalfEdgeSelector_LightfieldExp : public EdgeSelector { 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::iterator it ; bool valid ; static std::string CGoGNnameOfType() { return "LightfieldHalfEdgeInfo" ; } } LightfieldHalfEdgeInfo ; typedef NoMathIOAttribute HalfEdgeInfo ; DartAttribute halfEdgeInfo ; VertexAttribute > m_quadricGeom ; DartAttribute > m_quadricHF ; VertexAttribute m_pos, m_frameT, m_frameB, m_frameN, m_avgColor ; std::vector > m_HF ; int m_approxindex_pos, m_attrindex_pos ; int m_approxindex_FN, m_attrindex_FN ; std::vector m_approxindex_HF, m_attrindex_HF ; unsigned int m_K ; std::vector* > m_approx ; std::multimap halfEdges ; typename std::multimap::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& pos, std::vector*>& approx, const FunctorSelect& select = allDarts) : EdgeSelector(m, pos, approx, select), m_approxindex_pos(-1), m_attrindex_pos(-1), m_approxindex_FN(-1), m_attrindex_FN(-1), m_K(0) { halfEdgeInfo = m.template addAttribute("halfEdgeInfo") ; m_quadricGeom = m.template addAttribute, VERTEX>("QEMquadric") ; m_quadricHF = m.template getAttribute, DART>("HFquadric") ; m_avgColor = m.template getAttribute("color") ; assert(m_avgColor.isValid()) ; } ~HalfEdgeSelector_LightfieldExp() { this->m_map.removeAttribute(m_quadricGeom) ; this->m_map.removeAttribute(halfEdgeInfo) ; } SelectorType getType() { return S_hLightfieldExp ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse() { } void getEdgeErrors(EdgeAttribute *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 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[dd].it->first < (*errors)[d]) { (*errors)[d] = halfEdgeInfo[dd].it->first ; } } } } ; /***************************************************************************************************************** * HALF-EDGE LIGHTFIELD METRIC KCL08-like * *****************************************************************************************************************/ template class HalfEdgeSelector_LightfieldKCL : public EdgeSelector { public: typedef typename PFP::MAP MAP ; typedef typename PFP::REAL REAL ; typedef typename PFP::VEC3 VEC3 ; private: typedef struct { typename std::multimap::iterator it ; bool valid ; static std::string CGoGNnameOfType() { return "LightfieldHalfEdgeInfo" ; } } LightfieldHalfEdgeInfo ; typedef NoMathIOAttribute HalfEdgeInfo ; DartAttribute halfEdgeInfo ; VertexAttribute > m_quadricGeom ; VertexAttribute m_visualImportance ; VertexAttribute m_avgColor ; int m_approxindex_pos, m_attrindex_pos ; int m_approxindex_FT, m_attrindex_FT ; int m_approxindex_FB, m_attrindex_FB ; int m_approxindex_FN, m_attrindex_FN ; std::vector m_approxindex_HF, m_attrindex_HF ; unsigned int m_K ; REAL tmpVisualImportance ; std::vector* > m_approx ; std::multimap halfEdges ; typename std::multimap::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) ; REAL computeLightfieldError(Dart v0) ; REAL computeSquaredLightfieldDifference(Dart d1, Dart d2) ; public: HalfEdgeSelector_LightfieldKCL(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select = allDarts) : EdgeSelector(m, pos, approx, select), m_approxindex_pos(-1), m_attrindex_pos(-1), m_approxindex_FT(-1), m_attrindex_FT(-1), m_approxindex_FB(-1), m_attrindex_FB(-1), m_approxindex_FN(-1), m_attrindex_FN(-1), m_K(0) { halfEdgeInfo = m.template addAttribute("halfEdgeInfo") ; m_quadricGeom = m.template addAttribute, VERTEX>("QEMquadric") ; m_visualImportance = m.template addAttribute("VisualImportance") ; m_avgColor = m.template getAttribute("color") ; assert(m_avgColor.isValid()) ; } ~HalfEdgeSelector_LightfieldKCL() { this->m_map.removeAttribute(m_quadricGeom) ; this->m_map.removeAttribute(halfEdgeInfo) ; this->m_map.removeAttribute(m_visualImportance) ; } SelectorType getType() { return S_hLightfieldKCL ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse() { } void getEdgeErrors(EdgeAttribute *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 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[dd].it->first > (*errors)[d]) { (*errors)[dd] = halfEdgeInfo[dd].it->first ; } //m_avgColor[d] = VEC3(m_visualImportance[d]/6.,m_visualImportance[d]/6.,m_visualImportance[d]/6.) ; } } } ; } // namespace Decimation } // namespace Algo } // namespace CGoGN #include "Algo/Decimation/halfEdgeSelector.hpp" #endif