OMToolkit  1.0
The polygonal mesh processing tool.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
OMIO.hxx
Go to the documentation of this file.
1 //==============================================================================
14 #ifndef _OM_IO_HXX_
15 #define _OM_IO_HXX_
16 
17 namespace OMToolkit {
18 namespace IO {
19 
21 // Method writes a mesh into MDSTk input channel
22 // Automaticaly sets persistency od original auxiliary data
23 // If user wants to save his custom properties too, it must be saved as persistent property
24 // @param mesh Mesh to store
25 // @param channel MDSTk input channel
26 // @param opt Options for reading (for binary/ascii specification etc.)
27 // @return True, if writing was done successfully
29 template<class Mesh>
30 bool writeMesh(Mesh &mesh, mds::mod::CChannel& channel, Options opt)
31 {
32  using namespace OpenMesh::IO;
33  opt += Options::Default;
34  opt += Options::Binary;
35  opt += Options::ColorAlpha;
36 
37  if (mesh.has_edge_colors())
38  opt += Options::EdgeColor;
39  if (mesh.has_face_colors())
40  opt += Options::FaceColor;
41  if (mesh.has_face_normals())
42  opt += Options::FaceNormal;
43  if (mesh.has_vertex_colors())
44  opt += Options::VertexColor;
45  if (mesh.has_vertex_normals())
46  opt += Options::VertexNormal;
47 
48  return OMWriterExt().write(channel, ExporterT<Mesh>(mesh), opt);
49 }
50 
52 // Method writes a mesh into file specified by filename (format is determined from filename)
53 // Possible formats are STL, OFF, OM, OBJ, PLY
54 // Automaticaly sets persistency od original auxiliary data
55 // If user wants to save his custom properties too, it must be saved as persistent property
56 // @param mesh Mesh to store
57 // @param filename File name
58 // @param opt Options for reading (for binary/ascii specification etc.)
59 // @return True, if writing was done successfully
61 template<class Mesh>
62 bool writeMesh( Mesh &mesh, std::string filename, Options opt)
63 {
64  using namespace OpenMesh::IO;
65  opt += Options::Default;
66  opt += Options::Binary;
67  opt += Options::ColorAlpha;
68 
69  if (mesh.has_edge_colors())
70  opt += Options::EdgeColor;
71  if (mesh.has_face_colors())
72  opt += Options::FaceColor;
73  if (mesh.has_face_normals())
74  opt += Options::FaceNormal;
75  if (mesh.has_vertex_colors())
76  opt += Options::VertexColor;
77  if (mesh.has_vertex_normals())
78  opt += Options::VertexNormal;
79 
80  return write_mesh(mesh, filename, opt);
81 }
82 
84 // Method writes a mesh into STL output stream
85 // Possible formats are STL, OFF, OM, OBJ, PLY
86 // Automaticaly sets persistency od original auxiliary data
87 // If user wants to save his custom properties too, it must be saved as persistent property
88 // @param mesh Mesh to store
89 // @param stream Stream where a mesh will be stored
90 // @param format Format specification - for ex. ".OM"
91 // @param opt Options for reading (for binary/ascii specification etc.)
92 // @return True, if writing was done successfully
94 template<class Mesh>
95 bool writeMesh (Mesh &mesh, std::ostream& stream, std::string format, Options opt)
96 {
97  using namespace OpenMesh::IO;
98  opt += Options::Default;
99  opt += Options::Binary;
100  opt += Options::ColorAlpha;
101 
102  if (mesh.has_edge_colors())
103  opt += Options::EdgeColor;
104  if (mesh.has_face_colors())
105  opt += Options::FaceColor;
106  if (mesh.has_face_normals())
107  opt += Options::FaceNormal;
108  if (mesh.has_vertex_colors())
109  opt += Options::VertexColor;
110  if (mesh.has_vertex_normals())
111  opt += Options::VertexNormal;
112 
113  return write_mesh(mesh, stream, format, opt);
114 }
115 
117 // Method reads a mesh from MDSTk input channel
118 // Automaticaly reads all available data
119 // @param mesh Destination mesh
120 // @param channel MDSTk output channel
121 // @param opt Options for reading (for binary/ascii specification etc.)
122 // @return True, if reading was done successfully
124 template<class Mesh>
125 bool readMesh(Mesh &mesh, mds::mod::CChannel& channel, Options& opt)
126 {
127  using namespace OpenMesh::IO;
128  opt += Options::Default;
129  opt += Options::Binary;
130  opt += Options::ColorAlpha;
131  opt += Options::EdgeColor;
132  opt += Options::FaceColor;
133  opt += Options::FaceNormal;
134  opt += Options::VertexColor;
135  opt += Options::VertexNormal;
136  opt += Options::VertexTexCoord;
137 
138  return OMReaderExt().read(channel, ImporterT<Mesh>(mesh), opt);
139 }
140 
142 // Method reads a mesh from a file specified by filename (format is determined from filename)
143 // Possible formats are STL, OFF, OM, OBJ, PLY
144 // @param mesh Destination mesh
145 // @param filename File name
146 // @param opt Options for reading (for binary/ascii specification etc.)
147 // @return True, if reading was done successfully
149 template<class Mesh>
150 bool readMesh(Mesh &mesh, std::string filename, Options& opt)
151 {
152  opt += Options::Default;
153  opt += Options::Binary;
154  opt += Options::ColorAlpha;
155 
156  if (mesh.has_edge_colors())
157  opt += Options::EdgeColor;
158  if (mesh.has_face_colors())
159  opt += Options::FaceColor;
160  if (mesh.has_face_normals())
161  opt += Options::FaceNormal;
162  if (mesh.has_vertex_colors())
163  opt += Options::VertexColor;
164  if (mesh.has_vertex_normals())
165  opt += Options::VertexNormal;
166 
167  return read_mesh(mesh, filename, opt);
168 }
169 
171 // Method writes a mesh from a STL input stream
172 // Possible formats are STL, OFF, OM, OBJ, PLY
173 // @param mesh Destination mesh
174 // @param stream Source stream
175 // @param format Format specification - for ex. ".OM"
176 // @param opt Options for reading (for binary/ascii specification etc.)
177 // @return True, if reading was done successfully
179 template<class Mesh>
180 bool readMesh(Mesh &mesh, std::istream& stream, std::string format, Options& opt)
181 {
182  opt += Options::Default;
183  opt += Options::Binary;
184  opt += Options::ColorAlpha;
185 
186  if (mesh.has_edge_colors())
187  opt += Options::EdgeColor;
188  if (mesh.has_face_colors())
189  opt += Options::FaceColor;
190  if (mesh.has_face_normals())
191  opt += Options::FaceNormal;
192  if (mesh.has_vertex_colors())
193  opt += Options::VertexColor;
194  if (mesh.has_vertex_normals())
195  opt += Options::VertexNormal;
196 
197  return read_mesh(mesh, stream, format, opt);
198 }
199 
201 // Method exports a mesh vertices into dense 2D array
202 // format of each line: Vx Vy Vz [Nx] [Ny] [Nz]
203 // V(x,y,z) are coordinates of each vertex
204 // N(x,y,z) are coordinates of surface normal on vertex (arbitrary)
205 // size = (num_vertices * 3 * sizeof(Scalar)) in case of normals == false
206 // size = (num_vertices * 6 * sizeof(Scalar)) in case of normals == true
207 // @tparam Mesh Input mesh type
208 // @tparam Scalar Output array type
209 // @param mesh Source mesh
210 // @param output_array Output array of Scalar type
211 // @param normals Should be normals added into output mesh?
212 // @return True, if writing was done successfully
214 template <class Mesh, typename Scalar>
215 bool exportVertices(Mesh &mesh, Scalar *output_array, bool normals)
216 {
217  if (output_array == NULL || (normals && !mesh.has_vertex_normals())) return false;
218 
219  Mesh::VertexIter end = mesh.vertices_end();
220  Scalar *current_pointer = output_array;
221  Mesh::Point pointCoords;
222  Mesh::Normal normalCoords;
223  for (Mesh::VertexIter vertex = mesh.vertices_begin(); vertex != end; ++vertex)
224  {
225  pointCoords = mesh.point(vertex);
226  *(current_pointer) = pointCoords[0];
227  *(current_pointer+1) = pointCoords[1];
228  *(current_pointer+2) = pointCoords[2];
229 
230  if (normals)
231  {
232  normalCoords = mesh.normal(vertex);
233  *(current_pointer+4) = normalCoords[0];
234  *(current_pointer+5) = normalCoords[1];
235  *(current_pointer+6) = normalCoords[2];
236  current_pointer += 8;
237  }
238  else
239  {
240  current_pointer += 4;
241  }
242  }
243 
244  return true;
245 }
246 
248 // Method exports a mesh faces into dense 2D array
249 // format of each line: Vid1 Vid2 Vid3
250 // VidX are indices of each vertex
251 // ARRAY MUST BE INITIALIZED
252 // size = (num_faces * 3 * sizeof(int))
253 // @tparam Mesh Input mesh type
254 // @param mesh Source mesh
255 // @param output_array Output array of int type
256 // @return True, if writing was done successfully
258 template <class Mesh>
259 static bool exportFaces(Mesh &mesh, int *output_array)
260 {
261  if (output_array == NULL) return false;
262 
263  Mesh::FaceIter end = mesh.faces_end();
264  int *current_pointer = output_array;
265 
266  for (Mesh::FaceIter face = mesh.faces_begin(); face != end; ++face)
267  {
268  for (Mesh::FVIter vertex = mesh.fv_begin(face); vertex; ++vertex)
269  {
270  *(current_pointer) = vertex.handle().idx();
271  ++current_pointer;
272  }
273 
274  ++current_pointer; // 4-byte alingment
275  }
276 
277  return true;
278 }
279 
281 // Method imports mesh vertices from dense 2D array
282 // format of each line: Vx Vy Vz [Nx] [Ny] [Nz]
283 // V(x,y,z) are coordinates of each vertex
284 // N(x,y,z) are coordinates of surface normal on vertex (arbitrary)
285 // @tparam Mesh Output mesh type
286 // @tparam Scalar Intput array type
287 // @param mesh Destination mesh
288 // @param input_array Input array of Scalar type
289 // @param normals Should be normals added into output mesh?
290 // @return True, if reading was done successfully
292 template <class Mesh, typename Scalar>
293 static bool importVertices(Mesh &mesh, Scalar *input_array, int size, bool normals)
294 {
295  if (input_array == NULL) return false;
296  if (!mesh.has_vertex_normals()) mesh.request_vertex_normals();
297 
298  Scalar *current_pointer = input_array;
299  Mesh::VertexHandle aux;
300  for (int i = 0; i < size; ++i)
301  {
302  aux = mesh.add_vertex(Mesh::Point( *(current_pointer),
303  *(current_pointer+1),
304  *(current_pointer+2)));
305 
306  if (normals)
307  {
308  mesh.set_normal(aux, Mesh::Normal( *(current_pointer+3),
309  *(current_pointer+4),
310  *(current_pointer+5)));
311  current_pointer += 6;
312  }
313  else
314  {
315  current_pointer += 3;
316  }
317  }
318 
319  return true;
320 }
321 
323 // Method imports mesh faces from dense 2D array
324 // format of each line: Vid1 Vid2 Vid3
325 // VidX are indices of each vertex
326 // @tparam Mesh Output mesh type
327 // @param mesh Output mesh
328 // @param input_array Input array of int type
329 // @param size Number of faces
330 // @return True, if reading was done successfully
332 template <class Mesh>
333 static bool importFaces(Mesh &mesh, int *input_array, int size)
334 {
335  if (input_array == NULL) return false;
336 
337  int *current_pointer = input_array;
338  Mesh::VertexHandle vertex[3];
339  for (int i = 0; i < size; ++i)
340  {
341  vertex[0] = mesh.vertex_handle(*(current_pointer));
342  vertex[1] = mesh.vertex_handle(*(current_pointer+1));
343  vertex[2] = mesh.vertex_handle(*(current_pointer+2));
344 
345  mesh.add_face(vertex[0], vertex[1], vertex[2]);
346  current_pointer += 3;
347  }
348  return true;
349 }
350 
351 } // namespace IO
352 } // namespace OMToolkit
353 
354 #endif