/******************************************************************************* * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * version 0.1 * * Copyright (C) 2009-2011, 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.u-strasbg.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/curvature.h" namespace CGoGN { namespace Algo { 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, typename PFP::TVEC3& 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) ; } ; 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, typename PFP::TVEC3& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select) {} ~EdgeSelector_Random() {} SelectorType getType() { return S_Random ; } bool init() ; bool nextEdge(Dart& d) ; void updateBeforeCollapse(Dart d2) {} void updateAfterCollapse(Dart d2, Dart dd2) ; } ; 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 ; AttributeHandler 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, typename PFP::TVEC3& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select) { edgeInfo = m.template addAttribute(EDGE, "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) ; } ; 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 ; AttributeHandler edgeInfo ; AttributeHandler > quadric ; 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, typename PFP::TVEC3& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select) { edgeInfo = m.template addAttribute(EDGE, "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) ; } ; 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 ; AttributeHandler edgeInfo ; AttributeHandler > 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, typename PFP::TVEC3& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select) { edgeInfo = m.template addAttribute(EDGE, "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) ; } ; 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 ; typename PFP::TVEC3 normal ; AttributeHandler edgeInfo ; typename PFP::TREAL edgeangle ; typename PFP::TREAL kmax ; typename PFP::TREAL kmin ; typename PFP::TVEC3 Kmax ; typename PFP::TVEC3 Kmin ; typename PFP::TVEC3 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, typename PFP::TVEC3& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select) { bb = Algo::Geometry::computeBoundingBox(m, pos) ; radius = bb.diagSize() * 0.003 ; normal = m.template getAttribute(VERTEX, "normal") ; if(!normal.isValid()) { normal = m.template addAttribute(VERTEX, "normal") ; Algo::Geometry::computeNormalVertices(m, pos, normal) ; } edgeangle = m.template getAttribute(VERTEX, "edgeangle") ; if(!edgeangle.isValid()) { edgeangle = m.template addAttribute(EDGE, "edgeangle") ; Algo::Geometry::computeAnglesBetweenNormalsOnEdges(m, pos, edgeangle) ; } kmax = m.template getAttribute(VERTEX, "kmax") ; kmin = m.template getAttribute(VERTEX, "kmin") ; Kmax = m.template getAttribute(VERTEX, "Kmax") ; Kmin = m.template getAttribute(VERTEX, "Kmin") ; Knormal = m.template getAttribute(VERTEX, "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(VERTEX, "kmax") ; kmin = m.template addAttribute(VERTEX, "kmin") ; Kmax = m.template addAttribute(VERTEX, "Kmax") ; Kmin = m.template addAttribute(VERTEX, "Kmin") ; Knormal = m.template addAttribute(VERTEX, "Knormal") ; Algo::Geometry::computeCurvatureVertices_NormalCycles(m, radius, pos, normal, edgeangle, kmax, kmin, Kmax, Kmin, Knormal) ; } edgeInfo = m.template addAttribute(EDGE, "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) ; } ; 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 ; AttributeHandler 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, typename PFP::TVEC3& pos, std::vector*>& approx, const FunctorSelect& select) : EdgeSelector(m, pos, approx, select) { edgeInfo = m.template addAttribute(EDGE, "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) ; } ; } // namespace Decimation } // namespace Algo } // namespace CGoGN #include "Algo/Decimation/edgeSelector.hpp" #endif