⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smoothert.cc

📁 penMesh is a generic and efficient data structure for representing and manipulating polygonal meshes
💻 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 + -