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>
79 _PLYWriter_::_PLYWriter_()
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";
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);
117 if ( !check( _be, _opt ) )
127 omerr() <<
"[PLYWriter] : Warning: Face normals are not supported and thus not exported! " << std::endl;
135 omerr() <<
"[PLYWriter] : Warning: Face colors are not supported and thus not exported! " << std::endl;
143 omerr() <<
"[PLYWriter] : cannot write to stream "
149 _os.precision(_precision);
153 write_binary(_os, _be, _opt) :
154 write_ascii(_os, _be, _opt));
171 std::vector<CustomProperty> customProps;
172 for (;_begin != _end; ++_begin)
189 assert_compile(
sizeof(
char) == 1);
192 if (castProperty<signed char>(prop) != 0 || castProperty<char>(prop) != 0)
193 cProp.type = ValueTypeCHAR;
194 else if (castProperty<unsigned char>(prop) != 0)
195 cProp.type = ValueTypeUCHAR;
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;
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;
221 assert_compile (
sizeof(
double) == 8);
222 if (castProperty<double>(prop) != 0)
223 cProp.type = ValueTypeDOUBLE;
229 if (cProp.type != Unsupported)
232 customProps.push_back(cProp);
233 _out <<
"property " << nameOfType_[cProp.type] <<
" " << cProp.property->
name() <<
"\n";
241 template<
bool binary>
242 void _PLYWriter_::write_customProp(std::ostream& _out,
const CustomProperty& _prop,
size_t _index)
const
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>());
269 _out <<
"ply" <<
'\n';
271 if (_opt.is_binary()) {
274 _out <<
"binary_big_endian ";
276 _out <<
"binary_little_endian ";
277 _out <<
"1.0" <<
'\n';
279 _out <<
"format ascii 1.0" <<
'\n';
281 _out <<
"element vertex " << _be.n_vertices() <<
'\n';
283 _out <<
"property float x" <<
'\n';
284 _out <<
"property float y" <<
'\n';
285 _out <<
"property float z" <<
'\n';
287 if ( _opt.vertex_has_normal() ){
288 _out <<
"property float nx" <<
'\n';
289 _out <<
"property float ny" <<
'\n';
290 _out <<
"property float nz" <<
'\n';
293 if ( _opt.vertex_has_texcoord() ){
294 _out <<
"property float u" <<
'\n';
295 _out <<
"property float v" <<
'\n';
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';
304 if ( _opt.color_has_alpha() )
305 _out <<
"property float alpha" <<
'\n';
307 _out <<
"property uchar red" <<
'\n';
308 _out <<
"property uchar green" <<
'\n';
309 _out <<
"property uchar blue" <<
'\n';
311 if ( _opt.color_has_alpha() )
312 _out <<
"property uchar alpha" <<
'\n';
318 _out <<
"element face " << _be.n_faces() <<
'\n';
319 _out <<
"property list uchar int vertex_indices" <<
'\n';
323 _out <<
"end_header" <<
'\n';
335 unsigned int i, nV, nF;
343 std::vector<VertexHandle> vhandles;
345 std::vector<CustomProperty> vProps;
346 std::vector<CustomProperty> fProps;
350 if (_opt.color_is_float())
354 for (i=0, nV=
int(_be.n_vertices()); i<nV; ++i)
360 _out << v[0] <<
" " << v[1] <<
" " << v[2];
363 if ( _opt.vertex_has_normal() ){
365 _out <<
" " << n[0] <<
" " << n[1] <<
" " << n[2];
369 if ( _opt.vertex_has_texcoord() ) {
370 t = _be.texcoord(vh);
371 _out <<
" " << t[0] <<
" " << t[1];
375 if ( _opt.vertex_has_color() ) {
377 if ( _opt.color_has_alpha() ){
378 if (_opt.color_is_float()) {
379 cAf = _be.colorAf(vh);
382 cA = _be.colorAi(vh);
387 if (_opt.color_is_float()) {
399 for (std::vector<CustomProperty>::iterator iter = vProps.begin(); iter < vProps.end(); ++iter)
400 write_customProp<false>(_out,*iter,i);
406 for (i=0, nF=
int(_be.n_faces()); i<nF; ++i)
409 nV = _be.get_vhandles(FaceHandle(i), vhandles);
411 for (
size_t j=0; j<vhandles.size(); ++j)
412 _out <<
" " << vhandles[j].idx();
415 for (std::vector<CustomProperty>::iterator iter = fProps.begin(); iter < fProps.end(); ++iter)
416 write_customProp<false>(_out,*iter,i);
427 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out,
int value)
const {
449 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out,
unsigned int value)
const {
471 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out,
float value)
const {
476 case ValueTypeFLOAT32:
482 std::cerr <<
"unsupported conversion type to float: " << _type << std::endl;
487 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out,
double value)
const {
492 case ValueTypeDOUBLE:
497 std::cerr <<
"unsupported conversion type to float: " << _type << std::endl;
502 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out,
signed char value)
const{
512 std::cerr <<
"unsupported conversion type to int: " << _type << std::endl;
516 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out,
unsigned char value)
const{
526 std::cerr <<
"unsupported conversion type to int: " << _type << std::endl;
530 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out,
short value)
const{
540 std::cerr <<
"unsupported conversion type to int: " << _type << std::endl;
544 void _PLYWriter_::writeValue(ValueType _type, std::ostream& _out,
unsigned short value)
const{
549 case ValueTypeUSHORT:
554 std::cerr <<
"unsupported conversion type to int: " << _type << std::endl;
561 write_binary(std::ostream& _out,
BaseExporter& _be, Options _opt)
const
564 unsigned int i, nV, nF;
570 std::vector<VertexHandle> vhandles;
573 std::vector<CustomProperty> vProps;
574 std::vector<CustomProperty> fProps;
579 for (i=0, nV=
int(_be.n_vertices()); i<nV; ++i)
581 vh = VertexHandle(i);
585 writeValue(ValueTypeFLOAT, _out, v[0]);
586 writeValue(ValueTypeFLOAT, _out, v[1]);
587 writeValue(ValueTypeFLOAT, _out, v[2]);
590 if ( _opt.vertex_has_normal() ){
592 writeValue(ValueTypeFLOAT, _out, n[0]);
593 writeValue(ValueTypeFLOAT, _out, n[1]);
594 writeValue(ValueTypeFLOAT, _out, n[2]);
598 if ( _opt.vertex_has_texcoord() ) {
599 t = _be.texcoord(vh);
600 writeValue(ValueTypeFLOAT, _out, t[0]);
601 writeValue(ValueTypeFLOAT, _out, t[1]);
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]);
612 if ( _opt.color_has_alpha() )
613 writeValue(ValueTypeFLOAT, _out, cf[3]);
616 writeValue(ValueTypeUCHAR, _out, (
int)c[0]);
617 writeValue(ValueTypeUCHAR, _out, (
int)c[1]);
618 writeValue(ValueTypeUCHAR, _out, (
int)c[2]);
620 if ( _opt.color_has_alpha() )
621 writeValue(ValueTypeUCHAR, _out, (
int)c[3]);
625 for (std::vector<CustomProperty>::iterator iter = vProps.begin(); iter < vProps.end(); ++iter)
626 write_customProp<true>(_out,*iter,i);
630 for (i=0, nF=
int(_be.n_faces()); i<nF; ++i)
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() );
638 for (std::vector<CustomProperty>::iterator iter = fProps.begin(); iter < fProps.end(); ++iter)
639 write_customProp<true>(_out,*iter,i);
654 size_t _3floats(3*
sizeof(
float));
655 size_t _3ui(3*
sizeof(
unsigned int));
656 size_t _4ui(4*
sizeof(
unsigned int));
658 if ( !_opt.is_binary() )
663 size_t _3longs(3*
sizeof(
long));
667 data += _be.n_vertices() * _3floats;
670 if ( _opt.vertex_has_normal() && _be.has_vertex_normals() )
673 data += _be.n_vertices() * _3floats;
676 if ( _opt.vertex_has_color() && _be.has_vertex_colors() )
679 data += _be.n_vertices() * _3floats;
682 if ( _opt.vertex_has_texcoord() && _be.has_vertex_texcoords() )
684 size_t _2floats(2*
sizeof(
float));
686 data += _be.n_vertices() * _2floats;
690 if (_be.is_triangle_mesh())
692 data += _be.n_faces() * _4ui;
697 std::vector<VertexHandle> vhandles;
699 for (i=0, nF=
int(_be.n_faces()); i<nF; ++i)
701 data += _be.get_vhandles(
FaceHandle(i), vhandles) *
sizeof(
unsigned int);
707 if ( _opt.face_has_color() && _be.has_face_colors() ){
708 if ( _opt.color_has_alpha() )
709 data += _be.n_faces() * _4ui;
711 data += _be.n_faces() * _3ui;
Has (r) / store (w) face colors.
Handle for a vertex entity.
Has (r) / store (w) face normals.
virtual size_t element_size() const =0
Size of one element in bytes or UnknownSize if not known.
Options & unset(const value_type _rhs)
Unset options defined in _rhs.
bool write(const std::string &, BaseExporter &, Options, std::streamsize _precision=6) const
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...
_IOManager_ & IOManager()
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...
Default property class for any type T.
bool persistent(void) const
Returns true if the persistent flag is enabled else false.
Set options for reader/writer modules.
_PLYWriter_ __PLYWriterInstance
Declare the single entity of the PLY writer.
Assume big endian byte ordering.
const std::string & name() const
Return the name of the property.
size_t binary_size(BaseExporter &_be, Options _opt) const
Returns expected size of file if binary format is supported else 0.
bool register_module(BaseReader *_bl)
Handle for a face entity.