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 */
89 OpenMesh::MPropHandleT<std::string> mp_comment;
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 }
OpenMesh::MPropHandleT
Definition: Property.hh:544
FileOFFPlugin::writeASCIIData
bool writeASCIIData(std::ostream &_out, MeshT &_mesh)
Write ASCII mesh data to file.
Definition: FileOFFT_impl.hh:119
BaseObject::getAllCommentsFlat
const QString getAllCommentsFlat() const
Definition: BaseObject.cc:856
BaseObject
Definition: BaseObject.hh:82
FileOFFPlugin::writeBinaryData
bool writeBinaryData(std::ostream &_out, MeshT &_mesh)
Write binary mesh data to file.
Definition: FileOFFT_impl.hh:197
OpenMesh::VectorT< float, 4 >
OpenMesh::Attributes::TexCoord2D
Add 2D texture coordinates (vertices, halfedges)
Definition: Attributes.hh:87
FileOFFPlugin::writeMesh
bool writeMesh(std::ostream &_out, MeshT &_mesh, BaseObject &_baseObj)
Writer function.
Definition: FileOFFT_impl.hh:54
BaseObject::hasComments
bool hasComments() const
Definition: BaseObject.cc:839