From ce1d3c7b89ef63bb279172df2292de478f428d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Fri, 4 Nov 2011 12:59:37 +0000 Subject: [PATCH] Changes to Decimater Base for new mods Decimate to faces function in DecimaterT ModBase with preprocess_collapse git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@448 fdac6126-5c0c-442c-9429-916003d36597 --- src/OpenMesh/Tools/Decimater/DecimaterT.cc | 133 +++++++++++++++++++++ src/OpenMesh/Tools/Decimater/DecimaterT.hh | 7 ++ src/OpenMesh/Tools/Decimater/ModBaseT.hh | 6 + 3 files changed, 146 insertions(+) diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.cc b/src/OpenMesh/Tools/Decimater/DecimaterT.cc index aae98f28..d0fdf562 100644 --- a/src/OpenMesh/Tools/Decimater/DecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/DecimaterT.cc @@ -419,6 +419,21 @@ postprocess_collapse(CollapseInfo& _ci) //----------------------------------------------------------------------------- +template +void +DecimaterT:: +preprocess_collapse(CollapseInfo& _ci) +{ + typename ModuleList::iterator m_it, m_end = bmodules_.end(); + + for (m_it = bmodules_.begin(); m_it != m_end; ++m_it) + (*m_it)->preprocess_collapse(_ci); + + cmodule_->preprocess_collapse(_ci); +} + + +//----------------------------------------------------------------------------- template size_t DecimaterT::decimate( size_t _n_collapses ) @@ -518,6 +533,124 @@ DecimaterT::decimate( size_t _n_collapses ) } +//----------------------------------------------------------------------------- + + +template +size_t +DecimaterT:: +decimate_to_faces( size_t _nv, size_t _nf ) +{ + if ( !is_initialized() ) + return 0; + + if (_nv >= mesh_.n_vertices() || _nf >= mesh_.n_faces()) + return 0; + + typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); + typename Mesh::VertexHandle vp; + typename Mesh::HalfedgeHandle v0v1; + typename Mesh::VertexVertexIter vv_it; + typename Mesh::VertexFaceIter vf_it; + unsigned int nv = mesh_.n_vertices(); + unsigned int nf = mesh_.n_faces(); + unsigned int n_collapses = 0; + + typedef std::vector Support; + typedef typename Support::iterator SupportIterator; + + Support support(15); + SupportIterator s_it, s_end; + + + + + // initialize heap + HeapInterface HI(mesh_, priority_, heap_position_); + heap_ = std::auto_ptr(new DeciHeap(HI)); + heap_->reserve(mesh_.n_vertices()); + + + for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) + { + heap_->reset_heap_position( v_it.handle() ); + if (!mesh_.status(v_it).deleted()) + heap_vertex( v_it.handle() ); + } + + + // process heap + while ((!heap_->empty()) && (_nv < nv) && (_nf < nf)) + { + // get 1st heap entry + vp = heap_->front(); + v0v1 = mesh_.property(collapse_target_, vp); + heap_->pop_front(); + + + // setup collapse info + CollapseInfo ci(mesh_, v0v1); + + + // check topological correctness AGAIN ! + if (!is_collapse_legal(ci)) + continue; + + + // store support (= one ring of *vp) + vv_it = mesh_.vv_iter(ci.v0); + support.clear(); + for (; vv_it; ++vv_it) + support.push_back(vv_it.handle()); + + + // adjust complexity in advance (need boundary status) + ++n_collapses; + --nv; + if (mesh_.is_boundary(ci.v0v1) || + mesh_.is_boundary(ci.v1v0)) + --nf; + else nf -= 2; + + + // pre-processing + preprocess_collapse(ci); + + + // perform collapse + mesh_.collapse(v0v1); + + + // update triangle normals + vf_it = mesh_.vf_iter(ci.v1); + for (; vf_it; ++vf_it) + if (!mesh_.status(vf_it).deleted()) + mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle())); + + + // post-process collapse + postprocess_collapse(ci); + + + // update heap (former one ring of decimated vertex) + for (s_it = support.begin(), s_end = support.end(); + s_it != s_end; ++s_it) + { + assert(!mesh_.status(*s_it).deleted()); + heap_vertex(*s_it); + } + } + + + // delete heap + heap_.reset(); + + + // DON'T do garbage collection here! It's up to the application. + return n_collapses; +} + + //============================================================================= } // END_NS_DECIMATER } // END_NS_OPENMESH diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.hh b/src/OpenMesh/Tools/Decimater/DecimaterT.hh index f9b21bcb..907b4613 100644 --- a/src/OpenMesh/Tools/Decimater/DecimaterT.hh +++ b/src/OpenMesh/Tools/Decimater/DecimaterT.hh @@ -178,6 +178,10 @@ public: decimate( mesh().n_vertices() - _n_vertices ) : 0 ); } + /** Decimate to target complexity (vertices and faces). + * Returns number of performed collapses. + */ + size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 ); private: @@ -245,6 +249,9 @@ private: //---------------------------------------------------- private methods /// Calculate priority of an halfedge collapse (using the modules) float collapse_priority(const CollapseInfo& _ci); + /// Pre-process a collapse + void preprocess_collapse(CollapseInfo& _ci); + /// Post-process a collapse void postprocess_collapse(CollapseInfo& _ci); diff --git a/src/OpenMesh/Tools/Decimater/ModBaseT.hh b/src/OpenMesh/Tools/Decimater/ModBaseT.hh index 5c87533b..61ca66e3 100644 --- a/src/OpenMesh/Tools/Decimater/ModBaseT.hh +++ b/src/OpenMesh/Tools/Decimater/ModBaseT.hh @@ -242,6 +242,12 @@ public: // common interface virtual float collapse_priority(const CollapseInfoT& /* _ci */) { return LEGAL_COLLAPSE; } + /** Before _from_vh has been collapsed into _to_vh, this method + will be called. + */ + virtual void preprocess_collapse(const CollapseInfoT& /* _ci */) + {} + /** After _from_vh has been collapsed into _to_vh, this method will be called. */