Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
PLYWriter.cc
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openmesh.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenMesh. *
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 * $Revision$ *
45 * $Date$ *
46 * *
47 \*===========================================================================*/
48
49
50 //== INCLUDES =================================================================
51
52 #include <fstream>
53 #include <OpenMesh/Core/System/omstream.hh>
54 #include <OpenMesh/Core/Utils/Endian.hh>
55 #include <OpenMesh/Core/IO/IOManager.hh>
56 #include <OpenMesh/Core/IO/BinaryHelper.hh>
57 #include <OpenMesh/Core/IO/writer/PLYWriter.hh>
58
59 #include <iostream>
60
61 //=== NAMESPACES ==============================================================
62
63
64 namespace OpenMesh {
65 namespace IO {
66
67
68 //=== INSTANCIATE =============================================================
69
70
71 // register the PLYLoader singleton with MeshLoader
72 _PLYWriter_ __PLYWriterInstance;
73 _PLYWriter_& PLYWriter() { return __PLYWriterInstance; }
74
75
76 //=== IMPLEMENTATION ==========================================================
77
78
79 _PLYWriter_::_PLYWriter_()
80 {
81 IOManager().register_module(this);
82
83 nameOfType_[Unsupported] = "";
84 nameOfType_[ValueTypeCHAR] = "char";
85 nameOfType_[ValueTypeUCHAR] = nameOfType_[ValueTypeUINT8] = "uchar";
86 nameOfType_[ValueTypeUSHORT] = "ushort";
87 nameOfType_[ValueTypeSHORT] = "short";
88 nameOfType_[ValueTypeUINT] = "uint";
89 nameOfType_[ValueTypeINT] = "int";
90 nameOfType_[ValueTypeFLOAT32] = nameOfType_[ValueTypeFLOAT] = "float";
91 nameOfType_[ValueTypeDOUBLE] = "double";
92 }
93
94
95 //-----------------------------------------------------------------------------
96
97
98 bool
99 _PLYWriter_::
100 write(const std::string& _filename, BaseExporter& _be, Options _opt, std::streamsize _precision) const
101 {
102
103 // open file
104 std::ofstream out(_filename.c_str(), (_opt.check(Options::Binary) ? std::ios_base::binary | std::ios_base::out
105 : std::ios_base::out) );
106 return write(out, _be, _opt, _precision);
107 }
108
109 //-----------------------------------------------------------------------------
110
111
112 bool
113 _PLYWriter_::
114 write(std::ostream& _os, BaseExporter& _be, Options _opt, std::streamsize _precision) const
115 {
116 // check exporter features
117 if ( !check( _be, _opt ) )
118 return false;
119
120
121 // check writer features
122 if ( _opt.check(Options::FaceNormal) ) {
123 // Face normals are not supported
124 // Uncheck these options and output message that
125 // they are not written out even though they were requested
126 _opt.unset(Options::FaceNormal);
127 omerr() << "[PLYWriter] : Warning: Face normals are not supported and thus not exported! " << std::endl;
128 }
129
130 if ( _opt.check(Options::FaceColor) ) {
131 // Face normals are not supported
132 // Uncheck these options and output message that
133 // they are not written out even though they were requested
134 _opt.unset(Options::FaceColor);
135 omerr() << "[PLYWriter] : Warning: Face colors are not supported and thus not exported! " << std::endl;
136 }
137
138 options_ = _opt;
139
140
141 if (!_os.good())
142 {
143 omerr() << "[PLYWriter] : cannot write to stream "
144 << std::endl;
145 return false;
146 }
147
148 if (!_opt.check(Options::Binary))
149 _os.precision(_precision);
150
151 // write to file
152 bool result = (_opt.check(Options::Binary) ?
153 write_binary(_os, _be, _opt) :
154 write_ascii(_os, _be, _opt));
155
156 return result;
157 }
158
159 //-----------------------------------------------------------------------------
160
161 // helper function for casting a property
162 template<typename T>
163 const PropertyT<T>* castProperty(const BaseProperty* _prop)
164 {
165 return dynamic_cast< const PropertyT<T>* >(_prop);
166 }
167
168 //-----------------------------------------------------------------------------
169 std::vector<_PLYWriter_::CustomProperty> _PLYWriter_::writeCustomTypeHeader(std::ostream& _out, BaseKernel::const_prop_iterator _begin, BaseKernel::const_prop_iterator _end) const
170 {
171 std::vector<CustomProperty> customProps;
172 for (;_begin != _end; ++_begin)
173 {
174 BaseProperty* prop = *_begin;
175
176
177 // check, if property is persistant
178 if (!prop || !prop->persistent())
179 continue;
180
181
182 // identify type of property
183 CustomProperty cProp(prop);
184 size_t propSize = prop->element_size();
185 switch (propSize)
186 {
187 case 1:
188 {
189 assert_compile(sizeof(char) == 1);
190 //check, if prop is a char or unsigned char by dynamic_cast
191 //char, unsigned char and signed char are 3 distinct types
192 if (castProperty<signed char>(prop) != 0 || castProperty<char>(prop) != 0) //treat char as signed char
193 cProp.type = ValueTypeCHAR;
194 else if (castProperty<unsigned char>(prop) != 0)
195 cProp.type = ValueTypeUCHAR;
196 break;
197 }
198 case 2:
199 {
200 assert_compile (sizeof(short) == 2);
201 if (castProperty<signed short>(prop) != 0)
202 cProp.type = ValueTypeSHORT;
203 else if (castProperty<unsigned short>(prop) != 0)
204 cProp.type = ValueTypeUSHORT;
205 break;
206 }
207 case 4:
208 {
209 assert_compile (sizeof(int) == 4);
210 assert_compile (sizeof(float) == 4);
211 if (castProperty<signed int>(prop) != 0)
212 cProp.type = ValueTypeINT;
213 else if (castProperty<unsigned int>(prop) != 0)
214 cProp.type = ValueTypeUINT;
215 else if (castProperty<float>(prop) != 0)
216 cProp.type = ValueTypeFLOAT;
217 break;
218
219 }
220 case 8:
221 assert_compile (sizeof(double) == 8);
222 if (castProperty<double>(prop) != 0)
223 cProp.type = ValueTypeDOUBLE;
224 break;
225 default:
226 break;
227 }
228
229 if (cProp.type != Unsupported)
230 {
231 // property type was identified and it is persistant, write into header
232 customProps.push_back(cProp);
233 _out << "property " << nameOfType_[cProp.type] << " " << cProp.property->name() << "\n";
234 }
235 }
236 return customProps;
237 }
238
239 //-----------------------------------------------------------------------------
240
241 template<bool binary>
242 void _PLYWriter_::write_customProp(std::ostream& _out, const CustomProperty& _prop, size_t _index) const
243 {
244 if (_prop.type == ValueTypeCHAR)
245 writeProxy(_prop.type,_out, castProperty<signed char>(_prop.property)->data()[_index], OpenMesh::GenProg::Bool2Type<binary>());
246 else if (_prop.type == ValueTypeUCHAR || _prop.type == ValueTypeUINT8)
247 writeProxy(_prop.type,_out, castProperty<unsigned char>(_prop.property)->data()[_index], OpenMesh::GenProg::Bool2Type<binary>());
248 else if (_prop.type == ValueTypeSHORT)
249 writeProxy(_prop.type,_out, castProperty<signed short>(_prop.property)->data()[_index], OpenMesh::GenProg::Bool2Type<binary>());
250 else if (_prop.type == ValueTypeUSHORT)
251 writeProxy(_prop.type,_out, castProperty<unsigned short>(_prop.property)->data()[_index], OpenMesh::GenProg::Bool2Type<binary>());
252 else if (_prop.type == ValueTypeUINT)
253 writeProxy(_prop.type,_out, castProperty<unsigned int>(_prop.property)->data()[_index], OpenMesh::GenProg::Bool2Type<binary>());
254 else if (_prop.type == ValueTypeINT || _prop.type == ValueTypeINT32)
255 writeProxy(_prop.type,_out, castProperty<signed int>(_prop.property)->data()[_index], OpenMesh::GenProg::Bool2Type<binary>());
256 else if (_prop.type == ValueTypeFLOAT || _prop.type == ValueTypeFLOAT32)
257 writeProxy(_prop.type,_out, castProperty<float>(_prop.property)->data()[_index], OpenMesh::GenProg::Bool2Type<binary>());
258 else if (_prop.type == ValueTypeDOUBLE)
259 writeProxy(_prop.type,_out, castProperty<double>(_prop.property)->data()[_index], OpenMesh::GenProg::Bool2Type<binary>());
260 }
261
262
263 //-----------------------------------------------------------------------------
264
265
266
267 void _PLYWriter_::write_header(std::ostream& _out, BaseExporter& _be, Options& _opt, std::vector<CustomProperty>& _ovProps, std::vector<CustomProperty>& _ofProps) const {
268 //writing header
269 _out << "ply" << '\n';
270
271 if (_opt.is_binary()) {
272 _out << "format ";
273 if ( options_.check(Options::MSB) )
274 _out << "binary_big_endian ";
275 else
276 _out << "binary_little_endian ";
277 _out << "1.0" << '\n';
278 } else
279 _out << "format ascii 1.0" << '\n';
280
281 _out << "element vertex " << _be.n_vertices() << '\n';
282
283 _out << "property float x" << '\n';
284 _out << "property float y" << '\n';
285 _out << "property float z" << '\n';
286
287 if ( _opt.vertex_has_normal() ){
288 _out << "property float nx" << '\n';
289 _out << "property float ny" << '\n';
290 _out << "property float nz" << '\n';
291 }
292
293 if ( _opt.vertex_has_texcoord() ){
294 _out << "property float u" << '\n';
295 _out << "property float v" << '\n';
296 }
297
298 if ( _opt.vertex_has_color() ){
299 if ( _opt.color_is_float() ) {
300 _out << "property float red" << '\n';
301 _out << "property float green" << '\n';
302 _out << "property float blue" << '\n';
303
304 if ( _opt.color_has_alpha() )
305 _out << "property float alpha" << '\n';
306 } else {
307 _out << "property uchar red" << '\n';
308 _out << "property uchar green" << '\n';
309 _out << "property uchar blue" << '\n';
310
311 if ( _opt.color_has_alpha() )
312 _out << "property uchar alpha" << '\n';
313 }
314 }
315
316 _ovProps = writeCustomTypeHeader(_out, _be.kernel()->vprops_begin(), _be.kernel()->vprops_end());
317
318 _out << "element face " << _be.n_faces() << '\n';
319 _out << "property list uchar int vertex_indices" << '\n';
320
321 _ofProps = writeCustomTypeHeader(_out, _be.kernel()->fprops_begin(), _be.kernel()->fprops_end());
322
323 _out << "end_header" << '\n';
324 }
325
326
327 //-----------------------------------------------------------------------------
328
329
330 bool
331 _PLYWriter_::
332 write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
333 {
334
335 unsigned int i, nV, nF;
336 Vec3f v, n;
337 OpenMesh::Vec3ui c;
338 OpenMesh::Vec4ui cA;
339 OpenMesh::Vec3f cf;
340 OpenMesh::Vec4f cAf;
341 OpenMesh::Vec2f t;
342 VertexHandle vh;
343 std::vector<VertexHandle> vhandles;
344
345 std::vector<CustomProperty> vProps;
346 std::vector<CustomProperty> fProps;
347
348 write_header(_out, _be, _opt, vProps, fProps);
349
350 if (_opt.color_is_float())
351 _out << std::fixed;
352
353 // vertex data (point, normals, colors, texcoords)
354 for (i=0, nV=int(_be.n_vertices()); i<nV; ++i)
355 {
356 vh = VertexHandle(i);
357 v = _be.point(vh);
358
359 //Vertex
360 _out << v[0] << " " << v[1] << " " << v[2];
361
362 // Vertex Normals
363 if ( _opt.vertex_has_normal() ){
364 n = _be.normal(vh);
365 _out << " " << n[0] << " " << n[1] << " " << n[2];
366 }
367
368 // Vertex TexCoords
369 if ( _opt.vertex_has_texcoord() ) {
370 t = _be.texcoord(vh);
371 _out << " " << t[0] << " " << t[1];
372 }
373
374 // VertexColor
375 if ( _opt.vertex_has_color() ) {
376 //with alpha
377 if ( _opt.color_has_alpha() ){
378 if (_opt.color_is_float()) {
379 cAf = _be.colorAf(vh);
380 _out << " " << cAf;
381 } else {
382 cA = _be.colorAi(vh);
383 _out << " " << cA;
384 }
385 }else{
386 //without alpha
387 if (_opt.color_is_float()) {
388 cf = _be.colorf(vh);
389 _out << " " << cf;
390 } else {
391 c = _be.colori(vh);
392 _out << " " << c;
393 }
394 }
395 }
396
397
398 // write custom properties for vertices
399 for (std::vector<CustomProperty>::iterator iter = vProps.begin(); iter < vProps.end(); ++iter)
400 write_customProp<false>(_out,*iter,i);
401
402 _out << "\n";
403 }
404
405 // faces (indices starting at 0)
406 for (i=0, nF=int(_be.n_faces()); i<nF; ++i)
407 {
408 // write vertex indices per face
409 nV = _be.get_vhandles(FaceHandle(i), vhandles);
410 _out << nV;
411 for (size_t j=0; j<vhandles.size(); ++j)
412 _out << " " << vhandles[j].idx();
413
414 // write custom props
415 for (std::vector<CustomProperty>::iterator iter = fProps.begin(); iter < fProps.end(); ++iter)
416 write_customProp<false>(_out,*iter,i);
417 _out << "\n";
418 }
419
420
421 return true;
422 }
423
424
425 //-----------------------------------------------------------------------------
426
427 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out, int value) const {
428
429 uint32_t tmp32;
430 uint8_t tmp8;
431
432 switch (_type) {
433 case ValueTypeINT:
434 case ValueTypeINT32:
435 tmp32 = value;
436 store(_out, tmp32, options_.check(Options::MSB) );
437 break;
438 // case ValueTypeUINT8:
439 default :
440 tmp8 = value;
441 store(_out, tmp8, options_.check(Options::MSB) );
442 break;
443 // default :
444 // std::cerr << "unsupported conversion type to int: " << _type << std::endl;
445 // break;
446 }
447 }
448
449 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out, unsigned int value) const {
450
451 uint32_t tmp32;
452 uint8_t tmp8;
453
454 switch (_type) {
455 case ValueTypeINT:
456 case ValueTypeINT32:
457 tmp32 = value;
458 store(_out, tmp32, options_.check(Options::MSB) );
459 break;
460 // case ValueTypeUINT8:
461 default :
462 tmp8 = value;
463 store(_out, tmp8, options_.check(Options::MSB) );
464 break;
465 // default :
466 // std::cerr << "unsupported conversion type to int: " << _type << std::endl;
467 // break;
468 }
469 }
470
471 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out, float value) const {
472
473 float32_t tmp;
474
475 switch (_type) {
476 case ValueTypeFLOAT32:
477 case ValueTypeFLOAT:
478 tmp = value;
479 store( _out , tmp, options_.check(Options::MSB) );
480 break;
481 default :
482 std::cerr << "unsupported conversion type to float: " << _type << std::endl;
483 break;
484 }
485 }
486
487 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out, double value) const {
488
489 float64_t tmp;
490
491 switch (_type) {
492 case ValueTypeDOUBLE:
493 tmp = value;
494 store( _out , tmp, options_.check(Options::MSB) );
495 break;
496 default :
497 std::cerr << "unsupported conversion type to float: " << _type << std::endl;
498 break;
499 }
500 }
501
502 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out, signed char value) const{
503
504 int8_t tmp;
505
506 switch (_type) {
507 case ValueTypeCHAR:
508 tmp = value;
509 store(_out, tmp, options_.check(Options::MSB) );
510 break;
511 default :
512 std::cerr << "unsupported conversion type to int: " << _type << std::endl;
513 break;
514 }
515 }
516 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out, unsigned char value) const{
517
518 uint8_t tmp;
519
520 switch (_type) {
521 case ValueTypeUCHAR:
522 tmp = value;
523 store(_out, tmp, options_.check(Options::MSB) );
524 break;
525 default :
526 std::cerr << "unsupported conversion type to int: " << _type << std::endl;
527 break;
528 }
529 }
530 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out, short value) const{
531
532 int16_t tmp;
533
534 switch (_type) {
535 case ValueTypeSHORT:
536 tmp = value;
537 store(_out, tmp, options_.check(Options::MSB) );
538 break;
539 default :
540 std::cerr << "unsupported conversion type to int: " << _type << std::endl;
541 break;
542 }
543 }
544 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out, unsigned short value) const{
545
546 uint16_t tmp;
547
548 switch (_type) {
549 case ValueTypeUSHORT:
550 tmp = value;
551 store(_out, tmp, options_.check(Options::MSB) );
552 break;
553 default :
554 std::cerr << "unsupported conversion type to int: " << _type << std::endl;
555 break;
556 }
557 }
558
559 bool
560 _PLYWriter_::
561 write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const
562 {
563
564 unsigned int i, nV, nF;
565 Vec3f v, n;
566 Vec2f t;
567 OpenMesh::Vec4uc c;
568 OpenMesh::Vec4f cf;
569 VertexHandle vh;
570 std::vector<VertexHandle> vhandles;
571
572 // vProps and fProps will be empty, until custom properties are supported by the binary writer
573 std::vector<CustomProperty> vProps;
574 std::vector<CustomProperty> fProps;
575
576 write_header(_out, _be, _opt, vProps, fProps);
577
578 // vertex data (point, normals, texcoords)
579 for (i=0, nV=int(_be.n_vertices()); i<nV; ++i)
580 {
581 vh = VertexHandle(i);
582 v = _be.point(vh);
583
584 //vertex
585 writeValue(ValueTypeFLOAT, _out, v[0]);
586 writeValue(ValueTypeFLOAT, _out, v[1]);
587 writeValue(ValueTypeFLOAT, _out, v[2]);
588
589 // Vertex Normal
590 if ( _opt.vertex_has_normal() ){
591 n = _be.normal(vh);
592 writeValue(ValueTypeFLOAT, _out, n[0]);
593 writeValue(ValueTypeFLOAT, _out, n[1]);
594 writeValue(ValueTypeFLOAT, _out, n[2]);
595 }
596
597 // Vertex TexCoords
598 if ( _opt.vertex_has_texcoord() ) {
599 t = _be.texcoord(vh);
600 writeValue(ValueTypeFLOAT, _out, t[0]);
601 writeValue(ValueTypeFLOAT, _out, t[1]);
602 }
603
604 // vertex color
605 if ( _opt.vertex_has_color() ) {
606 if ( _opt.color_is_float() ) {
607 cf = _be.colorAf(vh);
608 writeValue(ValueTypeFLOAT, _out, cf[0]);
609 writeValue(ValueTypeFLOAT, _out, cf[1]);
610 writeValue(ValueTypeFLOAT, _out, cf[2]);
611
612 if ( _opt.color_has_alpha() )
613 writeValue(ValueTypeFLOAT, _out, cf[3]);
614 } else {
615 c = _be.colorA(vh);
616 writeValue(ValueTypeUCHAR, _out, (int)c[0]);
617 writeValue(ValueTypeUCHAR, _out, (int)c[1]);
618 writeValue(ValueTypeUCHAR, _out, (int)c[2]);
619
620 if ( _opt.color_has_alpha() )
621 writeValue(ValueTypeUCHAR, _out, (int)c[3]);
622 }
623 }
624
625 for (std::vector<CustomProperty>::iterator iter = vProps.begin(); iter < vProps.end(); ++iter)
626 write_customProp<true>(_out,*iter,i);
627 }
628
629
630 for (i=0, nF=int(_be.n_faces()); i<nF; ++i)
631 {
632 //face
633 nV = _be.get_vhandles(FaceHandle(i), vhandles);
634 writeValue(ValueTypeUINT8, _out, nV);
635 for (size_t j=0; j<vhandles.size(); ++j)
636 writeValue(ValueTypeINT32, _out, vhandles[j].idx() );
637
638 for (std::vector<CustomProperty>::iterator iter = fProps.begin(); iter < fProps.end(); ++iter)
639 write_customProp<true>(_out,*iter,i);
640 }
641
642 return true;
643 }
644
645 // ----------------------------------------------------------------------------
646
647
648 size_t
649 _PLYWriter_::
650 binary_size(BaseExporter& _be, Options _opt) const
651 {
652 size_t header(0);
653 size_t data(0);
654 size_t _3floats(3*sizeof(float));
655 size_t _3ui(3*sizeof(unsigned int));
656 size_t _4ui(4*sizeof(unsigned int));
657
658 if ( !_opt.is_binary() )
659 return 0;
660 else
661 {
662
663 size_t _3longs(3*sizeof(long));
664
665 header += 11; // 'OFF BINARY\n'
666 header += _3longs; // #V #F #E
667 data += _be.n_vertices() * _3floats; // vertex data
668 }
669
670 if ( _opt.vertex_has_normal() && _be.has_vertex_normals() )
671 {
672 header += 1; // N
673 data += _be.n_vertices() * _3floats;
674 }
675
676 if ( _opt.vertex_has_color() && _be.has_vertex_colors() )
677 {
678 header += 1; // C
679 data += _be.n_vertices() * _3floats;
680 }
681
682 if ( _opt.vertex_has_texcoord() && _be.has_vertex_texcoords() )
683 {
684 size_t _2floats(2*sizeof(float));
685 header += 2; // ST
686 data += _be.n_vertices() * _2floats;
687 }
688
689 // topology
690 if (_be.is_triangle_mesh())
691 {
692 data += _be.n_faces() * _4ui;
693 }
694 else
695 {
696 unsigned int i, nF;
697 std::vector<VertexHandle> vhandles;
698
699 for (i=0, nF=int(_be.n_faces()); i<nF; ++i)
700 {
701 data += _be.get_vhandles(FaceHandle(i), vhandles) * sizeof(unsigned int);
702
703 }
704 }
705
706 // face colors
707 if ( _opt.face_has_color() && _be.has_face_colors() ){
708 if ( _opt.color_has_alpha() )
709 data += _be.n_faces() * _4ui;
710 else
711 data += _be.n_faces() * _3ui;
712 }
713
714 return header+data;
715 }
716
717
718 //=============================================================================
719 } // namespace IO
720 } // namespace OpenMesh
721 //=============================================================================
OpenMesh::IO::_PLYWriter_
Definition: PLYWriter.hh:93
OpenMesh
Definition: MeshItems.hh:64
OpenMesh::IO::_IOManager_::register_module
bool register_module(BaseReader *_bl)
Definition: IOManager.hh:222
OpenMesh::IO::__PLYWriterInstance
_PLYWriter_ __PLYWriterInstance
Declare the single entity of the PLY writer.
Definition: PLYWriter.cc:72
OpenMesh::PropertyT
Default property class for any type T.
Definition: Property.hh:94
OpenMesh::IO::Options::FaceNormal
Has (r) / store (w) face normals.
Definition: Options.hh:113
OpenMesh::IO::Options::MSB
Assume big endian byte ordering.
Definition: Options.hh:106
OpenMesh::IO::Options::FaceColor
Has (r) / store (w) face colors.
Definition: Options.hh:114
omstream.hh
OpenMesh::IO::_PLYWriter_::CustomProperty
Definition: PLYWriter.hh:123
OpenMesh::IO::Options::unset
Options & unset(const value_type _rhs)
Unset options defined in _rhs.
Definition: Options.hh:178
OpenMesh::IO::Options
Set options for reader/writer modules.
Definition: Options.hh:95
OpenMesh::IO::BaseExporter
Definition: BaseExporter.hh:89
OpenMesh::IO::uint16_t
unsigned short uint16_t
Definition: SR_types.hh:86
OpenMesh::VectorT< float, 3 >
OpenMesh::BaseProperty::name
const std::string & name() const
Return the name of the property.
Definition: BaseProperty.hh:125
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:125
OpenMesh::BaseProperty
Definition: BaseProperty.hh:65
OpenMesh::IO::_PLYWriter_::write
bool write(const std::string &, BaseExporter &, Options, std::streamsize _precision=6) const
Definition: PLYWriter.cc:100
OpenMesh::IO::int16_t
short int16_t
Definition: SR_types.hh:86
OpenMesh::IO::float32_t
float float32_t
Definition: SR_types.hh:97
OpenMesh::IO::float64_t
double float64_t
Definition: SR_types.hh:98
OpenMesh::FaceHandle
Handle for a face entity.
Definition: Handles.hh:146
OpenMesh::IO::_PLYWriter_::write_header
void write_header(std::ostream &_out, BaseExporter &_be, Options &_opt, std::vector< CustomProperty > &_ovProps, std::vector< CustomProperty > &_ofProps) const
write header into the stream _out. Returns custom properties (vertex and face) which are written into...
Definition: PLYWriter.cc:267
OpenMesh::BaseProperty::persistent
bool persistent(void) const
Returns true if the persistent flag is enabled else false.
Definition: BaseProperty.hh:132
OpenMesh::IO::Options::Binary
Set binary mode for r/w.
Definition: Options.hh:105
OpenMesh::IO::_PLYWriter_::writeCustomTypeHeader
std::vector< CustomProperty > writeCustomTypeHeader(std::ostream &_out, BaseKernel::const_prop_iterator _begin, BaseKernel::const_prop_iterator _end) const
write custom persistant properties into the header for the current element, returns all properties...
Definition: PLYWriter.cc:169
OpenMesh::IO::uint32_t
unsigned int uint32_t
Definition: SR_types.hh:90
OpenVolumeMesh::Geometry::VectorT
Definition: Vector11T.hh:78
OpenMesh::IO::int8_t
signed char int8_t
Definition: SR_types.hh:85
BaseExporter
Definition: BaseExporter.hh:1
OpenMesh::BaseProperty::element_size
virtual size_t element_size() const =0
Size of one element in bytes or UnknownSize if not known.
OpenMesh::IO::IOManager
_IOManager_ & IOManager()
Definition: IOManager.cc:77
OpenMesh::IO::_PLYWriter_::binary_size
size_t binary_size(BaseExporter &_be, Options _opt) const
Returns expected size of file if binary format is supported else 0.
Definition: PLYWriter.cc:650
OpenMesh::IO::uint8_t
unsigned char uint8_t
Definition: SR_types.hh:85