Developer Documentation

FileOpenVolumeMeshT_impl.hh
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 #define FILEOPENVOLUMEMESHT_CC
44
45 #include "FileOpenVolumeMesh.hh"
46
47 //----------------------------------------------------------------------------
48
49 template <typename MeshT>
50 void FileOpenVolumeMeshPlugin::loadMesh(const char* _filename, MeshT& _mesh, bool _comp, bool _topCheck) {
51
52 // found edges in file
53 bool edges_in_file = false;
54
55 typedef typename MeshT::PointT Vertex;
56 _mesh.clear(false);
57
58 std::ifstream iff(_filename, std::ios::in);
59
60 std::string s;
61
62 // read header
63 iff >> s;
64 if (s != "Vertices") {
65 std::cerr << "ERROR reading OpenVolumeMesh (Vertex Section Failed)\n";
66 iff.close();
67 return;
68 }
69
70 // read vertices
71 int nv;
72 iff >> nv;
73 for (int i = 0; i < nv; ++i) {
74 double x, y, z;
75 iff >> x;
76 iff >> y;
77 iff >> z;
78
79 ACG::Vec3d v(x, y, z);
80 _mesh.add_vertex(v);
81 }
82
83 iff >> s;
84 if (s != "Edges") {
85 std::cerr << "No edges found" << std::endl;
86 } else {
87 edges_in_file = true;
88 int ne;
89 iff >> ne;
90 for (int e = 0; e < ne; ++e) {
91 int v1, v2;
92 iff >> v1;
93 iff >> v2;
94 _mesh.add_edge(OpenVolumeMesh::VertexHandle(v1), OpenVolumeMesh::VertexHandle(v2));
95 }
96 }
97
98 if (edges_in_file) {
99 iff >> s;
100 }
101
102 if (s != "Faces") {
103 std::cerr << "ERROR reading OpenVolumeMesh (Face Section Failed)\n";
104 iff.close();
105 return;
106 }
107
108 if(_comp) {
109
110 // Read vertex indices and define faces
111 // via its vertices (in correct order)
112 int nf;
113 iff >> nf;
114 for (int f = 0; f < nf; ++f) {
115 int nfv;
116 iff >> nfv;
117 std::vector<OpenVolumeMesh::VertexHandle> vhs;
118 for (int v = 0; v < nfv; ++v) {
119 int i;
120 iff >> i;
121 vhs.push_back(OpenVolumeMesh::VertexHandle(i));
122 }
123 int pos_cell, neg_cell;
124 iff >> pos_cell;
125 iff >> neg_cell;
126 _mesh.add_face(vhs);
127 }
128 } else {
129
130 // Read halfface indices
131 int nf;
132 iff >> nf;
133 for (int f = 0; f < nf; ++f) {
134 int nfhe;
135 iff >> nfhe;
136 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes;
137 for (int he = 0; he < nfhe; ++he) {
138 int i;
139 iff >> i;
140 hes.push_back(OpenVolumeMesh::HalfEdgeHandle(i));
141 }
142
143 _mesh.add_face(hes, _topCheck);
144 }
145 }
146
147 // Read faces and find the respective halffaces
148 iff >> s;
149 if(s != "Polyhedra") {
150 std::cerr << "ERROR reading OpenVolumeMesh (Polyhedra Section Failed)\n";
151 iff.close();
152 return;
153 }
154
155 if(_comp) {
156
157 int nc;
158 iff >> nc;
159
160 for( int i = 0; i < nc; ++i) {
161
162 int ncf;
163 iff >> ncf;
164 std::vector< OpenVolumeMesh::FaceHandle > faces;
165
166 for( int f = 0; f < ncf; ++f) {
167
168 int fidx;
169 iff >> fidx;
170 faces.push_back(OpenVolumeMesh::FaceHandle(fidx));
171 }
172
173 // Get right halffaces
174 // First determine the barycenter of the polyhedron
175 ACG::Vec3d c(0.0, 0.0, 0.0);
176 unsigned int num_faces = faces.size();
177 for(auto fh : faces)
178 {
179
180 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes = _mesh.face(fh).halfedges();
181 unsigned int val = hes.size();
182 ACG::Vec3d f_mid(0.0, 0.0, 0.0);
183 for(std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator p_it = hes.begin();
184 p_it != hes.end(); ++p_it) {
185 f_mid += (_mesh.vertex(_mesh.halfedge(*p_it).to_vertex()) / (double)val);
186 }
187 c += f_mid / (double)num_faces;
188 }
189
190 // Now determine all halffaces
191 // Test whether their normals point into the polyhedron
192 std::vector<OpenVolumeMesh::HalfFaceHandle> hfhandles;
193 for(auto fh : faces)
194 {
195
196 // Get face's mid-point
197 std::vector<OpenVolumeMesh::HalfEdgeHandle> hes = _mesh.face(fh).halfedges();
198 unsigned int val = hes.size();
199 ACG::Vec3d f_mid(0.0, 0.0, 0.0);
200 for(std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator p_it = hes.begin();
201 p_it != hes.end(); ++p_it) {
202 f_mid += (_mesh.vertex(_mesh.halfedge(*p_it).to_vertex()) / (double)val);
203 }
204
205 // Now compute the face's normal
206 if(hes.size() < 2) continue;
207 ACG::Vec3d p0 = _mesh.vertex(_mesh.halfedge(hes[0]).from_vertex());
208 ACG::Vec3d p1 = _mesh.vertex(_mesh.halfedge(hes[0]).to_vertex());
209 ACG::Vec3d p2 = _mesh.vertex(_mesh.halfedge(hes[1]).to_vertex());
210 ACG::Vec3d n = (p0 - p1) % (p2 - p1);
211 n.normalize();
212
213 if(((c - f_mid) | n) >= 0.0) hfhandles.push_back(_mesh.halfface_handle(fh, 0));
214 else hfhandles.push_back(_mesh.halfface_handle(fh, 1));
215 }
216
217 if(hfhandles.size() > 3) {
218
219 HexahedralMesh* hm = 0;
220 hm = dynamic_cast<HexahedralMesh*>(&_mesh);
221
222 if(hm) {
223 hm->add_cell(hfhandles, _topCheck);
224 } else {
225 _mesh.add_cell(hfhandles, _topCheck);
226 }
227 } else {
228 std::cerr << "Could not determine corresponding halffaces!" << std::endl;
229 }
230 }
231 } else {
232
233 // Just read the specified halffaces
234 int nc;
235 iff >> nc;
236 for (int c = 0; c < nc; ++c) {
237
238 int nhf;
239 iff >> nhf;
240 std::vector<OpenVolumeMesh::HalfFaceHandle> hfs;
241 for (int hf = 0; hf < nhf; ++hf) {
242 int i;
243 iff >> i;
244 hfs.push_back(OpenVolumeMesh::HalfFaceHandle(i));
245 }
246
247 // Implement hex mesh shit
248 HexahedralMesh* hm = 0;
249 hm = dynamic_cast<HexahedralMesh*>(&_mesh);
250
251 if(hm) {
252 hm->add_cell(hfs, _topCheck);
253 } else {
254 _mesh.add_cell(hfs, _topCheck);
255 }
256 }
257 }
258 iff.close();
259
260 std::cerr << "######## openvolumemesh info #########\n";
261 std::cerr << "#vertices: " << _mesh.n_vertices() << std::endl;
262 std::cerr << "#edges : " << _mesh.n_edges() << std::endl;
263 std::cerr << "#faces : " << _mesh.n_faces() << std::endl;
264 std::cerr << "#cells : " << _mesh.n_cells() << std::endl;
265 }
266
267 //----------------------------------------------------------------------------
268
269 template <typename MeshT>
270 void FileOpenVolumeMeshPlugin::saveMesh(const char* _filename, MeshT& _mesh, bool _comp) {
271
272 typedef OpenVolumeMesh::OpenVolumeMeshFace Face;
273 std::ofstream off(_filename, std::ios::out);
274
275 int n_vertices(_mesh.n_vertices());
276 off << "Vertices" << std::endl;
277 off << n_vertices << std::endl;
278
279 // write vertices
280 for(OpenVolumeMesh::VertexIter v_it = _mesh.v_iter(); v_it; ++v_it) {
281
282 ACG::Vec3d v = _mesh.vertex(*v_it);
283 off << v[0] << " " << v[1] << " " << v[2] << std::endl;
284 }
285
286 int n_edges(_mesh.n_edges());
287 off << "Edges" << std::endl;
288 off << n_edges << std::endl;
289
290 // write edges
291 for(OpenVolumeMesh::EdgeIter e_it = _mesh.e_iter(); e_it; ++e_it) {
292
293 OpenVolumeMesh::VertexHandle from_vertex = _mesh.edge(*e_it).from_vertex();
294 OpenVolumeMesh::VertexHandle to_vertex = _mesh.edge(*e_it).to_vertex();
295 off << from_vertex << " " << to_vertex << std::endl;
296 }
297
298 int n_faces(_mesh.n_faces());
299 off << "Faces" << std::endl;
300 off << n_faces << std::endl;
301
302 // write faces
303 for(OpenVolumeMesh::FaceIter f_it = _mesh.f_iter(); f_it; ++f_it) {
304
305 off << _mesh.face(*f_it).halfedges().size() << " ";
306
307 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(*f_it).halfedges();
308
309 for (std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator it = halfedges.begin();
310 it != halfedges.end(); ++it) {
311
312 if(_comp) {
313 off << _mesh.halfedge(*it).from_vertex();
314 } else {
315 off << *it;
316 }
317
318 if((it+1) != halfedges.end()) off << " ";
319 }
320
321 off << std::endl;
322 }
323
324
325 int n_cells(_mesh.n_cells());
326 off << "Polyhedra" << std::endl;
327 off << n_cells << std::endl;
328
329 for(OpenVolumeMesh::CellIter c_it = _mesh.c_iter(); c_it; ++c_it) {
330
331 off << _mesh.cell(*c_it).halffaces().size() << " ";
332
333 std::vector<OpenVolumeMesh::HalfFaceHandle> halffaces = _mesh.cell(*c_it).halffaces();
334
335 for (std::vector<OpenVolumeMesh::HalfFaceHandle>::const_iterator it = halffaces.begin();
336 it != halffaces.end(); ++it) {
337
338 if(_comp) {
339 off << _mesh.face_handle(*it);
340 } else {
341 off << *it;
342 }
343
344 if((it+1) != halffaces.end()) off << " ";
345 }
346
347 off << std::endl;
348 }
349
350 off.close();
351 }
OpenVolumeMesh::FaceIter
Definition: Iterators.hh:995
OpenVolumeMesh::OpenVolumeMeshFace
Definition: BaseEntities.hh:90
OpenMesh::VectorT::normalize
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:429
OpenVolumeMesh::GeometryKernel
Definition: GeometryKernel.hh:55
OpenVolumeMesh::VertexIter
Definition: Iterators.hh:833
OpenVolumeMesh::HandleT< Entity::Vertex >
OpenVolumeMesh::CellIter
Definition: Iterators.hh:1103
OpenMesh::VectorT
Definition: Vector11T.hh:83
OpenVolumeMesh::EdgeIter
Definition: Iterators.hh:887