MorphoGraphX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PlyFile.hpp
1 #ifndef PLYFILE_HPP
2 #define PLYFILE_HPP
3 
4 #include <Config.hpp>
5 
6 #include <QHash>
7 #include <QList>
8 #include <QString>
9 #include <QStringList>
10 #include <stdint.h>
11 #include <vector>
12 
13 class QFile;
14 
15 #define FORALL_PLY_TYPES(macro) \
16  macro(int8_t); \
17  macro(uint8_t); \
18  macro(int16_t); \
19  macro(uint16_t); \
20  macro(int32_t); \
21  macro(uint32_t); \
22  macro(float); \
23  macro(double)
24 
25 #define FORALL_PLY_TYPEIDS(macro) \
26  macro(int8_t, PlyFile::CHAR); \
27  macro(uint8_t, PlyFile::UCHAR); \
28  macro(int16_t, PlyFile::SHORT); \
29  macro(uint16_t, PlyFile::USHORT); \
30  macro(int32_t, PlyFile::INT); \
31  macro(uint32_t, PlyFile::UINT); \
32  macro(float, PlyFile::FLOAT); \
33  macro(double, PlyFile::DOUBLE)
34 
35 namespace mgx {
36 namespace util {
37 
55 struct PlyFile {
59  enum TYPE {
60  CHAR,
64  INT,
65  UINT,
69  INVALID_TYPE = NB_TYPES
70  };
71 
72 #define INLINE_TYPE_ASSOC(T, TYPEID) \
73  static inline TYPE getType(const T &) { return TYPEID; \
74  }
75  FORALL_PLY_TYPEIDS(INLINE_TYPE_ASSOC)
76 #undef INLINE_TYPE_ASSOC
77 
81  static const unsigned int typeSizes[NB_TYPES];
85  static char const* const typeNames[NB_TYPES + 1];
86 
90  enum FORMAT_TYPES {
95  };
96 
100  static char const* const formatNames[4];
101 
102  struct Element;
103 
109  struct Property {
113  enum KIND {
116  };
128  Property(const QString& name, Element* el = 0);
129 
133  ~Property();
134 
140  void allocate(size_t size);
141 
145  void deallocate();
146 
150  template <typename T> std::vector<std::vector<T> >* list()
151  {
152  if(_kind != LIST)
153  return 0;
154  if(getType(T()) != _memType)
155  return 0;
156  return (std::vector<std::vector<T> >*)_content;
157  }
158 
163  template <typename T> std::vector<T>* value()
164  {
165  if(_kind != VALUE)
166  return 0;
167  if(getType(T()) != _memType)
168  return 0;
169  return (std::vector<T>*)_content;
170  }
171 
175  template <typename T> const std::vector<std::vector<T> >* list() const
176  {
177  if(_kind != LIST)
178  return 0;
179  if(getType(T()) != _memType)
180  return 0;
181  return (const std::vector<std::vector<T> >*)_content;
182  }
183 
188  template <typename T> const std::vector<T>* value() const
189  {
190  if(_kind != VALUE)
191  return 0;
192  if(getType(T()) != _memType)
193  return 0;
194  return (const std::vector<T>*)_content;
195  }
196 
200  bool error(const QString& str) const;
201 
205  const QString& name() const {
206  return _name;
207  }
208 
212  TYPE fileType() const {
213  return _fileType;
214  }
215 
219  TYPE memType() const {
220  return _memType;
221  }
222 
226  TYPE sizeType() const {
227  return _sizeType;
228  }
229 
233  KIND kind() const {
234  return _kind;
235  }
236 
240  size_t size() const {
241  return _size;
242  }
243 
249  bool rename(const QString& n);
250 
254  void setFileType(TYPE ft) {
255  _fileType = ft;
256  }
257 
263  void setMemType(TYPE mt);
264 
268  void setSizeType(TYPE st) {
269  _sizeType = st;
270  }
271 
277  void setKind(KIND k); // Changing the kind after allocation looses all data!
278 
283  return _parent;
284  }
285 
289  const Element* parent() const {
290  return _parent;
291  }
292 
296  bool setParent(Element* parent);
297 
305  void resize(size_t s);
306 
307 protected:
308  QString _name; // Name of the property
309  TYPE _fileType; // type of the elements on the file
310  TYPE _memType; // type of the elements in memory (INVALID_TYPE if the property should not be loaded)
311  TYPE _sizeType; // type used to hold the number of elements (if any)
312  KIND _kind; // Single value or list (later .. vector?)
313  Element* _parent; // Element containing the property (if any)
314  void* _content; // Content of the property, if allocated
315  size_t _size; // Number of elements
316  };
317 
323  struct Element {
336  Element(const QString& name, PlyFile* parent = 0);
337 
341  ~Element();
342 
346  void allocate();
347 
353  void clear();
354 
358  size_t nbProperties() const {
359  return _properties.size();
360  }
361 
365  size_t size() const {
366  return _nbElements;
367  }
368 
374  void resize(size_t n);
375 
379  QStringList properties() const;
380 
384  Property* property(size_t pos);
388  const Property* property(size_t pos) const;
392  Property* property(const QString& name);
396  const Property* property(const QString& name) const;
397 
405  Property* createValue(const QString& name, TYPE file, TYPE mem = INVALID_TYPE);
414  Property* createList(const QString& name, TYPE size, TYPE file, TYPE mem = INVALID_TYPE);
415 
419  bool error(const QString& str) const;
420 
424  bool hasProperty(const QString& name) const;
425 
429  bool attach(Property* prop);
430 
434  bool detach(Property* prop);
435 
439  Property* detach(const QString& name);
440 
444  const QString& name() const {
445  return _name;
446  }
447 
451  bool rename(const QString& n);
452 
456  bool allocated() const {
457  return _allocated;
458  }
459 
463  bool setParent(PlyFile* p);
468  return _parent;
469  }
473  const PlyFile* parent() const {
474  return _parent;
475  }
476 
481  void _rename_prop(Property* prop, const QString& new_name); // Don't call this yourself!
486  void _attach(Property* prop);
491  void _detach(Property* prop);
492 
493 protected:
494  QString _name;
495  size_t _nbElements;
496  QList<Property*> _properties;
497  QHash<QString, int> _property_map;
498  PlyFile* _parent;
499  bool _allocated;
500  };
501 
505  PlyFile();
506 
510  void clear();
511 
516 
520  bool validate();
521 
525  void allocate();
526 
531  return _format;
532  }
537  {
538  if(f != UNSPECIFIED_FORMAT) {
539  _format = f;
540  return true;
541  }
542  return false;
543  }
544 
548  bool setVersion(QString version);
552  const QString& version() const {
553  return _version;
554  }
555 
559  Element* element(size_t idx);
563  const Element* element(size_t idx) const;
567  Element* element(const QString& name);
571  const Element* element(const QString& name) const;
575  Element* createElement(const QString& name, size_t nb_elements);
576 
581  return current_element;
582  }
586  bool hasElement(const QString& name) const;
587 
591  size_t nbElements() const {
592  return _elements.size();
593  }
594 
598  bool attach(Element* el);
599 
603  bool detach(Element* el);
604 
610  bool parseHeader(const QString& filename);
611 
618  bool parseContent(); // Parse the content of the file whose header has been parsed last
619 
624  bool error(const QString err) const;
625 
629  bool save(const QString& filename) const;
630 
636  qint64 contentPosition() const {
637  return _contentPosition;
638  }
639 
643  bool isValid() const {
644  return is_valid;
645  }
649  operator bool() const { return is_valid; }
650 
654  const QStringList& comments() const {
655  return _comments;
656  }
657 
663  void addComment(QString line);
664 
668  void clearComments() {
669  _comments.clear();
670  }
671 
676  void _attach(Element* el);
681  void _detach(Element* el);
682 
683 protected:
684  bool parseAsciiContent(QFile& f);
685  bool parseBinaryContent(QFile& f, bool little_endian);
686 
687  bool readFormat(const QStringList& fields);
688  bool readElement(const QStringList& fields);
689  bool readProperty(const QStringList& fields);
690 
691  bool writeHeader(QFile& f) const;
692  bool writeAsciiContent(QFile& f) const;
693  bool writeBinaryContent(QFile& f, bool little_endian) const;
694 
695  TYPE parseType(QString typeName) const;
696 
697  QList<Element*> _elements;
698  QHash<QString, int> _element_map;
699 
700  Element* current_element;
701 
702  QString filename;
703  int line_nb;
704 
705  FORMAT_TYPES _format;
706  QString _version;
707  QStringList _comments;
708  int _version_major, _version_minor;
709  bool is_valid;
710  qint64 _contentPosition;
711 };
712 } // namespace util
713 } // namespace mgx
714 #endif // PLYFILE_HPP
Class representing an element.
Definition: PlyFile.hpp:323
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:163
The content is written in ASCII.
Definition: PlyFile.hpp:92
Element * createElement(const QString &name, size_t nb_elements)
Create a element name with nb_elements items.
const Element * parent() const
Get the element containing the property, if any.
Definition: PlyFile.hpp:289
bool setVersion(QString version)
Set the format version, checking it's validity.
size_t nbElements() const
Return the number of elements in the file.
Definition: PlyFile.hpp:591
qint64 contentPosition() const
Get the position of the content in a file.
Definition: PlyFile.hpp:636
TYPE
Enumeration for the possible types of the properties.
Definition: PlyFile.hpp:59
TYPE fileType() const
File type of the property value.
Definition: PlyFile.hpp:212
16 bits unsigned integer
Definition: PlyFile.hpp:63
Element * currentElement()
Get the current element (i.e.
Definition: PlyFile.hpp:580
bool save(const QString &filename) const
Save the file to filename.
void setSizeType(TYPE st)
Change the file type of the size of the property.
Definition: PlyFile.hpp:268
Class representing a property in an element.
Definition: PlyFile.hpp:109
The content is written in binary with little endian representation of numbers.
Definition: PlyFile.hpp:93
AttribBase(const QString &name) const QString & name()
Default constructor of named attribute.
Definition: Attributes.hpp:54
bool hasElement(const QString &name) const
Check if the element name exists.
size_t size() const
Number of items in the element.
Definition: PlyFile.hpp:365
bool error(const QString err) const
Write the error on standard out, possibly with file and line number if they have been specified...
void setMemType(TYPE mt)
Change the memory type of the property.
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:188
bool hasProperty(const QString &name) const
Returns true if the element has a property names name.
void allocate(size_t size)
Allocate the memory for the property, as long as memType is not INVALID_TYPE.
Element(const QString &name, PlyFile *parent=0)
Element constructor.
const QString & name() const
Name of the element.
Definition: PlyFile.hpp:444
bool attach(Element *el)
Attach an element to the file.
QStringList properties() const
Get the list of property names.
Element * element(size_t idx)
Access an element by index.
64 bits floating point
Definition: PlyFile.hpp:67
Property(const QString &name, Element *el=0)
Constructor of a property.
size_t size() const
Size of the property, that is the number of elements stored in it.
Definition: PlyFile.hpp:240
Property * createValue(const QString &name, TYPE file, TYPE mem=INVALID_TYPE)
Create a new value property if the name doesn't already exist.
PlyFile * parent()
Get the parent of the element.
Definition: PlyFile.hpp:467
bool init(FORMAT_TYPES format=BINARY_LITTLE_ENDIAN, const QString &version="1.0")
Initialize the file with a format and a version.
const PlyFile * parent() const
Get the parent of the element.
Definition: PlyFile.hpp:473
static const unsigned int typeSizes[NB_TYPES]
Array holding the size in byte of the various types.
Definition: PlyFile.hpp:81
bool parseHeader(const QString &filename)
Parse the head of a PLY file.
void allocate()
Allocate all the properties of all the element in the file.
FORMAT_TYPES
Enumeration of the possible file formats.
Definition: PlyFile.hpp:90
bool validate()
Validate the content.
KIND kind() const
Kind of the property.
Definition: PlyFile.hpp:233
Property * createList(const QString &name, TYPE size, TYPE file, TYPE mem=INVALID_TYPE)
Create a new value property if the name doesn't already exist.
const QString & name() const
Name of the property.
Definition: PlyFile.hpp:205
const QStringList & comments() const
See the comments currently defined.
Definition: PlyFile.hpp:654
The property holds a variable number of values per element.
Definition: PlyFile.hpp:115
void clearComments()
Remove all comments.
Definition: PlyFile.hpp:668
8 bits signed integer
Definition: PlyFile.hpp:60
Property * property(size_t pos)
Access a property by index number.
Number of types, also used to mark an invalid type.
Definition: PlyFile.hpp:68
void clear()
Remove any property attached to this element.
16 bits signed integer
Definition: PlyFile.hpp:62
32 bits signed integer
Definition: PlyFile.hpp:64
TYPE sizeType() const
File type of the size of the property list.
Definition: PlyFile.hpp:226
void allocate()
Allocate the memory for all the properties attached to the element.
TYPE memType() const
Memory type of the property value.
Definition: PlyFile.hpp:219
bool error(const QString &str) const
Write the error in the standard out and return false.
bool error(const QString &str) const
Print an error on the standard output and return false.
32 bits floating point
Definition: PlyFile.hpp:66
PlyFile()
Create a new file.
bool detach(Property *prop)
Remove a property from the element.
bool allocated() const
Return true if the element has been allocated.
Definition: PlyFile.hpp:456
8 bits unsigned integer
Definition: PlyFile.hpp:61
static char const *const formatNames[4]
Array of C-string representation of the formats.
Definition: PlyFile.hpp:100
bool setParent(PlyFile *p)
Change the parent of the element, only if the new parent doesn't have an element with the same name...
void addComment(QString line)
Add a comment.
The content is written in binary with big endian representation of numbers.
Definition: PlyFile.hpp:94
void resize(size_t n)
Change the number of items in the element.
~Property()
The destructor takes charge to detach the property from any element that contains it...
32 bits unsigned integer
Definition: PlyFile.hpp:65
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:175
The format is not yet specified.
Definition: PlyFile.hpp:91
bool rename(const QString &n)
Rename the element, only if the containing PLY file doesn't already contain an element with the new n...
void resize(size_t s)
Resize the property.
Element * parent()
Get the element containing the property, if any.
Definition: PlyFile.hpp:282
FORMAT_TYPES format() const
Format of the file.
Definition: PlyFile.hpp:530
Class representing the content of a PLY file.
Definition: PlyFile.hpp:55
bool setParent(Element *parent)
Change the parent, only if the new parent doesn't already have a property with the same name...
const QString & version() const
Version fo the format.
Definition: PlyFile.hpp:552
void deallocate()
Free the memory occupied by the property.
static char const *const typeNames[NB_TYPES+1]
Array of C-string representation of the types.
Definition: PlyFile.hpp:85
void setKind(KIND k)
Change the kind of the property.
bool attach(Property *prop)
Attach a property to the element.
bool rename(const QString &n)
Change the name of the property, only if the new name doesn't conflict with one of the other properti...
bool isValid() const
Check if the last call to PlyFile::validate was successful of not.
Definition: PlyFile.hpp:643
bool detach(Element *el)
Detach an element from the file.
void setFileType(TYPE ft)
Change the file type of the property.
Definition: PlyFile.hpp:254
size_t nbProperties() const
Number of properties in the element.
Definition: PlyFile.hpp:358
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:150
bool setFormat(FORMAT_TYPES f)
Set the file format, checking the validity of the argument.
Definition: PlyFile.hpp:536
KIND
Kind of a property.
Definition: PlyFile.hpp:113
~Element()
The destructor takes care of detaching the element from the PLY file that contains it...
bool parseContent()
Parse the content of the current file.
void clear()
Remove any element from the file, and reset version number and format.
The property holds a single value per element.
Definition: PlyFile.hpp:114