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
38namespace igl
39{
40namespace tinyply
41{
42
43 enum class Type : uint8_t
44 {
45 INVALID,
46 INT8,
47 UINT8,
48 INT16,
49 UINT16,
50 INT32,
51 UINT32,
52 FLOAT32,
53 FLOAT64
54 };
55
56 struct PropertyInfo
57 {
58 PropertyInfo() {};
59 PropertyInfo(int stride, std::string str)
60 : stride(stride), str(str) {}
61 int stride {0};
62 std::string str;
63 };
64
65 static std::map<Type, PropertyInfo> PropertyTable
66 {
67 { Type::INT8, PropertyInfo(1, std::string("char")) },
68 { Type::UINT8, PropertyInfo(1, std::string("uchar")) },
69 { Type::INT16, PropertyInfo(2, std::string("short")) },
70 { Type::UINT16, PropertyInfo(2, std::string("ushort")) },
71 { Type::INT32, PropertyInfo(4, std::string("int")) },
72 { Type::UINT32, PropertyInfo(4, std::string("uint")) },
73 { Type::FLOAT32, PropertyInfo(4, std::string("float")) },
74 { Type::FLOAT64, PropertyInfo(8, std::string("double")) },
75 { Type::INVALID, PropertyInfo(0, std::string("INVALID"))}
76 };
77
78 class Buffer
79 {
80 uint8_t * alias{ nullptr };
81 struct delete_array { void operator()(uint8_t * p) { delete[] p; } };
82 std::unique_ptr<uint8_t, decltype(Buffer::delete_array())> data;
83 size_t size {0};
84 public:
85 Buffer() {};
86 Buffer(const size_t size) : data(new uint8_t[size], delete_array()), size(size) { alias = data.get(); } // allocating
87 Buffer(uint8_t * ptr): alias(ptr) { } // non-allocating, todo: set size?
88 uint8_t * get() { return alias; }
89 size_t size_bytes() const { return size; }
90 };
91
92 struct PlyData
93 {
94 Type t;
95 Buffer buffer;
96 size_t count {0};
97 bool isList {false};
98 };
99
100 struct PlyProperty
101 {
102 PlyProperty(std::istream & is);
103 PlyProperty(Type type, std::string & _name) : name(_name), propertyType(type) {}
104 PlyProperty(Type list_type, Type prop_type, std::string & _name, size_t list_count)
105 : name(_name), propertyType(prop_type), isList(true), listType(list_type), listCount(list_count) {}
106 std::string name;
107 Type propertyType{ Type::INVALID };
108 bool isList{ false };
109 Type listType{ Type::INVALID };
110 size_t listCount {0};
111 };
112
113 struct PlyElement
114 {
115 PlyElement(std::istream & istream);
116 PlyElement(const std::string & _name, size_t count) : name(_name), size(count) {}
117 std::string name;
118 size_t size {0};
119 std::vector<PlyProperty> properties;
120 };
121
122 struct PlyFile
123 {
124 struct PlyFileImpl;
125 std::unique_ptr<PlyFileImpl> impl;
126
127 PlyFile();
128 ~PlyFile();
129
130 /*
131 * The ply format requires an ascii header. This can be used to determine at
132 * runtime which properties or elements exist in the file. Limited validation of the
133 * header is performed; it is assumed the header correctly reflects the contents of the
134 * payload. This function may throw. Returns true on success, false on failure.
135 */
136 bool parse_header(std::istream & is);
137
138 /*
139 * Execute a read operation. Data must be requested via `request_properties_from_element(...)`
140 * prior to calling this function.
141 */
142 void read(std::istream & is);
143
144 /*
145 * `write` performs no validation and assumes that the data passed into
146 * `add_properties_to_element` is well-formed.
147 */
148 void write(std::ostream & os, bool isBinary);
149
150 /*
151 * These functions are valid after a call to `parse_header(...)`. In the case of
152 * writing, get_comments() reference may also be used to add new comments to the ply header.
153 */
154 std::vector<PlyElement> get_elements() const;
155 std::vector<std::string> get_info() const;
156 std::vector<std::string> & get_comments();
157 bool is_binary_file() const;
158
159 /*
160 * In the general case where |list_size_hint| is zero, `read` performs a two-pass
161 * parse to support variable length lists. The most general use of the
162 * ply format is storing triangle meshes. When this fact is known a-priori, we can pass
163 * an expected list length that will apply to this element. Doing so results in an up-front
164 * memory allocation and a single-pass import, a 2x performance optimization.
165 */
166 std::shared_ptr<PlyData> request_properties_from_element(const std::string & elementKey,
167 const std::vector<std::string> propertyKeys, const uint32_t list_size_hint = 0);
168
169 void add_properties_to_element(const std::string & elementKey,
170 const std::vector<std::string> propertyKeys,
171 const Type type,
172 const size_t count,
173 uint8_t * data,
174 const Type listType,
175 const size_t listCount);
176 };
177
178} // end namespace tinyply
179} // end namespace igl
180
181#ifndef IGL_STATIC_LIBRARY
182// implementation moved to tinyply.cpp
183# include "tinyply.cpp"
184#endif
185
186
187#endif // end tinyply_h
Definition AABB.h:17
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.