59 #define OPENMESH_SMOOTHERT_C
63 #include <OpenMesh/Core/Utils/vector_cast.hh>
83 mesh_.request_vertex_status();
84 mesh_.request_face_normals();
85 mesh_.request_vertex_normals();
88 mesh_.add_property(original_positions_);
89 mesh_.add_property(original_normals_);
90 mesh_.add_property(new_positions_);
91 mesh_.add_property(is_active_);
104 template <
class Mesh>
109 mesh_.release_vertex_status();
110 mesh_.release_face_normals();
111 mesh_.release_vertex_normals();
114 mesh_.remove_property(original_positions_);
115 mesh_.remove_property(original_normals_);
116 mesh_.remove_property(new_positions_);
117 mesh_.remove_property(is_active_);
124 template <
class Mesh>
129 typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end());
143 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
145 mesh_.property(original_positions_, *v_it) = mesh_.point(*v_it);
146 mesh_.property(original_normals_, *v_it) = mesh_.normal(*v_it);
154 template <
class Mesh>
159 typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end());
163 bool nothing_selected(
true);
164 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
165 if (mesh_.status(*v_it).selected())
166 { nothing_selected =
false;
break; }
170 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
172 bool active = ((nothing_selected || mesh_.status(*v_it).selected())
173 && !mesh_.is_boundary(*v_it)
174 && !mesh_.status(*v_it).locked());
176 if ( skip_features_ ) {
178 active = active && !mesh_.status(*v_it).feature();
181 for ( ; voh_it.is_valid() ; ++voh_it ) {
184 if ( mesh_.status(mesh_.edge_handle(*voh_it)).feature() )
187 typename Mesh::FaceHandle fh1 = mesh_.face_handle(*voh_it );
188 typename Mesh::FaceHandle fh2 = mesh_.face_handle(mesh_.opposite_halfedge_handle(*voh_it ) );
191 if ( fh1.is_valid() && mesh_.status( fh1 ).feature() )
193 if ( fh2.is_valid() && mesh_.status( fh2 ).feature() )
199 mesh_.property(is_active_, *v_it) = active;
204 if (continuity_ == C1)
206 typename Mesh::VVIter vv_it;
208 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
209 if (mesh_.is_boundary(*v_it))
210 for (vv_it=mesh_.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
211 mesh_.property(is_active_, *vv_it) =
false;
216 if (continuity_ == C2)
218 typename Mesh::VVIter vv_it;
220 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
222 mesh_.status(*v_it).set_tagged(
false);
223 mesh_.status(*v_it).set_tagged2(
false);
226 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
227 if (mesh_.is_boundary(*v_it))
228 for (vv_it=mesh_.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
229 mesh_.status(*v_it).set_tagged(
true);
231 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
232 if (mesh_.status(*v_it).tagged())
233 for (vv_it=mesh_.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
234 mesh_.status(*v_it).set_tagged2(
true);
236 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
238 if (mesh_.status(*v_it).tagged2())
239 mesh_.property(is_active_, *vv_it) =
false;
240 mesh_.status(*v_it).set_tagged(
false);
241 mesh_.status(*v_it).set_tagged2(
false);
250 template <
class Mesh>
255 if (!mesh_.vertices_empty())
257 typename Mesh::VertexIter v_it(mesh_.vertices_begin()),
258 v_end(mesh_.vertices_end());
262 Point bb_min, bb_max;
263 bb_min = bb_max = mesh_.point(*v_it);
264 for (++v_it; v_it!=v_end; ++v_it)
266 bb_min.minimize(mesh_.point(*v_it));
267 bb_max.maximize(mesh_.point(*v_it));
272 set_absolute_local_error(_err * (bb_max-bb_min).norm());
280 template <
class Mesh>
292 template <
class Mesh>
304 template <
class Mesh>
310 set_active_vertices();
315 compute_new_positions();
317 if (component_ == Tangential)
318 project_to_tangent_plane();
320 else if (tolerance_ >= 0.0)
331 template <
class Mesh>
339 compute_new_positions_C0();
343 compute_new_positions_C1();
355 template <
class Mesh>
358 project_to_tangent_plane()
360 typename Mesh::VertexIter v_it(mesh_.vertices_begin()),
361 v_end(mesh_.vertices_end());
367 for (; v_it != v_end; ++v_it)
369 if (is_active(*v_it))
371 translation = new_position(*v_it)-orig_position(*v_it);
372 normal = orig_normal(*v_it);
373 normal *=
dot(translation, normal);
374 translation -= normal;
376 set_new_position(*v_it, translation);
385 template <
class Mesh>
390 typename Mesh::VertexIter v_it(mesh_.vertices_begin()),
391 v_end(mesh_.vertices_end());
397 for (; v_it != v_end; ++v_it)
399 if (is_active(*v_it))
401 translation = new_position(*v_it) - orig_position(*v_it);
403 s = fabs(
dot(translation, orig_normal(*v_it)));
407 translation *= (tolerance_ / s);
408 translation +=
vector_cast<NormalType>(orig_position(*v_it));
409 set_new_position(*v_it, translation);
419 template <
class Mesh>
424 typename Mesh::VertexIter v_it(mesh_.vertices_begin()),
425 v_end(mesh_.vertices_end());
427 for (; v_it != v_end; ++v_it)
428 if (is_active(*v_it))
429 mesh_.set_point(*v_it, mesh_.property(new_positions_, *v_it));
void initialize(Component _comp, Continuity _cont)
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
void disable_local_error_check()
Disable error control of the smoother.
void set_active_vertices()
Find active vertices. Resets tagged status !
void set_absolute_local_error(Scalar _err)
Set local error as an absolute value.
virtual void smooth(unsigned int _n)
Do _n smoothing iterations.
void update_vertex_normals()
Update normal vectors for all vertices.
void update_face_normals()
Update normal vectors for all faces.
Kernel::VertexOHalfedgeIter VertexOHalfedgeIter
Circulator.
SmootherT(Mesh &_mesh)
constructor & destructor
Smooth tangential and normal direction.
osg::Vec3f::ValueType dot(const osg::Vec3f &_v1, const osg::Vec3f &_v2)
Adapter for osg vector member computing a scalar product.
Kernel::Scalar Scalar
Scalar type.
void set_relative_local_error(Scalar _err)
Set local error relative to bounding box.
Kernel::Normal Normal
Normal type.