Developer Documentation
FileOFFT_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 
44 #define FILEOFFPLUGIN_C
45 
46 #include "FileOFF.hh"
47 
48 #include <OpenMesh/Core/Utils/color_cast.hh>
49 #include <OpenMesh/Core/Geometry/VectorT.hh>
50 #include <sstream>
51 
52 
53 template< class MeshT >
54 bool FileOFFPlugin::writeMesh(std::ostream& _out, MeshT& _mesh, BaseObject &_baseObj){
55 
56  /*****************
57  * HEADER
58  ******************/
59 
60  // Write option ST
61  if(_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & OFFImporter::VERTEXTEXCOORDS) ) {
62  _out << "ST";
63  }
64 
65  // Write option C
66  if(_mesh.has_vertex_colors() && (userWriteOptions_ & OFFImporter::VERTEXCOLOR) ) {
67  _out << "C";
68  }
69 
70  // Write option N
71  if(_mesh.has_vertex_normals() && (userWriteOptions_ & OFFImporter::VERTEXNORMAL) ) {
72  _out << "N";
73  }
74 
75  // Write
76  _out << "OFF";
77 
78  // Write BINARY
79  if(userWriteOptions_ & OFFImporter::BINARY) {
80  _out << " BINARY";
81  }
82 
83  _out << "\n";
84 
85 
86  /*
87  * Comment
88  */
90 
91  if (_baseObj.hasComments()) {
92  _out << "# %% BEGIN OPENFLIPPER_COMMENT %%" << std::endl;
93  std::istringstream comment(_baseObj.getAllCommentsFlat().toStdString());
94  std::string commentLine;
95  while (std::getline(comment, commentLine)) {
96  _out << "# " << commentLine << std::endl;
97  }
98  _out << "# %% END OPENFLIPPER_COMMENT %%" << std::endl;
99  }
100 
101  /*****************
102  * DATA
103  ******************/
104 
105  // Call corresponding write routine
106  if(userWriteOptions_ & OFFImporter::BINARY) {
107  return writeBinaryData(_out, _mesh);
108  } else {
109  if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
110  _out.precision(savePrecision_->value());
111 
112  return writeASCIIData(_out, _mesh);
113  }
114 }
115 
116 //------------------------------------------------------------------------------------------------------
117 
118 template< class MeshT >
119 bool FileOFFPlugin::writeASCIIData(std::ostream& _out, MeshT& _mesh ) {
120 
121  typename MeshT::Point p;
122  typename MeshT::Normal n;
123  typename OpenMesh::Vec4f c;
124  typename MeshT::TexCoord2D t;
125 
126  typename MeshT::VertexIter vit = _mesh.vertices_begin();
127  typename MeshT::VertexIter end_vit = _mesh.vertices_end();
128 
129  // #V #F #E
130  _out << _mesh.n_vertices() << " " << _mesh.n_faces() << " " << _mesh.n_edges();
131 
132  // Write vertex data
133  for(; vit != end_vit; ++vit) {
134 
135  _out << "\n";
136 
137  // Write vertex p[0] p[1] p[2]
138  p = _mesh.point(*vit);
139  _out << p[0] << " " << p[1] << " " << p[2];
140 
141  // Write vertex normals
142  if(_mesh.has_vertex_normals() && (userWriteOptions_ & OFFImporter::VERTEXNORMAL)) {
143  n = _mesh.normal(*vit);
144  _out << " " << n[0] << " " << n[1] << " " << n[2];
145  }
146 
147  // Write vertex colors
148  // Note: Vertex colors always have only three components.
149  // This has to be determined since it can not be read dynamically in binary files.
150  if(_mesh.has_vertex_colors() && (userWriteOptions_ & OFFImporter::VERTEXCOLOR)) {
151  c = OpenMesh::color_cast<OpenMesh::Vec4f> (_mesh.color(*vit));
152  _out << " " << std::showpoint << c[0] << " " << std::showpoint << c[1] << " " << std::showpoint << c[2] << " " << std::showpoint << c[3];
153  }
154 
155  // Write vertex texcoords
156  if(_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & OFFImporter::VERTEXTEXCOORDS)) {
157  t = _mesh.texcoord2D(*vit);
158  _out << " " << t[0] << " " << t[1];
159  }
160  }
161 
162  typename MeshT::FaceIter fit = _mesh.faces_begin();
163  typename MeshT::FaceIter end_fit = _mesh.faces_end();
164  typename MeshT::FaceVertexIter fvit;
165 
166  // Write face data
167  for(; fit != end_fit; ++fit) {
168 
169  _out << "\n";
170 
171  // Write face valence
172  _out << _mesh.valence(*fit);
173 
174  // Get face-vertex iterator
175  fvit = _mesh.fv_iter(*fit);
176 
177  // Write vertex indices
178  for(;fvit.is_valid(); ++fvit) {
179  _out << " " << fvit->idx();
180  }
181 
182  // Write face colors
183  if(_mesh.has_face_colors() && (userWriteOptions_ & OFFImporter::FACECOLOR ) ) {
184  c = OpenMesh::color_cast<OpenMesh::Vec4f> (_mesh.color(*fit));
185  _out << " " << std::showpoint << c[0] << " " << std::showpoint << c[1] << " " << std::showpoint << c[2];
186 
187  if(userWriteOptions_ & OFFImporter::COLORALPHA) _out << " " << std::showpoint << c[3];
188  }
189  }
190 
191  return true;
192 }
193 
194 //------------------------------------------------------------------------------------------------------
195 
196 template< class MeshT >
197 bool FileOFFPlugin::writeBinaryData(std::ostream& _out, MeshT& _mesh ){
198 
199  Vec3f v, n;
200  Vec2f t;
201  OpenMesh::Vec4f c(1.0,1.0,1.0,1.0);
202  OpenMesh::Vec3f p;
203 
204  typename MeshT::VertexIter vit = _mesh.vertices_begin();
205  typename MeshT::VertexIter end_vit = _mesh.vertices_end();
206 
207  // #vertices, #faces, #edges
208  writeValue(_out, (uint)_mesh.n_vertices() );
209  writeValue(_out, (uint)_mesh.n_faces() );
210  writeValue(_out, (uint)_mesh.n_edges() );
211 
212  // Write vertex data
213  for(; vit != end_vit; ++vit) {
214 
215  // Write vertex p[0] p[1] p[2]
216  p = _mesh.point(*vit);
217  writeValue(_out, p[0]);
218  writeValue(_out, p[1]);
219  writeValue(_out, p[2]);
220 
221  // Write vertex normals
222  if(_mesh.has_vertex_normals() && (userWriteOptions_ & OFFImporter::VERTEXNORMAL)) {
223  n = _mesh.normal(*vit);
224  writeValue(_out, n[0]);
225  writeValue(_out, n[1]);
226  writeValue(_out, n[2]);
227  }
228 
229  // Write vertex colors
230  // Note: Vertex colors always have only three components.
231  // This has to be determined since it can not be read dynamically in binary files.
232  if(_mesh.has_vertex_colors() && (userWriteOptions_ & OFFImporter::VERTEXCOLOR)) {
233  c = OpenMesh::color_cast<OpenMesh::Vec4f> (_mesh.color(*vit));
234  writeValue(_out, c[0]);
235  writeValue(_out, c[1]);
236  writeValue(_out, c[2]);
237  }
238 
239  // Write vertex texcoords
240  if(_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & OFFImporter::VERTEXTEXCOORDS)) {
241  t = _mesh.texcoord2D(*vit);
242  writeValue(_out, t[0]);
243  writeValue(_out, t[1]);
244  }
245  }
246 
247  typename MeshT::FaceIter fit = _mesh.faces_begin();
248  typename MeshT::FaceIter end_fit = _mesh.faces_end();
249  typename MeshT::FaceVertexIter fvit;
250 
251  // Write face data
252  for(; fit != end_fit; ++fit) {
253 
254  // Write face valence
255  writeValue(_out, _mesh.valence(*fit));
256 
257  // Get face-vertex iterator
258  fvit = _mesh.fv_iter(*fit);
259 
260  // Write vertex indices
261  for(;fvit.is_valid(); ++fvit) {
262  writeValue(_out, fvit->idx());
263  }
264 
265  // Write face colors
266  if(_mesh.has_face_colors() && (userWriteOptions_ & OFFImporter::FACECOLOR)) {
267 
268  // Number of color components
269  if(userWriteOptions_ & OFFImporter::COLORALPHA) writeValue(_out, (uint)4);
270  else writeValue(_out, (uint)3);
271 
272  // Color itself
273  c = OpenMesh::color_cast<OpenMesh::Vec4f> (_mesh.color(*fit));
274  writeValue(_out, c[0]);
275  writeValue(_out, c[1]);
276  writeValue(_out, c[2]);
277 
278  if(userWriteOptions_ & OFFImporter::COLORALPHA) writeValue(_out, c[3]);
279  }
280  }
281 
282  return true;
283 }
const QString getAllCommentsFlat() const
Definition: BaseObject.cc:856
bool hasComments() const
Definition: BaseObject.cc:839
bool writeBinaryData(std::ostream &_out, MeshT &_mesh)
Write binary mesh data to file.
bool writeASCIIData(std::ostream &_out, MeshT &_mesh)
Write ASCII mesh data to file.
Add 2D texture coordinates (vertices, halfedges)
Definition: Attributes.hh:87
bool writeMesh(std::ostream &_out, MeshT &_mesh, BaseObject &_baseObj)
Writer function.