OpenMesh
|
00001 /*===========================================================================*\ 00002 * * 00003 * OpenMesh * 00004 * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * 00005 * www.openmesh.org * 00006 * * 00007 *---------------------------------------------------------------------------* 00008 * This file is part of OpenMesh. * 00009 * * 00010 * OpenMesh is free software: you can redistribute it and/or modify * 00011 * it under the terms of the GNU Lesser General Public License as * 00012 * published by the Free Software Foundation, either version 3 of * 00013 * the License, or (at your option) any later version with the * 00014 * following exceptions: * 00015 * * 00016 * If other files instantiate templates or use macros * 00017 * or inline functions from this file, or you compile this file and * 00018 * link it with other files to produce an executable, this file does * 00019 * not by itself cause the resulting executable to be covered by the * 00020 * GNU Lesser General Public License. This exception does not however * 00021 * invalidate any other reasons why the executable file might be * 00022 * covered by the GNU Lesser General Public License. * 00023 * * 00024 * OpenMesh is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU Lesser General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU LesserGeneral Public * 00030 * License along with OpenMesh. If not, * 00031 * see <http://www.gnu.org/licenses/>. * 00032 * * 00033 \*===========================================================================*/ 00034 00035 /*===========================================================================*\ 00036 * * 00037 * $Revision: 448 $ * 00038 * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ * 00039 * * 00040 \*===========================================================================*/ 00041 00045 //============================================================================= 00046 // 00047 // CLASS ModNormalDeviationT 00048 // 00049 //============================================================================= 00050 00051 00052 #ifndef OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH 00053 #define OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH 00054 00055 00056 //== INCLUDES ================================================================= 00057 00058 #include <OpenMesh/Tools/Decimater/ModBaseT.hh> 00059 #include <OpenMesh/Core/Utils/Property.hh> 00060 #include <OpenMesh/Core/Geometry/NormalConeT.hh> 00061 00062 00063 //== NAMESPACES =============================================================== 00064 00065 namespace OpenMesh { 00066 namespace Decimater { 00067 00068 00069 //== CLASS DEFINITION ========================================================= 00070 00071 00086 template <class DecimaterT> 00087 class ModNormalDeviationT : public ModBaseT< DecimaterT > 00088 { 00089 public: 00090 00091 DECIMATING_MODULE( ModNormalDeviationT, DecimaterT, NormalDeviation ); 00092 00093 typedef typename Mesh::Scalar Scalar; 00094 typedef typename Mesh::Point Point; 00095 typedef typename Mesh::Normal Normal; 00096 typedef typename Mesh::VertexHandle VertexHandle; 00097 typedef typename Mesh::FaceHandle FaceHandle; 00098 typedef typename Mesh::EdgeHandle EdgeHandle; 00099 typedef NormalConeT<Scalar> NormalCone; 00100 00101 00102 00103 public: 00104 00106 ModNormalDeviationT(DecimaterT& _dec, float _max_dev = 180.0) 00107 : Base(_dec, true), mesh_(Base::mesh()) 00108 { 00109 set_normal_deviation(_max_dev); 00110 mesh_.add_property(normal_cones_); 00111 } 00112 00113 00115 ~ModNormalDeviationT() { 00116 mesh_.add_property(normal_cones_); 00117 } 00118 00119 00121 Scalar normal_deviation() const { 00122 return normal_deviation_ / M_PI * 180.0; 00123 } 00124 00126 void set_normal_deviation(Scalar _s) { 00127 normal_deviation_ = _s / 180.0 * M_PI; 00128 } 00129 00130 00132 void initialize() { 00133 if (!normal_cones_.is_valid()) 00134 mesh_.add_property(normal_cones_); 00135 00136 typename Mesh::FaceIter f_it = mesh_.faces_begin(), 00137 f_end = mesh_.faces_end(); 00138 00139 for (; f_it != f_end; ++f_it) 00140 mesh_.property(normal_cones_, f_it) = NormalCone(mesh_.normal(f_it)); 00141 } 00142 00157 float collapse_priority(const CollapseInfo& _ci) { 00158 // simulate collapse 00159 mesh_.set_point(_ci.v0, _ci.p1); 00160 00161 00162 typename Mesh::Scalar max_angle(0.0); 00163 typename Mesh::ConstVertexFaceIter vf_it(mesh_, _ci.v0); 00164 typename Mesh::FaceHandle fh, fhl, fhr; 00165 00166 if (_ci.v0vl.is_valid()) fhl = mesh_.face_handle(_ci.v0vl); 00167 if (_ci.vrv0.is_valid()) fhr = mesh_.face_handle(_ci.vrv0); 00168 00169 for (; vf_it; ++vf_it) { 00170 fh = vf_it.handle(); 00171 if (fh != _ci.fl && fh != _ci.fr) { 00172 NormalCone nc = mesh_.property(normal_cones_, fh); 00173 00174 nc.merge(NormalCone(mesh_.calc_face_normal(fh))); 00175 if (fh == fhl) nc.merge(mesh_.property(normal_cones_, _ci.fl)); 00176 if (fh == fhr) nc.merge(mesh_.property(normal_cones_, _ci.fr)); 00177 00178 if (nc.angle() > max_angle) { 00179 max_angle = nc.angle(); 00180 if (max_angle > 0.5 * normal_deviation_) 00181 break; 00182 } 00183 } 00184 } 00185 00186 00187 // undo simulation changes 00188 mesh_.set_point(_ci.v0, _ci.p0); 00189 00190 00191 return (max_angle < 0.5 * normal_deviation_ ? max_angle : float( Base::ILLEGAL_COLLAPSE )); 00192 } 00193 00194 00195 void postprocess_collapse(const CollapseInfo& _ci) { 00196 // account for changed normals 00197 typename Mesh::VertexFaceIter vf_it(mesh_, _ci.v1); 00198 for (; vf_it; ++vf_it) 00199 mesh_.property(normal_cones_, vf_it). 00200 merge(NormalCone(mesh_.normal(vf_it))); 00201 00202 00203 // normal cones of deleted triangles 00204 typename Mesh::FaceHandle fh; 00205 00206 if (_ci.vlv1.is_valid()) { 00207 fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(_ci.vlv1)); 00208 if (fh.is_valid()) 00209 mesh_.property(normal_cones_, fh). 00210 merge(mesh_.property(normal_cones_, _ci.fl)); 00211 } 00212 00213 if (_ci.v1vr.is_valid()) { 00214 fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(_ci.v1vr)); 00215 if (fh.is_valid()) 00216 mesh_.property(normal_cones_, fh). 00217 merge(mesh_.property(normal_cones_, _ci.fr)); 00218 } 00219 } 00220 00221 00222 00223 private: 00224 00225 Mesh& mesh_; 00226 Scalar normal_deviation_; 00227 OpenMesh::FPropHandleT<NormalCone> normal_cones_; 00228 }; 00229 00230 00231 //============================================================================= 00232 } // END_NS_DECIMATER 00233 } // END_NS_OPENMESH 00234 //============================================================================= 00235 #endif // OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH defined 00236 //============================================================================= 00237