Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MeshFunctions.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50
51
52
53 //=============================================================================
54 //
55 // IMPLEMENTATION
56 //
57 //=============================================================================
58
59 #define MESHFUNCTIONS_C
60
61 //== INCLUDES =================================================================
62
63 #include "MeshFunctions.hh"
64
65 #include <ACG/Geometry/Algorithms.hh>
66 #include "Math_Tools/Math_Tools.hh"
67
68 #include <set>
69
70 #include <iostream>
71
72 #include <OpenMesh/Core/Geometry/MathDefs.hh>
73 #include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
74
75 //== NAMESPACES ===============================================================
76
77 namespace MeshFunctions {
78
79 //== IMPLEMENTATION ==========================================================
80
81 template < typename MeshT , typename VectorT >
82 bool get_boundary(MeshT& _mesh,
83 typename MeshT::VertexHandle _vh,
84 std::vector< std::pair< VectorT , typename MeshT::VertexHandle > >& _boundary)
85 {
86 _boundary.clear();
87 typename MeshT::VertexHandle last = _vh;
88 const typename MeshT::VertexHandle begin = _vh;
89
90 std::set< typename MeshT::VertexHandle > set;
91
92 //walk along boundary
93 do {
94 //insert current Vertex (which is on boundary to set (needed to detect loops)
95 set.insert( _vh );
96
97 // store the current vertex in the boundary list
98 _boundary.push_back(std::pair< VectorT , typename MeshT::VertexHandle > ( (VectorT)_mesh.point(_vh) , _vh ) );
99
100 // iterate over all outgoing halfedges of the current vertex to find next one
101 for (typename MeshT::VertexOHalfedgeIter vohe_it(_mesh,_vh); vohe_it.is_valid() ; ++vohe_it) {
102
103 //if vertex is on the boundary use it as the next one (if its not the one, we are comming from)
104 if ( _mesh.is_boundary(*vohe_it) && ( _mesh.to_vertex_handle(*vohe_it) != last ) ) {
105 last = _vh;
106 _vh = _mesh.to_vertex_handle(*vohe_it);
107 break;
108 }
109 }
110 // stop if we find a vertex which is already in the list (can also detect partial loops)
111 } while ( set.count( _vh ) == 0 );
112
113 if ( begin != _vh ) {
114 std::cout << "Warning in ( GeometryFunctions.cc get_boundary ) : boundary loop may be partial ( start- != endpoint ) " << std::endl;
115 }
116
117 return true;
118 }
119
120 template < typename MeshT , typename VectorT >
121 bool get_boundary(MeshT& _mesh,
122 std::vector< std::pair< VectorT , typename MeshT::VertexHandle > >& _boundary)
123 {
124 typename MeshT::VertexHandle vh;
125
126 // Search for one Vertex on boundary
127 bool found = false;
128 for (typename MeshT::HalfedgeIter he_it=_mesh.halfedges_begin() ; he_it != _mesh.halfedges_end() ; ++he_it) {
129 if ( _mesh.is_boundary(he_it) ) {
130 vh = _mesh.from_vertex_handle(he_it);
131 found = true;
132 break;
133 }
134 }
135
136 if ( found )
137 return get_boundary(_mesh , vh , _boundary);
138 else {
139 std::cerr << "Did not find Mesh boundary!! ( GeometryFunctions.cc get_boundary )" << std::endl;
140 return false;
141 }
142 }
143
144 template < typename MeshT , typename VectorT >
145 void smooth_boundary(MeshT& _mesh,
146 typename MeshT::VertexHandle _vh)
147 {
148 std::vector< std::pair< VectorT , typename MeshT::VertexHandle > > boundary;
149
150 //get the boundary
151 get_boundary (_mesh , _vh , boundary);
152
153 for (uint i = 1 ; i <= boundary.size() ; ++i ) {
154 _mesh.point( boundary[ i % boundary.size() ].second ) = ( boundary[ ( i - 1) % boundary.size() ].first
155 + boundary[ ( i ) % boundary.size() ].first * 2.0
156 + boundary[ ( i + 1) % boundary.size() ].first ) * 0.25;
157
158 }
159 }
160
161 template < typename MeshT >
162 bool neighbour(const MeshT& _mesh ,
163 const typename MeshT::FaceHandle _fh1 ,
164 const typename MeshT::FaceHandle _fh2 )
165 {
166 for ( typename MeshT::FaceFaceIter ff_it(_mesh,_fh1) ; ff_it ; ++ff_it)
167 if (*ff_it == _fh2)
168 return true;
169 return false;
170 }
171
172
173 template <class MeshT , typename VectorT >
174 bool
175 cut_face(const VectorT& _porigin,
176 const VectorT& _pnormal,
177 const MeshT& _mesh,
178 const typename MeshT::FaceHandle& _fh)
179 {
180 typename MeshT::ConstFaceVertexIter fv_it = _mesh.cfv_iter(_fh);
181 const VectorT p0 = _mesh.point( fv_it);
182 const VectorT p1 = _mesh.point(++fv_it);
183 const VectorT p2 = _mesh.point(++fv_it);
184
185 unsigned int npos(0), nneg(0);
186
187 if( ACG::Geometry::distPointPlane< VectorT , double >( _porigin, _pnormal, p0) > 0 ) ++npos; else ++nneg;
188 if( ACG::Geometry::distPointPlane< VectorT , double >( _porigin, _pnormal, p1) > 0 ) ++npos; else ++nneg;
189 if( ACG::Geometry::distPointPlane< VectorT , double >( _porigin, _pnormal, p2) > 0 ) ++npos; else ++nneg;
190
191
192 if( npos && nneg ) return true;
193 else return false;
194 }
195
196 template < typename MeshT >
197 double
198 calc_area( const MeshT& _mesh)
199 {
200 double area = 0.0;
201 for ( typename MeshT::ConstFaceIter f_it = _mesh.faces_begin() ; f_it != _mesh.faces_end() ; ++f_it) {
202 typename MeshT::ConstFaceVertexIter fv_it = _mesh.cfv_iter(f_it);
203 const ACG::Vec3d vertex1 = (ACG::Vec3d)_mesh.point( fv_it );
204 const ACG::Vec3d vertex2 = (ACG::Vec3d)_mesh.point( ++fv_it );
205 const ACG::Vec3d vertex3 = (ACG::Vec3d)_mesh.point( ++fv_it );
206
207 area += ((vertex1 - vertex2) % (vertex3-vertex2)).norm();
208 }
209
210 return (0.5 * area);
211
212 }
213
214 template < typename MeshT >
215 double
216 calc_angle_around( const MeshT& _mesh , const typename MeshT::VertexHandle _vh)
217 {
218 double angle = 0.0;
219
220 const typename MeshT::Point p0 = _mesh.point(_vh);
221
222 typename MeshT::ConstVertexOHalfedgeIter voh_it(_mesh,_vh);
223 typename MeshT::ConstVertexOHalfedgeIter nx_voh_it = voh_it;
224
225 ++nx_voh_it;
226
227 for ( ; voh_it; ++voh_it , ++nx_voh_it) {
228 const typename MeshT::Point edge_1 = MathTools::sane_normalized( _mesh.point(_mesh.to_vertex_handle(voh_it)) - p0);
229 const typename MeshT::Point edge_2 = MathTools::sane_normalized( (_mesh.point(_mesh.to_vertex_handle(nx_voh_it))) - p0);
230 angle += acos(OpenMesh::sane_aarg(edge_1 | edge_2));
231 }
232
233 return angle;
234 }
235
236 template< typename MeshT >
237 void transformMesh(ACG::Matrix4x4d _matrix , MeshT& _mesh) {
238
239 // Get the inverse matrix of the transformation for the normals
240 ACG::Matrix4x4d invTranspMat = _matrix;
241
242 // Build inverse transposed matrix of _matrix
243 invTranspMat.invert();
244 invTranspMat.transpose();
245
246 typename MeshT::VertexIter v_it = _mesh.vertices_begin();
247 typename MeshT::VertexIter v_end = _mesh.vertices_end();
248 for (; v_it != v_end; ++v_it) {
249
250 // Transform the mesh vertex
251 _mesh.set_point(*v_it, _matrix.transform_point(_mesh.point(*v_it)));
252
253 // Transform the vertex normal
254 if(_mesh.has_vertex_normals()) {
255 typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*v_it));
256 n.normalize();
257 _mesh.set_normal(*v_it, n);
258 }
259 }
260
261 typename MeshT::FaceIter f_it = _mesh.faces_begin();
262 typename MeshT::FaceIter f_end = _mesh.faces_end();
263 for (; f_it != f_end; ++f_it) {
264
265 // Transform the face normal
266 if(_mesh.has_face_normals()) {
267 typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*f_it));
268 n.normalize();
269 _mesh.set_normal(*f_it, n);
270 }
271 }
272 }
273
274 template< typename MeshT >
275 void transformHandleVertices(ACG::Matrix4x4d _matrix , MeshT& _mesh) {
276
277 // Get the inverse matrix of the transformation for the normals
278 ACG::Matrix4x4d invTranspMat = _matrix;
279
280 // Build inverse transposed matrix of _matrix
281 invTranspMat.invert();
282 invTranspMat.transpose();
283
284 typename MeshT::VertexIter v_it = _mesh.vertices_begin();
285 typename MeshT::VertexIter v_end = _mesh.vertices_end();
286 for (; v_it != v_end; ++v_it) {
287
288 if(!_mesh.status(*v_it).is_bit_set(HANDLEAREA)) continue;
289
290 // Transform the mesh vertex
291 _mesh.set_point(*v_it, _matrix.transform_point(_mesh.point(*v_it)));
292
293 // Transform the vertex normal
294 if(_mesh.has_vertex_normals()) {
295 typename MeshT::Normal n = invTranspMat.transform_vector(_mesh.normal(*v_it));
296 n.normalize();
297 _mesh.set_normal(*v_it, n);
298 }
299 }
300
301 // Transform the face normal
302 if(_mesh.has_face_normals()) {
303 _mesh.update_face_normals();
304 }
305 }
306
307 //=============================================================================
308 } // MeshFunctions Namespace
309 //=============================================================================
MeshFunctions::transformMesh
void transformMesh(ACG::Matrix4x4d _matrix, MeshT &_mesh)
Definition: MeshFunctions.cc:237
MeshFunctions::transformHandleVertices
void transformHandleVertices(ACG::Matrix4x4d _matrix, MeshT &_mesh)
Definition: MeshFunctions.cc:275
MeshFunctions::smooth_boundary
void smooth_boundary(MeshT &_mesh, typename MeshT::VertexHandle _vh)
Definition: MeshFunctions.cc:145
TriangleMesh.hh
VectorT
MeshFunctions::neighbour
bool neighbour(const MeshT &_mesh, const typename MeshT::FaceHandle _fh1, const typename MeshT::FaceHandle _fh2)
Definition: MeshFunctions.cc:162
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
ACG::Matrix4x4T::transform_vector
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
Definition: Matrix4x4T.cc:225
MeshFunctions.hh
Functions for modifying a Mesh.
MeshFunctions::calc_angle_around
double calc_angle_around(const MeshT &_mesh, const typename MeshT::VertexHandle _vh)
Definition: MeshFunctions.cc:216
MeshFunctions
Namespace providing different Mesh editing functions.
Definition: MeshFunctions.cc:77
OpenMesh::VectorT
Definition: Vector11T.hh:83
MeshFunctions::get_boundary
bool get_boundary(MeshT &_mesh, typename MeshT::VertexHandle _vh, std::vector< std::pair< VectorT, typename MeshT::VertexHandle > > &_boundary)
Definition: MeshFunctions.cc:82
MeshFunctions::cut_face
bool cut_face(const VectorT &_porigin, const VectorT &_pnormal, const MeshT &_mesh, const typename MeshT::FaceHandle &_fh)
Definition: MeshFunctions.cc:175
ACG::Matrix4x4T::transform_point
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
Definition: Matrix4x4T.cc:202
OpenMesh::Attributes::Normal
Add normals to mesh item (vertices/faces)
Definition: Attributes.hh:87
MeshFunctions::calc_area
double calc_area(const MeshT &_mesh)
Definition: MeshFunctions.cc:198
ACG::Matrix4x4T::transpose
void transpose()
transpose matrix
Definition: Matrix4x4T.cc:272
ACG::Matrix4x4T::invert
bool invert()
matrix inversion (returns true on success)
Definition: Matrix4x4T.cc:297
ACG::Matrix4x4T< double >
OpenMesh::sane_aarg
T sane_aarg(T _aarg)
Trigonometry/angles - related.
Definition: MathDefs.hh:127