libigl v2.5.0
Loading...
Searching...
No Matches
tinyply.h
Go to the documentation of this file.
1/*
2 * tinyply 2.3.2 (https://github.com/ddiakopoulos/tinyply)
3 *
4 * A single-header, zero-dependency (except the C++ STL) public domain implementation
5 * of the PLY mesh file format. Requires C++11; errors are handled through exceptions.
6 *
7 * This software is in the public domain. Where that dedication is not
8 * recognized, you are granted a perpetual, irrevocable license to copy,
9 * distribute, and modify this file as you see fit.
10 *
11 * Authored by Dimitri Diakopoulos (http://www.dimitridiakopoulos.com)
12 *
13 * tinyply.h may be included in many files, however in a single compiled file,
14 * the implementation must be created with the following defined prior to header inclusion
15 * #define TINYPLY_IMPLEMENTATION
16 *
17 */
18
20// tinyply header //
22
23#ifndef tinyply_h
24#define tinyply_h
25#include "igl_inline.h"
26
27#include <vector>
28#include <string>
29#include <stdint.h>
30#include <cstddef>
31#include <sstream>
32#include <memory>
33#include <unordered_map>
34#include <map>
35#include <algorithm>
36#include <functional>
37#include <stdint.h>
38
39namespace igl
40{
41namespace tinyply
42{
43
44 enum class Type : uint8_t
45 {
46 INVALID,
47 INT8,
48 UINT8,
49 INT16,
50 UINT16,
51 INT32,
52 UINT32,
53 FLOAT32,
54 FLOAT64
55 };
56
57 struct PropertyInfo
58 {
59 PropertyInfo() {};
60 PropertyInfo(int stride, std::string str)
61 : stride(stride), str(str) {}
62 int stride {0};
63 std::string str;
64 };
65
66 static std::map<Type, PropertyInfo> PropertyTable
67 {
68 { Type::INT8, PropertyInfo(1, std::string("char")) },
69 { Type::UINT8, PropertyInfo(1, std::string("uchar")) },
70 { Type::INT16, PropertyInfo(2, std::string("short")) },
71 { Type::UINT16, PropertyInfo(2, std::string("ushort")) },
72 { Type::INT32, PropertyInfo(4, std::string("int")) },
73 { Type::UINT32, PropertyInfo(4, std::string("uint")) },
74 { Type::FLOAT32, PropertyInfo(4, std::string("float")) },
75 { Type::FLOAT64, PropertyInfo(8, std::string("double")) },
76 { Type::INVALID, PropertyInfo(0, std::string("INVALID"))}
77 };
78
79 class Buffer
80 {
81 uint8_t * alias{ nullptr };
82 struct delete_array { void operator()(uint8_t * p) { delete[] p; } };
83 std::unique_ptr<uint8_t, decltype(Buffer::delete_array())> data;
84 size_t size {0};
85 public:
86 Buffer() {};
87 Buffer(const size_t size) : data(new uint8_t[size], delete_array()), size(size) { alias = data.get(); } // allocating
88 Buffer(uint8_t * ptr): alias(ptr) { } // non-allocating, todo: set size?
89 uint8_t * get() { return alias; }
90 size_t size_bytes() const { return size; }
91 };
92
93 struct PlyData
94 {
95 Type t;
96 Buffer buffer;
97 size_t count {0};
98 bool isList {false};
99 };
100
101 struct PlyProperty
102 {
103 PlyProperty(std::istream & is);
104 PlyProperty(Type type, std::string & _name) : name(_name), propertyType(type) {}
105 PlyProperty(Type list_type, Type prop_type, std::string & _name, size_t list_count)
106 : name(_name), propertyType(prop_type), isList(true), listType(list_type), listCount(list_count) {}
107 std::string name;
108 Type propertyType{ Type::INVALID };
109 bool isList{ false };
110 Type listType{ Type::INVALID };
111 size_t listCount {0};
112 };
113
114 struct PlyElement
115 {
116 PlyElement(std::istream & istream);
117 PlyElement(const std::string & _name, size_t count) : name(_name), size(count) {}
118 std::string name;
119 size_t size {0};
120 std::vector<PlyProperty> properties;
121 };
122
123 struct PlyFile
124 {
125 struct PlyFileImpl;
126 std::unique_ptr<PlyFileImpl> impl;
127
128 PlyFile();
129 ~PlyFile();
130
131 /*
132 * The ply format requires an ascii header. This can be used to determine at
133 * runtime which properties or elements exist in the file. Limited validation of the
134 * header is performed; it is assumed the header correctly reflects the contents of the
135 * payload. This function may throw. Returns true on success, false on failure.
136 */
137 bool parse_header(std::istream & is);
138
139 /*
140 * Execute a read operation. Data must be requested via `request_properties_from_element(...)`
141 * prior to calling this function.
142 */
143 void read(std::istream & is);
144
145 /*
146 * `write` performs no validation and assumes that the data passed into
147 * `add_properties_to_element` is well-formed.
148 */
149 void write(std::ostream & os, bool isBinary);
150
151 /*
152 * These functions are valid after a call to `parse_header(...)`. In the case of
153 * writing, get_comments() reference may also be used to add new comments to the ply header.
154 */
155 std::vector<PlyElement> get_elements() const;
156 std::vector<std::string> get_info() const;
157 std::vector<std::string> & get_comments();
158 bool is_binary_file() const;
159
160 /*
161 * In the general case where |list_size_hint| is zero, `read` performs a two-pass
162 * parse to support variable length lists. The most general use of the
163 * ply format is storing triangle meshes. When this fact is known a-priori, we can pass
164 * an expected list length that will apply to this element. Doing so results in an up-front
165 * memory allocation and a single-pass import, a 2x performance optimization.
166 */
167 std::shared_ptr<PlyData> request_properties_from_element(const std::string & elementKey,
168 const std::vector<std::string> propertyKeys, const uint32_t list_size_hint = 0);
169
170 void add_properties_to_element(const std::string & elementKey,
171 const std::vector<std::string> propertyKeys,
172 const Type type,
173 const size_t count,
174 uint8_t * data,
175 const Type listType,
176 const size_t listCount);
177 };
178
179} // end namespace tinyply
180} // end namespace igl
181
182#ifndef IGL_STATIC_LIBRARY
183// implementation moved to tinyply.cpp
184# include "tinyply.cpp"
185#endif
186
187
188#endif // end tinyply_h
Definition AABB.h:18
void count(const Eigen::SparseMatrix< XType > &X, const int dim, Eigen::SparseVector< SType > &S)
Count the number of non-zeros in the columns or rows of a sparse matrix.