📄 smoothert.cc
字号:
//=============================================================================// // OpenMesh // Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen // www.openmesh.org // //-----------------------------------------------------------------------------// // License // // This library is free software; you can redistribute it and/or modify it // under the terms of the GNU Library General Public License as published // by the Free Software Foundation, version 2. // // 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 // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // //-----------------------------------------------------------------------------// // $Revision: 1.2 $// $Date: 2005-12-21 13:58:54 $// //=============================================================================/** \file SmootherT.cc *///=============================================================================//// CLASS SmootherT - IMPLEMENTATION////=============================================================================#define OPENMESH_SMOOTHERT_C//== INCLUDES =================================================================#include <OpenMesh/Tools/Smoother/SmootherT.hh>//== NAMESPACES ===============================================================namespace OpenMesh {namespace Smoother {//== IMPLEMENTATION ========================================================== template <class Mesh>SmootherT<Mesh>::SmootherT(Mesh& _mesh) : mesh_(_mesh){ // request properties mesh_.request_vertex_status(); mesh_.request_face_normals(); mesh_.request_vertex_normals(); // custom properties mesh_.add_property(original_positions_); mesh_.add_property(original_normals_); mesh_.add_property(new_positions_); mesh_.add_property(is_active_); // default settings component_ = Tangential_and_Normal; continuity_ = C0; tolerance_ = -1.0;}//-----------------------------------------------------------------------------template <class Mesh>SmootherT<Mesh>::~SmootherT(){ // free properties mesh_.release_vertex_status(); mesh_.release_face_normals(); mesh_.release_vertex_normals(); // free custom properties mesh_.remove_property(original_positions_); mesh_.remove_property(original_normals_); mesh_.remove_property(new_positions_); mesh_.remove_property(is_active_);}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::initialize(Component _comp, Continuity _cont){ typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); // store smoothing settings component_ = _comp; continuity_ = _cont; // update normals mesh_.update_face_normals(); mesh_.update_vertex_normals(); // store original points & normals for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it) { mesh_.property(original_positions_, v_it) = mesh_.point(v_it); mesh_.property(original_normals_, v_it) = mesh_.normal(v_it); }}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::set_active_vertices(){ typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); // is something selected? bool nothing_selected(true); for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it) if (mesh_.status(v_it).selected()) { nothing_selected = false; break; } // tagg all active vertices bool active; for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it) { active = ((nothing_selected || mesh_.status(v_it).selected()) && !mesh_.is_boundary(v_it) && !mesh_.status(v_it).locked()); mesh_.property(is_active_, v_it) = active; } // C1: remove one ring of boundary vertices if (continuity_ == C1) { typename Mesh::VVIter vv_it; for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it) if (mesh_.is_boundary(v_it)) for (vv_it=mesh_.vv_iter(v_it); vv_it; ++vv_it) mesh_.property(is_active_, vv_it) = false; } // C2: remove two rings of boundary vertices if (continuity_ == C1) { typename Mesh::VVIter vv_it; for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it) { mesh_.status(v_it).set_tagged(false); mesh_.status(v_it).set_tagged2(false); } for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it) if (mesh_.is_boundary(v_it)) for (vv_it=mesh_.vv_iter(v_it); vv_it; ++vv_it) mesh_.status(v_it).set_tagged(true); for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it) if (mesh_.status(v_it).tagged()) for (vv_it=mesh_.vv_iter(v_it); vv_it; ++vv_it) mesh_.status(v_it).set_tagged2(true); for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it) { if (mesh_.status(v_it).tagged2()) mesh_.property(is_active_, vv_it) = false; mesh_.status(v_it).set_tagged(false); mesh_.status(v_it).set_tagged2(false); } }}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::set_relative_local_error(Scalar _err){ if (!mesh_.vertices_empty()) { typename Mesh::VertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end()); // compute bounding box Point bb_min, bb_max; bb_min = bb_max = mesh_.point(v_it); for (++v_it; v_it!=v_end; ++v_it) { bb_min.minimize(mesh_.point(v_it)); bb_max.minimize(mesh_.point(v_it)); } // abs. error = rel. error * bounding-diagonal set_absolute_error(_err * (bb_max-bb_min).norm()); }}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::set_absolute_local_error(Scalar _err){ tolerance_ = _err;}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::disable_local_error_check(){ tolerance_ = -1.0;}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::smooth(unsigned int _n){ // mark active vertices set_active_vertices(); // smooth _n iterations while (_n--) { compute_new_positions(); if (component_ == Tangential) project_to_tangent_plane(); else if (tolerance_ >= 0.0) local_error_check(); move_points(); }}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::compute_new_positions(){ switch (continuity_) { case C0: compute_new_positions_C0(); break; case C1: compute_new_positions_C1(); break; case C2: break; }}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::project_to_tangent_plane(){ typename Mesh::VertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end()); // Normal should be a vector type. In some environment a vector type // is different from point type, e.g. OpenSG! typename Mesh::Normal translation, normal; for (; v_it != v_end; ++v_it) { if (is_active(v_it)) { translation = new_position(v_it)-orig_position(v_it); normal = orig_normal(v_it); normal *= dot(translation, normal); translation -= normal; translation += vector_cast<typename Mesh::Normal>(orig_position(v_it)); set_new_position(v_it, translation); } }}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::local_error_check(){ typename Mesh::VertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end()); typename Mesh::Normal translation; typename Mesh::Scalar s; for (; v_it != v_end; ++v_it) { if (is_active(v_it)) { translation = new_position(v_it) - orig_position(v_it); s = fabs(dot(translation, orig_normal(v_it))); if (s > tolerance_) { translation *= (tolerance_ / s); translation += vector_cast<NormalType>(orig_position(v_it)); set_new_position(v_it, translation); } } }}//-----------------------------------------------------------------------------template <class Mesh>voidSmootherT<Mesh>::move_points(){ typename Mesh::VertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end()); for (; v_it != v_end; ++v_it) if (is_active(v_it)) mesh_.set_point(v_it, mesh_.property(new_positions_, v_it));}//=============================================================================} // namespace Smoother} // namespace OpenMesh//=============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -