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;
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 
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 }
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:429