1 /* 2 This file forked from https://github.com/srajotte/libplyxx 3 4 Copyright (c) 2016 Simon Rajotte 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in all 14 copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 SOFTWARE. 23 24 Updated (c) 2021 Runette Software Ltd to make multiplatform, to complete the typemaps and add to voxel types. 25 26 Permission is hereby granted, free of charge, to any person obtaining a copy 27 of this software and associated documentation files (the "Software"), to deal 28 in the Software without restriction, including without limitation the rights 29 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 30 copies of the Software, and to permit persons to whom the Software is 31 furnished to do so, subject to the following conditions: 32 33 The above copyright notice and this permission notice shall be included in all 34 copies or substantial portions of the Software. 35 36 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 39 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 40 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 41 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 42 SOFTWARE. 43 44 */ 45 46 #pragma once 47 48 #include <vector> 49 #include <array> 50 #include <map> 51 #include <unordered_map> 52 #include <type_traits> 53 #include <cassert> 54 #include <memory> 55 #include <functional> 56 57 #include "textio.h" 58 59 namespace libply 60 { 61 enum class Type 62 { 63 INT8, 64 UINT8, 65 INT16, 66 UINT16, 67 INT32, 68 UINT32, 69 FLOAT32, 70 FLOAT64, 71 COORDINATE 72 }; 73 74 class IProperty 75 { 76 public: 77 virtual ~IProperty() = default; 78 79 virtual IProperty &operator=( unsigned int value ) = 0; 80 virtual IProperty &operator=( int value ) = 0; 81 virtual IProperty &operator=( float value ) = 0; 82 virtual IProperty &operator=( double value ) = 0; 83 84 virtual operator unsigned int() = 0; 85 virtual operator int() = 0; 86 virtual operator float() = 0; 87 virtual operator double() = 0; 88 89 virtual bool isList() = 0; 90 91 }; 92 93 template<typename InternalType> 94 class ScalarProperty: public IProperty 95 { 96 public : 97 98 virtual ~ScalarProperty() = default; 99 100 virtual ScalarProperty &operator=( unsigned int value ) override 101 { 102 m_value = static_cast<InternalType>( value ); 103 return *this; 104 }; 105 virtual ScalarProperty &operator=( int value ) override 106 { 107 m_value = static_cast<InternalType>( value ); 108 return *this; 109 }; 110 virtual ScalarProperty &operator=( float value ) override 111 { 112 m_value = static_cast<InternalType>( value ); 113 return *this; 114 }; 115 virtual ScalarProperty &operator=( double value ) override 116 { 117 m_value = static_cast<InternalType>( value ); 118 return *this; 119 }; 120 121 virtual operator unsigned int() override 122 { 123 return static_cast<unsigned int>( m_value ); 124 }; 125 virtual operator int() override 126 { 127 return static_cast<int>( m_value ); 128 }; 129 virtual operator float() override 130 { 131 return static_cast<float>( m_value ); 132 }; 133 virtual operator double() override 134 { 135 return static_cast<double>( m_value ); 136 }; 137 isList()138 virtual bool isList() override { return false; } 139 140 public: value()141 InternalType value() const { return m_value; }; 142 143 private : 144 InternalType m_value; 145 }; 146 147 class ListProperty : public IProperty 148 { 149 public: 150 151 IProperty &operator=( unsigned int ) override { return *this; }; 152 IProperty &operator=( int ) override { return *this; }; 153 IProperty &operator=( float ) override { return *this; }; 154 IProperty &operator=( double ) override { return *this; }; 155 156 operator unsigned int() override { return 0; }; 157 operator int() override { return 0; }; 158 operator float() override { return 0; }; 159 operator double() override { return 0; }; 160 isList()161 bool isList() override { return true; } 162 163 void define( Type type, size_t size ); size()164 size_t size() const { return list.size(); } 165 166 IProperty &value( size_t index ); 167 168 private: 169 std::vector<std::unique_ptr<IProperty>> list; 170 std::unique_ptr<IProperty> getScalarProperty( Type type ); 171 }; 172 173 struct ElementDefinition; 174 175 class ElementBuffer 176 { 177 public: 178 ElementBuffer() = default; 179 ElementBuffer( const ElementDefinition &definition ); 180 181 public: size()182 size_t size() const { return properties.size(); }; 183 IProperty &operator[]( size_t index ); 184 185 private: 186 void appendScalarProperty( Type type ); 187 void appendListProperty( Type type ); 188 std::unique_ptr<IProperty> getScalarProperty( Type type ); 189 190 private: 191 std::vector<std::unique_ptr<IProperty>> properties; 192 }; 193 194 struct Property 195 { PropertyProperty196 Property( const std::string &name, Type type, bool isList ) 197 : name( name ), type( type ), isList( isList ) {}; 198 199 std::string name; 200 Type type; 201 bool isList; 202 size_t listCount; 203 }; 204 205 typedef std::size_t ElementSize; 206 207 struct Element 208 { ElementElement209 Element( const std::string &name, ElementSize size, const std::vector<Property> &properties ) 210 : name( name ), size( size ), properties( properties ) {}; 211 212 std::string name; 213 ElementSize size; 214 std::vector<Property> properties; 215 }; 216 217 typedef std::function< void( ElementBuffer & ) > ElementReadCallback; 218 219 class FileParser; 220 221 typedef std::vector<Element> ElementsDefinition; 222 typedef std::unordered_map<std::string, std::string> Metadata; 223 224 class File 225 { 226 public: 227 File( const std::string &filename ); 228 ~File(); 229 230 ElementsDefinition definitions() const; 231 Metadata metadata() const; 232 void setElementReadCallback( std::string elementName, ElementReadCallback &readCallback ); 233 void read(); 234 235 public: 236 enum class Format 237 { 238 ASCII, 239 BINARY_LITTLE_ENDIAN, 240 BINARY_BIG_ENDIAN 241 }; 242 243 private: 244 std::string m_filename; 245 std::unique_ptr<FileParser> m_parser; 246 }; 247 248 249 typedef std::function< void( ElementBuffer &, size_t index ) > ElementWriteCallback; 250 251 class FileOut 252 { 253 public: 254 FileOut( const std::string &filename, File::Format format ); 255 256 void setElementsDefinition( const ElementsDefinition &definitions ); 257 void setElementWriteCallback( const std::string &elementName, ElementWriteCallback &writeCallback ); 258 void write(); 259 Metadata metadata; 260 261 private: 262 void createFile(); 263 void writeHeader(); 264 void writeData(); 265 266 private: 267 std::string m_filename; 268 File::Format m_format; 269 ElementsDefinition m_definitions; 270 std::map<std::string, ElementWriteCallback> m_writeCallbacks; 271 }; 272 } 273