MorphoGraphX  2.0-1-227
PlyFile.hpp
Go to the documentation of this file.
1 //
2 // This file is part of MorphoGraphX - http://www.MorphoGraphX.org
3 // Copyright (C) 2012-2015 Richard S. Smith and collaborators.
4 //
5 // If you use MorphoGraphX in your work, please cite:
6 // http://dx.doi.org/10.7554/eLife.05864
7 //
8 // MorphoGraphX is free software, and is licensed under under the terms of the
9 // GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
10 //
11 #ifndef PLYFILE_HPP
12 #define PLYFILE_HPP
13 
14 #include <Config.hpp>
15 
16 #include <QHash>
17 #include <QList>
18 #include <QString>
19 #include <QStringList>
20 #include <stdint.h>
21 #include <vector>
22 
23 class QFile;
24 
25 #define FORALL_PLY_TYPES(macro) \
26  macro(int8_t); \
27  macro(uint8_t); \
28  macro(int16_t); \
29  macro(uint16_t); \
30  macro(int32_t); \
31  macro(uint32_t); \
32  macro(float); \
33  macro(double)
34 
35 #define FORALL_PLY_TYPEIDS(macro) \
36  macro(int8_t, PlyFile::CHAR); \
37  macro(uint8_t, PlyFile::UCHAR); \
38  macro(int16_t, PlyFile::SHORT); \
39  macro(uint16_t, PlyFile::USHORT); \
40  macro(int32_t, PlyFile::INT); \
41  macro(uint32_t, PlyFile::UINT); \
42  macro(float, PlyFile::FLOAT); \
43  macro(double, PlyFile::DOUBLE)
44 
45 namespace mgx
46 {
64  struct mgx_EXPORT PlyFile {
68  enum TYPE {
69  CHAR,
73  INT,
74  UINT,
78  INVALID_TYPE = NB_TYPES
79  };
80 
81  #define INLINE_TYPE_ASSOC(T, TYPEID) \
82  static inline TYPE getType(const T &) { return TYPEID; \
83  }
85  #undef INLINE_TYPE_ASSOC
86 
90  static const unsigned int typeSizes[NB_TYPES];
94  static char const* const typeNames[NB_TYPES + 1][3];
95 
99  enum FORMAT_TYPES {
100  UNSPECIFIED_FORMAT = 0,
103  BINARY_BIG_ENDIAN
104  };
105 
109  static char const* const formatNames[4];
110 
111  struct Element;
112 
118  struct Property {
122  enum KIND {
124  LIST
125  };
137  Property(const QString& name, Element* el = 0);
138 
142  ~Property();
143 
149  void allocate(size_t size);
150 
154  void deallocate();
155 
159  template <typename T> std::vector<std::vector<T> >* list()
160  {
161  if(_kind != LIST)
162  return 0;
163  if(getType(T()) != _memType)
164  return 0;
165  return (std::vector<std::vector<T> >*)_content;
166  }
167 
172  template <typename T> std::vector<T>* value()
173  {
174  if(_kind != VALUE)
175  return 0;
176  if(getType(T()) != _memType)
177  return 0;
178  return (std::vector<T>*)_content;
179  }
180 
184  template <typename T> const std::vector<std::vector<T> >* list() const
185  {
186  if(_kind != LIST)
187  return 0;
188  if(getType(T()) != _memType)
189  return 0;
190  return (const std::vector<std::vector<T> >*)_content;
191  }
192 
197  template <typename T> const std::vector<T>* value() const
198  {
199  if(_kind != VALUE)
200  return 0;
201  if(getType(T()) != _memType)
202  return 0;
203  return (const std::vector<T>*)_content;
204  }
205 
209  bool error(const QString& str) const;
210 
214  const QString& name() const {
215  return _name;
216  }
217 
221  TYPE fileType() const {
222  return _fileType;
223  }
224 
228  TYPE memType() const {
229  return _memType;
230  }
231 
235  TYPE sizeType() const {
236  return _sizeType;
237  }
238 
242  KIND kind() const {
243  return _kind;
244  }
245 
249  size_t size() const {
250  return _size;
251  }
252 
258  bool rename(const QString& n);
259 
263  void setFileType(TYPE ft) {
264  _fileType = ft;
265  }
266 
272  void setMemType(TYPE mt);
273 
277  void setSizeType(TYPE st) {
278  _sizeType = st;
279  }
280 
286  void setKind(KIND k); // Changing the kind after allocation looses all data!
287 
292  return _parent;
293  }
294 
298  const Element* parent() const {
299  return _parent;
300  }
301 
305  bool setParent(Element* parent);
306 
314  void resize(size_t s);
315 
316  protected:
317  QString _name; // Name of the property
318  TYPE _fileType; // type of the elements on the file
319  TYPE _memType; // type of the elements in memory (INVALID_TYPE if the property should not be loaded)
320  TYPE _sizeType; // type used to hold the number of elements (if any)
321  KIND _kind; // Single value or list (later .. vector?)
322  Element* _parent; // Element containing the property (if any)
323  void* _content; // Content of the property, if allocated
324  size_t _size; // Number of elements
325  };
326 
332  struct Element {
345  Element(const QString& name, PlyFile* parent = 0);
346 
350  ~Element();
351 
355  void allocate();
356 
362  void clear();
363 
367  size_t nbProperties() const {
368  return _properties.size();
369  }
370 
374  size_t size() const {
375  return _nbElements;
376  }
377 
383  void resize(size_t n);
384 
388  QStringList properties() const;
389 
393  Property* property(size_t pos);
397  const Property* property(size_t pos) const;
401  Property* property(const QString& name);
405  const Property* property(const QString& name) const;
406 
414  Property* createValue(const QString& name, TYPE file, TYPE mem = INVALID_TYPE);
423  Property* createList(const QString& name, TYPE size, TYPE file, TYPE mem = INVALID_TYPE);
424 
428  bool error(const QString& str) const;
429 
433  bool hasProperty(const QString& name) const;
434 
438  bool attach(Property* prop);
439 
443  bool detach(Property* prop);
444 
448  Property* detach(const QString& name);
449 
453  const QString& name() const {
454  return _name;
455  }
456 
460  bool rename(const QString& n);
461 
465  bool allocated() const {
466  return _allocated;
467  }
468 
472  bool setParent(PlyFile* p);
477  return _parent;
478  }
482  const PlyFile* parent() const {
483  return _parent;
484  }
485 
490  void _rename_prop(Property* prop, const QString& new_name); // Don't call this yourself!
495  void _attach(Property* prop);
500  void _detach(Property* prop);
501 
502  protected:
503  QString _name;
504  size_t _nbElements;
505  QList<Property*> _properties;
506  QHash<QString, int> _property_map;
509  };
510 
514  PlyFile();
515 
519  void clear();
520 
524  bool init(FORMAT_TYPES format = BINARY_LITTLE_ENDIAN, const QString& version = "1.0");
525 
529  bool validate();
530 
534  void allocate();
535 
540  return _format;
541  }
546  {
547  if(f != UNSPECIFIED_FORMAT) {
548  _format = f;
549  return true;
550  }
551  return false;
552  }
553 
557  bool setVersion(QString version);
561  const QString& version() const {
562  return _version;
563  }
564 
568  Element* element(size_t idx);
572  const Element* element(size_t idx) const;
576  Element* element(const QString& name);
580  const Element* element(const QString& name) const;
584  Element* createElement(const QString& name, size_t nb_elements);
585 
590  return current_element;
591  }
595  bool hasElement(const QString& name) const;
596 
600  size_t nbElements() const {
601  return _elements.size();
602  }
603 
607  bool attach(Element* el);
608 
612  bool detach(Element* el);
613 
619  bool parseHeader(const QString& filename);
620 
627  bool parseContent(); // Parse the content of the file whose header has been parsed last
628 
633  bool error(const QString err) const;
634 
638  bool save(const QString& filename) const;
639 
645  qint64 contentPosition() const {
646  return _contentPosition;
647  }
648 
652  bool isValid() const {
653  return is_valid;
654  }
658  operator bool() const { return is_valid; }
659 
663  const QStringList& comments() const {
664  return _comments;
665  }
666 
672  void addComment(QString line);
673 
677  void clearComments() {
678  _comments.clear();
679  }
680 
685  void _attach(Element* el);
690  void _detach(Element* el);
691 
692  protected:
693  bool parseAsciiContent(QFile& f);
694  bool parseBinaryContent(QFile& f, bool little_endian);
695 
696  bool readFormat(const QStringList& fields);
697  bool readElement(const QStringList& fields);
698  bool readProperty(const QStringList& fields);
699 
700  bool writeHeader(QFile& f) const;
701  bool writeAsciiContent(QFile& f) const;
702  bool writeBinaryContent(QFile& f, bool little_endian) const;
703 
704  TYPE parseType(QString typeName) const;
705 
706  QList<Element*> _elements;
707  QHash<QString, int> _element_map;
708 
710 
711  QString filename;
712  int line_nb;
713 
715  QString _version;
716  QStringList _comments;
717  int _version_major, _version_minor;
718  bool is_valid;
720  };
721 }
722 #endif
mgx::PlyFile::Element::_name
QString _name
Definition: PlyFile.hpp:503
mgx::PlyFile::NB_TYPES
@ NB_TYPES
Number of types, also used to mark an invalid type.
Definition: PlyFile.hpp:77
mgx::PlyFile::Property::KIND
KIND
Kind of a property.
Definition: PlyFile.hpp:122
mgx::PlyFile::Property::_name
QString _name
Definition: PlyFile.hpp:317
mgx::PlyFile::Property::_memType
TYPE _memType
Definition: PlyFile.hpp:319
mgx::PlyFile::is_valid
bool is_valid
Definition: PlyFile.hpp:718
mgx::PlyFile::setFormat
bool setFormat(FORMAT_TYPES f)
Set the file format, checking the validity of the argument.
Definition: PlyFile.hpp:545
mgx::PlyFile::Property::name
const QString & name() const
Name of the property.
Definition: PlyFile.hpp:214
mgx::PlyFile::Property::_content
void * _content
Definition: PlyFile.hpp:323
mgx::PlyFile::FLOAT
@ FLOAT
32 bits floating point
Definition: PlyFile.hpp:75
mgx::PlyFile::Element::name
const QString & name() const
Name of the element.
Definition: PlyFile.hpp:453
mgx::PlyFile::Property::_sizeType
TYPE _sizeType
Definition: PlyFile.hpp:320
mgx::PlyFile::Element::_parent
PlyFile * _parent
Definition: PlyFile.hpp:507
mgx::PlyFile::Property::_size
size_t _size
Definition: PlyFile.hpp:324
mgx::PlyFile
Definition: PlyFile.hpp:64
mgx::PlyFile::Element::allocated
bool allocated() const
Return true if the element has been allocated.
Definition: PlyFile.hpp:465
n
#define n
Definition: Eigenvalues.hpp:36
mgx::Information::err
mgx_EXPORT QTextStream err
mgx::PlyFile::INT
@ INT
32 bits signed integer
Definition: PlyFile.hpp:73
mgx::PlyFile::UINT
@ UINT
32 bits unsigned integer
Definition: PlyFile.hpp:74
mgx::PlyFile::Element::parent
PlyFile * parent()
Get the parent of the element.
Definition: PlyFile.hpp:476
mgx::PlyFile::Property::kind
KIND kind() const
Kind of the property.
Definition: PlyFile.hpp:242
mgx::PlyFile::Element::nbProperties
size_t nbProperties() const
Number of properties in the element.
Definition: PlyFile.hpp:367
mgx::PlyFile::Property::list
std::vector< std::vector< T > > * list()
Return a pointer to the list help by the property as long as the property is a list and the type is c...
Definition: PlyFile.hpp:159
mgx::PlyFile::Property::memType
TYPE memType() const
Memory type of the property value.
Definition: PlyFile.hpp:228
mgx::Information::init
mgx_EXPORT void init(QMainWindow *wnd)
mgx::PlyFile::USHORT
@ USHORT
16 bits unsigned integer
Definition: PlyFile.hpp:72
mgx
Distributed matrix library.
Definition: Assert.hpp:26
mgx::PlyFile::format
FORMAT_TYPES format() const
Format of the file.
Definition: PlyFile.hpp:539
mgx::PlyFile::Property::size
size_t size() const
Size of the property, that is the number of elements stored in it.
Definition: PlyFile.hpp:249
mgx::PlyFile::TYPE
TYPE
Enumeration for the possible types of the properties.
Definition: PlyFile.hpp:68
mgx::PlyFile::version
const QString & version() const
Version fo the format.
Definition: PlyFile.hpp:561
mgx::PlyFile::Property::setFileType
void setFileType(TYPE ft)
Change the file type of the property.
Definition: PlyFile.hpp:263
mgx::PlyFile::Property::value
std::vector< T > * value()
Return a pointer to the values help by the property as long as the property is a value and the type i...
Definition: PlyFile.hpp:172
INLINE_TYPE_ASSOC
#define INLINE_TYPE_ASSOC(T, TYPEID)
Definition: PlyFile.hpp:81
mgx::PlyFile::Element::_nbElements
size_t _nbElements
Definition: PlyFile.hpp:504
mgx::PlyFile::CHAR
@ CHAR
8 bits signed integer
Definition: PlyFile.hpp:69
mgx::PlyFile::Property::_fileType
TYPE _fileType
Definition: PlyFile.hpp:318
mgx::PlyFile::Property::_kind
KIND _kind
Definition: PlyFile.hpp:321
mgx::PlyFile::ASCII
@ ASCII
The content is written in ASCII.
Definition: PlyFile.hpp:101
mgx::PlyFile::Property::fileType
TYPE fileType() const
File type of the property value.
Definition: PlyFile.hpp:221
mgx::PlyFile::FORMAT_TYPES
FORMAT_TYPES
Enumeration of the possible file formats.
Definition: PlyFile.hpp:99
mgx::resize
mgx_EXPORT HVecUS resize(const HVecUS &data, const Point3i &before, const Point3i &after, bool center)
mgx::PlyFile::Element
Definition: PlyFile.hpp:332
mgx::PlyFile::isValid
bool isValid() const
Check if the last call to PlyFile::validate was successful of not.
Definition: PlyFile.hpp:652
mgx::PlyFile::_element_map
QHash< QString, int > _element_map
Definition: PlyFile.hpp:707
mgx::PlyFile::_comments
QStringList _comments
Definition: PlyFile.hpp:716
mgx::PlyFile::Element::_allocated
bool _allocated
Definition: PlyFile.hpp:508
mgx::PlyFile::Element::size
size_t size() const
Number of items in the element.
Definition: PlyFile.hpp:374
mgx::PlyFile::Property::value
const std::vector< T > * value() const
Return a pointer to the values help by the property as long as the property is a value and the type i...
Definition: PlyFile.hpp:197
mgx::PlyFile::Element::_property_map
QHash< QString, int > _property_map
Definition: PlyFile.hpp:506
mgx::PlyFile::current_element
Element * current_element
Definition: PlyFile.hpp:709
mgx::PlyFile::SHORT
@ SHORT
16 bits signed integer
Definition: PlyFile.hpp:71
mgx::PlyFile::Property::setSizeType
void setSizeType(TYPE st)
Change the file type of the size of the property.
Definition: PlyFile.hpp:277
mgx::PlyFile::Property::sizeType
TYPE sizeType() const
File type of the size of the property list.
Definition: PlyFile.hpp:235
mgx::PlyFile::clearComments
void clearComments()
Remove all comments.
Definition: PlyFile.hpp:677
mgx::PlyFile::BINARY_LITTLE_ENDIAN
@ BINARY_LITTLE_ENDIAN
The content is written in binary with little endian representation of numbers.
Definition: PlyFile.hpp:102
mgx::PlyFile::Property::VALUE
@ VALUE
The property holds a single value per element.
Definition: PlyFile.hpp:123
mgx::PlyFile::_elements
QList< Element * > _elements
Definition: PlyFile.hpp:706
FORALL_PLY_TYPEIDS
#define FORALL_PLY_TYPEIDS(macro)
Definition: PlyFile.hpp:35
mgx::PlyFile::comments
const QStringList & comments() const
See the comments currently defined.
Definition: PlyFile.hpp:663
mgx::PlyFile::filename
QString filename
Definition: PlyFile.hpp:711
mgx::PlyFile::currentElement
Element * currentElement()
Get the current element (i.e.
Definition: PlyFile.hpp:589
mgx::PlyFile::contentPosition
qint64 contentPosition() const
Get the position of the content in a file.
Definition: PlyFile.hpp:645
mgx::PlyFile::line_nb
int line_nb
Definition: PlyFile.hpp:712
mgx::PlyFile::UCHAR
@ UCHAR
8 bits unsigned integer
Definition: PlyFile.hpp:70
mgx::PlyFile::Property::_parent
Element * _parent
Definition: PlyFile.hpp:322
mgx::PlyFile::Property::parent
Element * parent()
Get the element containing the property, if any.
Definition: PlyFile.hpp:291
mgx::PlyFile::_contentPosition
qint64 _contentPosition
Definition: PlyFile.hpp:719
mgx::PlyFile::nbElements
size_t nbElements() const
Return the number of elements in the file.
Definition: PlyFile.hpp:600
mgx::PlyFile::Element::parent
const PlyFile * parent() const
Get the parent of the element.
Definition: PlyFile.hpp:482
mgx::PlyFile::DOUBLE
@ DOUBLE
64 bits floating point
Definition: PlyFile.hpp:76
mgx::PlyFile::_version
QString _version
Definition: PlyFile.hpp:715
mgx::PlyFile::_format
FORMAT_TYPES _format
Definition: PlyFile.hpp:714
mgx::PlyFile::Element::_properties
QList< Property * > _properties
Definition: PlyFile.hpp:505
mgx::PlyFile::Property
Definition: PlyFile.hpp:118
mgx::PlyFile::Property::parent
const Element * parent() const
Get the element containing the property, if any.
Definition: PlyFile.hpp:298
mgx::PlyFile::_version_minor
int _version_minor
Definition: PlyFile.hpp:717
mgx::PlyFile::Property::list
const std::vector< std::vector< T > > * list() const
Return a pointer to the list help by the property as long as the property is a list and the type is c...
Definition: PlyFile.hpp:184