/******************************************************************************* * 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 __EDGESELECTOR_H__ #define __EDGESELECTOR_H__ #include "Algo/Decimation/selector.h" #include "Algo/Geometry/boundingbox.h" #include "Container/fakeAttribute.h" #include "Utils/qem.h" #include "Utils/quadricRGBfunctions.h" #include "Algo/Geometry/normal.h" #include "Algo/Selection/collector.h" #include "Algo/Geometry/curvature.h" #include "Algo/Geometry/area.h" namespace CGoGN { namespace Algo { namespace Surface { namespace Decimation { template class EdgeSelector_MapOrder : public EdgeSelector { public: typedef typename PFP::MAP MAP ; typedef typename PFP::VEC3 VEC3 ; typedef typename PFP::REAL REAL ; private: Dart cur ; public: EdgeSelector_MapOrder(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select) {} ~EdgeSelector_MapOrder() {} SelectorType getType() { return S_MapOrder ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) {} void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse() { } } ; template class EdgeSelector_Random : public EdgeSelector { public: typedef typename PFP::MAP MAP ; typedef typename PFP::VEC3 VEC3 ; typedef typename PFP::REAL REAL ; private: std::vector darts ; unsigned int cur ; bool allSkipped ; public: EdgeSelector_Random(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select), cur(0), allSkipped(false) {} ~EdgeSelector_Random() {} SelectorType getType() { return S_Random ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d2) {} void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse(); } ; template class EdgeSelector_Length : 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 "LengthEdgeInfo" ; } } LengthEdgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; std::multimap edges ; typename std::multimap::iterator cur ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d, bool recompute) ; void computeEdgeInfo(Dart d, EdgeInfo& einfo) ; public: EdgeSelector_Length(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select) { edgeInfo = m.template addAttribute("edgeInfo") ; } ~EdgeSelector_Length() { this->m_map.removeAttribute(edgeInfo) ; } SelectorType getType() { return S_EdgeLength ; } 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(edgeInfo.isValid()) ; TraversorE travE(this->m_map) ; for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next()) { (*errors)[d] = -1 ; if (edgeInfo[d].valid) { (*errors)[d] = edgeInfo[d].it->first ; } } } } ; template class EdgeSelector_QEM : 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 "QEMedgeInfo" ; } } QEMedgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; VertexAttribute > quadric ; Utils::Quadric tmpQ ; std::multimap edges ; typename std::multimap::iterator cur ; Approximator* m_positionApproximator ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d, bool recompute) ; void computeEdgeInfo(Dart d, EdgeInfo& einfo) ; public: EdgeSelector_QEM(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select), m_positionApproximator(NULL) { edgeInfo = m.template addAttribute("edgeInfo") ; quadric = m.template addAttribute, VERTEX>("QEMquadric") ; } ~EdgeSelector_QEM() { this->m_map.removeAttribute(quadric) ; this->m_map.removeAttribute(edgeInfo) ; } SelectorType getType() { return S_QEM ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse(); } ; template class EdgeSelector_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 "QEMedgeInfo" ; } } QEMedgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; VertexAttribute > quadric ; std::multimap edges ; typename std::multimap::iterator cur ; Approximator* m_positionApproximator ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d, bool recompute) ; void computeEdgeInfo(Dart d, EdgeInfo& einfo) ; void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ; public: EdgeSelector_QEMml(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select), m_positionApproximator(NULL) { edgeInfo = m.template addAttribute("edgeInfo") ; quadric = m.template addAttribute, VERTEX>("QEMquadric") ; } ~EdgeSelector_QEMml() { this->m_map.removeAttribute(quadric) ; this->m_map.removeAttribute(edgeInfo) ; } SelectorType getType() { return S_QEMml ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse(); } ; template class EdgeSelector_NormalArea : 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 "NormalAreaEdgeInfo" ; } } NormalAreaEdgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; EdgeAttribute > edgeMatrix ; std::multimap edges ; typename std::multimap::iterator cur ; Approximator* m_positionApproximator ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d) ; void computeEdgeInfo(Dart d, EdgeInfo& einfo) ; void computeEdgeMatrix(Dart d) ; // void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ; public: EdgeSelector_NormalArea(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select), m_positionApproximator(NULL) { edgeInfo = m.template addAttribute("edgeInfo") ; edgeMatrix = m.template addAttribute, EDGE>("NormalAreaMatrix") ; } ~EdgeSelector_NormalArea() { this->m_map.removeAttribute(edgeMatrix) ; this->m_map.removeAttribute(edgeInfo) ; } SelectorType getType() { return S_NormalArea ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse() { } } ; template class EdgeSelector_Curvature : 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 "CurvatureEdgeInfo" ; } } CurvatureEdgeInfo ; typedef NoMathIOAttribute EdgeInfo ; Geom::BoundingBox bb ; REAL radius ; VertexAttribute normal ; EdgeAttribute edgeInfo ; EdgeAttribute edgeangle ; VertexAttribute kmax ; VertexAttribute kmin ; VertexAttribute Kmax ; VertexAttribute Kmin ; VertexAttribute Knormal ; std::multimap edges ; typename std::multimap::iterator cur ; Approximator* m_positionApproximator ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d, bool recompute) ; void computeEdgeInfo(Dart d, EdgeInfo& einfo) ; public: EdgeSelector_Curvature(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select), m_positionApproximator(NULL) { bb = Algo::Geometry::computeBoundingBox(m, pos) ; radius = bb.diagSize() * 0.003 ; normal = m.template getAttribute("normal") ; if(!normal.isValid()) { normal = m.template addAttribute("normal") ; Algo::Surface::Geometry::computeNormalVertices(m, pos, normal) ; } edgeangle = m.template getAttribute("edgeangle") ; if(!edgeangle.isValid()) { edgeangle = m.template addAttribute("edgeangle") ; Algo::Surface::Geometry::computeAnglesBetweenNormalsOnEdges(m, pos, edgeangle) ; } kmax = m.template getAttribute("kmax") ; kmin = m.template getAttribute("kmin") ; Kmax = m.template getAttribute("Kmax") ; Kmin = m.template getAttribute("Kmin") ; Knormal = m.template getAttribute("Knormal") ; // as all these attributes are computed simultaneously by computeCurvatureVertices // one can assume that if one of them is not valid, the others must be created too if(!kmax.isValid()) { kmax = m.template addAttribute("kmax") ; kmin = m.template addAttribute("kmin") ; Kmax = m.template addAttribute("Kmax") ; Kmin = m.template addAttribute("Kmin") ; Knormal = m.template addAttribute("Knormal") ; Algo::Surface::Geometry::computeCurvatureVertices_NormalCycles(m, radius, pos, normal, edgeangle, kmax, kmin, Kmax, Kmin, Knormal) ; } edgeInfo = m.template addAttribute("edgeInfo") ; } ~EdgeSelector_Curvature() { this->m_map.removeAttribute(edgeangle) ; this->m_map.removeAttribute(kmax) ; this->m_map.removeAttribute(kmin) ; this->m_map.removeAttribute(Kmax) ; this->m_map.removeAttribute(Kmin) ; this->m_map.removeAttribute(Knormal) ; this->m_map.removeAttribute(edgeInfo) ; } SelectorType getType() { return S_Curvature ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse(); } ; template class EdgeSelector_CurvatureTensor : public EdgeSelector { // TODO : this selector still needs to be tested 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 "CurvatureTensorEdgeInfo" ; } } CurvatureTensorEdgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; EdgeAttribute edgeangle ; std::multimap edges ; typename std::multimap::iterator cur ; Approximator* m_positionApproximator ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d) ; // TODO : usually has a 2nd arg (, bool recompute) : why ?? void computeEdgeInfo(Dart d, EdgeInfo& einfo) ; public: EdgeSelector_CurvatureTensor(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select), m_positionApproximator(NULL) { edgeangle = m.template getAttribute("edgeangle") ; if(!edgeangle.isValid()) { edgeangle = m.template addAttribute("edgeangle") ; Algo::Surface::Geometry::computeAnglesBetweenNormalsOnEdges(m, pos, edgeangle) ; } edgeInfo = m.template addAttribute("edgeInfo") ; } ~EdgeSelector_CurvatureTensor() { this->m_map.removeAttribute(edgeangle) ; // TODO : pas malin s'il existait avant this->m_map.removeAttribute(edgeInfo) ; } SelectorType getType() { return S_CurvatureTensor ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse() {}; } ; template class EdgeSelector_MinDetail : 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 "MinDetailEdgeInfo" ; } } MinDetailEdgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; std::multimap edges ; typename std::multimap::iterator cur ; Approximator* m_positionApproximator ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d, bool recompute) ; void computeEdgeInfo(Dart d, EdgeInfo& einfo) ; public: EdgeSelector_MinDetail(MAP& m, VertexAttribute& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select), m_positionApproximator(NULL) { edgeInfo = m.template addAttribute("edgeInfo") ; } ~EdgeSelector_MinDetail() { this->m_map.removeAttribute(edgeInfo) ; } SelectorType getType() { return S_MinDetail ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse(); } ; /***************************************************************************************************************** * EDGE NAIVE COLOR METRIC (using QEMml) * *****************************************************************************************************************/ template class EdgeSelector_ColorNaive : 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 "ColorNaiveEdgeInfo" ; } } ColorNaiveedgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; 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 ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d, bool recompute) ; void computeEdgeInfo(Dart d,EdgeInfo& einfo) ; void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ; public: EdgeSelector_ColorNaive(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) { edgeInfo = m.template addAttribute("edgeInfo") ; m_quadric = m.template addAttribute, VERTEX>("QEMquadric") ; } ~EdgeSelector_ColorNaive() { this->m_map.removeAttribute(edgeInfo) ; this->m_map.removeAttribute(m_quadric) ; } SelectorType getType() { return S_ColorNaive ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d) ; void updateAfterCollapse(Dart d2, Dart dd2) ; void updateWithoutCollapse() { } } ; /***************************************************************************************************************** * QEM extended to color metric * *****************************************************************************************************************/ template class EdgeSelector_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 "QEMextColorEdgeInfo" ; } } QEMextColorEdgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; 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 ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d, bool recompute) ; void computeEdgeInfo(Dart d,EdgeInfo& einfo) ; void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ; public: EdgeSelector_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) { edgeInfo = m.template addAttribute("edgeInfo") ; m_quadric = m.template addAttribute, VERTEX>("QEMext-quadric") ; } ~EdgeSelector_QEMextColor() { this->m_map.removeAttribute(edgeInfo) ; this->m_map.removeAttribute(m_quadric) ; } SelectorType getType() { return S_QEMextColor ; } 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(edgeInfo.isValid()) ; TraversorE travE(this->m_map) ; for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next()) { (*errors)[d] = -1 ; if (edgeInfo[d].valid) { (*errors)[d] = edgeInfo[d].it->first ; } } } } ; /***************************************************************************************************************** * LIGHTFIELD QUADRIC ERROR METRIC * *****************************************************************************************************************/ template class EdgeSelector_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 "QEMextColorEdgeInfo" ; } } LightfieldEdgeInfo ; typedef NoMathIOAttribute EdgeInfo ; EdgeAttribute edgeInfo ; 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 ; VertexAttribute > m_quadricGeom ; EdgeAttribute > m_quadricHF ; std::vector* > m_approx ; std::multimap edges ; typename std::multimap::iterator cur ; void initEdgeInfo(Dart d) ; void updateEdgeInfo(Dart d, bool recompute) ; void computeEdgeInfo(Dart d,EdgeInfo& einfo) ; void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ; public: EdgeSelector_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) { edgeInfo = m.template addAttribute("edgeInfo") ; m_quadricGeom = m.template addAttribute, VERTEX>("QEMquadric") ; m_quadricHF = m.template getAttribute, EDGE>("HFquadric") ; } ~EdgeSelector_Lightfield() { this->m_map.removeAttribute(edgeInfo) ; this->m_map.removeAttribute(m_quadricGeom) ; } SelectorType getType() { return S_Lightfield ; } 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(edgeInfo.isValid()) ; TraversorE travE(this->m_map) ; for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next()) { if (edgeInfo[d].valid) { (*errors)[d] = edgeInfo[d].it->first ; } else (*errors)[d] = -1 ; } } } ; } // namespace Decimation } } // namespace Algo } // namespace CGoGN #include "Algo/Decimation/edgeSelector.hpp" #endif