00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #define OPENMESH_POLYMESH_C
00051
00052
00053
00054
00055 #include <OpenMesh/Core/Mesh/PolyMeshT.hh>
00056 #include <OpenMesh/Core/Geometry/LoopSchemeMaskT.hh>
00057 #include <OpenMesh/Core/Utils/vector_cast.hh>
00058 #include <OpenMesh/Core/System/omstream.hh>
00059 #include <vector>
00060
00061
00062
00063
00064
00065 namespace OpenMesh {
00066
00067
00068
00069 template <class Kernel>
00070 uint PolyMeshT<Kernel>::find_feature_edges(Scalar _angle_tresh)
00071 {
00072 assert(Kernel::has_edge_status());
00073 uint n_feature_edges = 0;
00074 for (EdgeIter e_it = Kernel::edges_begin(); e_it != Kernel::edges_end(); ++e_it)
00075 {
00076 if (fabs(calc_dihedral_angle(e_it)) > _angle_tresh)
00077 {
00078 status(e_it).set_feature(true);
00079 n_feature_edges++;
00080 }
00081 else
00082 {
00083 status(e_it).set_feature(false);
00084 }
00085 }
00086 return n_feature_edges;
00087 }
00088
00089
00090
00091 template <class Kernel>
00092 typename PolyMeshT<Kernel>::Normal
00093 PolyMeshT<Kernel>::
00094 calc_face_normal(FaceHandle _fh) const
00095 {
00096 assert(halfedge_handle(_fh).is_valid());
00097 ConstFaceVertexIter fv_it(cfv_iter(_fh));
00098
00099 Point p0 = point(fv_it);
00100 Point p0i = p0;
00101 ++fv_it;
00102 Point p1 = point(fv_it);
00103 Point p1i = p1;
00104 ++fv_it;
00105 Point p2;
00106
00107
00108 Normal n(0,0,0);
00109 for(; fv_it; ++fv_it)
00110 {
00111 p2 = point(fv_it);
00112 n += vector_cast<Normal>(calc_face_normal(p0, p1, p2));
00113 p0 = p1;
00114 p1 = p2;
00115 }
00116
00117
00118 n += vector_cast<Normal>(calc_face_normal(p0i, p0, p1));
00119 n += vector_cast<Normal>(calc_face_normal(p1i, p0i, p1));
00120
00121 typename Normal::value_type norm = n.length();
00122
00123
00124
00125
00126 return (norm != typename Normal::value_type(0)) ? ((n *= (typename Normal::value_type(1)/norm)),n) : Normal(0,0,0);
00127 }
00128
00129
00130
00131
00132 template <class Kernel>
00133 typename PolyMeshT<Kernel>::Normal
00134 PolyMeshT<Kernel>::
00135 calc_face_normal(const Point& _p0,
00136 const Point& _p1,
00137 const Point& _p2) const
00138 {
00139 #if 1
00140
00141
00142
00143 Normal p1p0(vector_cast<Normal>(_p0)); p1p0 -= vector_cast<Normal>(_p1);
00144 Normal p1p2(vector_cast<Normal>(_p2)); p1p2 -= vector_cast<Normal>(_p1);
00145
00146 Normal n = cross(p1p2, p1p0);
00147 typename Normal::value_type norm = n.length();
00148
00149
00150
00151
00152 return (norm != typename Normal::value_type(0)) ? ((n *= (typename Normal::value_type(1)/norm)),n) : Normal(0,0,0);
00153 #else
00154 Point p1p0 = _p0; p1p0 -= _p1;
00155 Point p1p2 = _p2; p1p2 -= _p1;
00156
00157 Normal n = vector_cast<Normal>(cross(p1p2, p1p0));
00158 typename Normal::value_type norm = n.length();
00159
00160 return (norm != 0.0) ? n *= (1.0/norm) : Normal(0,0,0);
00161 #endif
00162 }
00163
00164
00165
00166 template <class Kernel>
00167 void
00168 PolyMeshT<Kernel>::
00169 calc_face_centroid(FaceHandle _fh, Point& _pt) const
00170 {
00171 _pt.vectorize(0);
00172 uint valence = 0;
00173 for (ConstFaceVertexIter cfv_it = cfv_iter(_fh); cfv_it; ++cfv_it, ++valence)
00174 {
00175 _pt += point(cfv_it);
00176 }
00177 _pt /= valence;
00178 }
00179
00180
00181
00182 template <class Kernel>
00183 void
00184 PolyMeshT<Kernel>::
00185 update_normals()
00186 {
00187 if (Kernel::has_face_normals()) update_face_normals();
00188 if (Kernel::has_vertex_normals()) update_vertex_normals();
00189 }
00190
00191
00192
00193
00194
00195 template <class Kernel>
00196 void
00197 PolyMeshT<Kernel>::
00198 update_face_normals()
00199 {
00200 FaceIter f_it(Kernel::faces_begin()), f_end(Kernel::faces_end());
00201
00202 for (; f_it != f_end; ++f_it)
00203 set_normal(f_it.handle(), calc_face_normal(f_it.handle()));
00204 }
00205
00206
00207
00208
00209
00210 template <class Kernel>
00211 typename PolyMeshT<Kernel>::Normal
00212 PolyMeshT<Kernel>::
00213 calc_vertex_normal(VertexHandle _vh) const
00214 {
00215 Normal n;
00216 calc_vertex_normal_fast(_vh,n);
00217
00218 Scalar norm = n.length();
00219 if (norm != 0.0) n *= (1.0/norm);
00220
00221 return n;
00222 }
00223
00224
00225 template <class Kernel>
00226 void PolyMeshT<Kernel>::
00227 calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const
00228 {
00229 _n.vectorize(0.0);
00230 for (ConstVertexFaceIter vf_it=cvf_iter(_vh); vf_it; ++vf_it)
00231 _n += normal(vf_it.handle());
00232 }
00233
00234
00235 template <class Kernel>
00236 void PolyMeshT<Kernel>::
00237 calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const
00238 {
00239 _n.vectorize(0.0);
00240 ConstVertexIHalfedgeIter cvih_it = cvih_iter(_vh);
00241 if (!cvih_it)
00242 {
00243 return;
00244 }
00245 Normal in_he_vec;
00246 calc_edge_vector(cvih_it, in_he_vec);
00247 for ( ; cvih_it; ++cvih_it)
00248 {
00249 if (is_boundary(cvih_it))
00250 {
00251 continue;
00252 }
00253 HalfedgeHandle out_heh(next_halfedge_handle(cvih_it));
00254 Normal out_he_vec;
00255 calc_edge_vector(out_heh, out_he_vec);
00256 _n += cross(in_he_vec, out_he_vec);
00257 in_he_vec = out_he_vec;
00258 in_he_vec *= -1;
00259 }
00260 }
00261
00262
00263 template <class Kernel>
00264 void PolyMeshT<Kernel>::
00265 calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const
00266 {
00267 static const LoopSchemeMaskDouble& loop_scheme_mask__ =
00268 LoopSchemeMaskDoubleSingleton::Instance();
00269
00270 Normal t_v(0.0,0.0,0.0), t_w(0.0,0.0,0.0);
00271 unsigned int vh_val = valence(_vh);
00272 unsigned int i = 0;
00273 for (ConstVertexOHalfedgeIter cvoh_it = cvoh_iter(_vh); cvoh_it; ++cvoh_it, ++i)
00274 {
00275 VertexHandle r1_v(to_vertex_handle(cvoh_it));
00276 t_v += (typename Point::value_type)(loop_scheme_mask__.tang0_weight(vh_val, i))*point(r1_v);
00277 t_w += (typename Point::value_type)(loop_scheme_mask__.tang1_weight(vh_val, i))*point(r1_v);
00278 }
00279 _n = cross(t_w, t_v);
00280 }
00281
00282
00283
00284
00285 template <class Kernel>
00286 void
00287 PolyMeshT<Kernel>::
00288 update_vertex_normals()
00289 {
00290 VertexIter v_it(Kernel::vertices_begin()), v_end(Kernel::vertices_end());
00291
00292 for (; v_it!=v_end; ++v_it)
00293 set_normal(v_it.handle(), calc_vertex_normal(v_it.handle()));
00294 }
00295
00296
00297 }
00298