diff options
Diffstat (limited to 'libs/assimp/code/AssetLib/Ply')
-rw-r--r-- | libs/assimp/code/AssetLib/Ply/PlyExporter.cpp | 406 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/Ply/PlyExporter.h | 88 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/Ply/PlyLoader.cpp | 927 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/Ply/PlyLoader.h | 135 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/Ply/PlyParser.cpp | 963 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/Ply/PlyParser.h | 488 |
6 files changed, 0 insertions, 3007 deletions
diff --git a/libs/assimp/code/AssetLib/Ply/PlyExporter.cpp b/libs/assimp/code/AssetLib/Ply/PlyExporter.cpp deleted file mode 100644 index a98b83f..0000000 --- a/libs/assimp/code/AssetLib/Ply/PlyExporter.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - - - -#if !defined(ASSIMP_BUILD_NO_EXPORT) && !defined(ASSIMP_BUILD_NO_PLY_EXPORTER) - -#include "PlyExporter.h" -#include <memory> -#include <cmath> -#include <assimp/Exceptional.h> -#include <assimp/scene.h> -#include <assimp/version.h> -#include <assimp/IOSystem.hpp> -#include <assimp/Exporter.hpp> -#include <assimp/qnan.h> - - -//using namespace Assimp; -namespace Assimp { - -// make sure type_of returns consistent output across different platforms -// also consider using: typeid(VAR).name() -template <typename T> const char* type_of(T&) { return "unknown"; } -template<> const char* type_of(float&) { return "float"; } -template<> const char* type_of(double&) { return "double"; } - -// ------------------------------------------------------------------------------------------------ -// Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp -void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) -{ - // invoke the exporter - PlyExporter exporter(pFile, pScene); - - if (exporter.mOutput.fail()) { - throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile)); - } - - // we're still here - export successfully completed. Write the file. - std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); - if (outfile == nullptr) { - throw DeadlyExportError("could not open output .ply file: " + std::string(pFile)); - } - - outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1); -} - -void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) -{ - // invoke the exporter - PlyExporter exporter(pFile, pScene, true); - - // we're still here - export successfully completed. Write the file. - std::unique_ptr<IOStream> outfile(pIOSystem->Open(pFile, "wb")); - if (outfile == nullptr) { - throw DeadlyExportError("could not open output .ply file: " + std::string(pFile)); - } - - outfile->Write(exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()), 1); -} - -#define PLY_EXPORT_HAS_NORMALS 0x1 -#define PLY_EXPORT_HAS_TANGENTS_BITANGENTS 0x2 -#define PLY_EXPORT_HAS_TEXCOORDS 0x4 -#define PLY_EXPORT_HAS_COLORS (PLY_EXPORT_HAS_TEXCOORDS << AI_MAX_NUMBER_OF_TEXTURECOORDS) - -// ------------------------------------------------------------------------------------------------ -PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool binary) -: filename(_filename) -, endl("\n") -{ - // make sure that all formatting happens using the standard, C locale and not the user's current locale - const std::locale& l = std::locale("C"); - mOutput.imbue(l); - mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION); - - unsigned int faces = 0u, vertices = 0u, components = 0u; - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - const aiMesh& m = *pScene->mMeshes[i]; - faces += m.mNumFaces; - vertices += m.mNumVertices; - - if (m.HasNormals()) { - components |= PLY_EXPORT_HAS_NORMALS; - } - if (m.HasTangentsAndBitangents()) { - components |= PLY_EXPORT_HAS_TANGENTS_BITANGENTS; - } - for (unsigned int t = 0; m.HasTextureCoords(t); ++t) { - components |= PLY_EXPORT_HAS_TEXCOORDS << t; - } - for (unsigned int t = 0; m.HasVertexColors(t); ++t) { - components |= PLY_EXPORT_HAS_COLORS << t; - } - } - - mOutput << "ply" << endl; - if (binary) { -#if (defined AI_BUILD_BIG_ENDIAN) - mOutput << "format binary_big_endian 1.0" << endl; -#else - mOutput << "format binary_little_endian 1.0" << endl; -#endif - } - else { - mOutput << "format ascii 1.0" << endl; - } - mOutput << "comment Created by Open Asset Import Library - http://assimp.sf.net (v" - << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.' - << aiGetVersionRevision() << ")" << endl; - - // Look through materials for a diffuse texture, and add it if found - for ( unsigned int i = 0; i < pScene->mNumMaterials; ++i ) - { - const aiMaterial* const mat = pScene->mMaterials[i]; - aiString s; - if ( AI_SUCCESS == mat->Get( AI_MATKEY_TEXTURE_DIFFUSE( 0 ), s ) ) - { - mOutput << "comment TextureFile " << s.data << endl; - } - } - - // TODO: probably want to check here rather than just assume something - // definitely not good to always write float even if we might have double precision - - ai_real tmp = 0.0; - const char * typeName = type_of(tmp); - - mOutput << "element vertex " << vertices << endl; - mOutput << "property " << typeName << " x" << endl; - mOutput << "property " << typeName << " y" << endl; - mOutput << "property " << typeName << " z" << endl; - - if(components & PLY_EXPORT_HAS_NORMALS) { - mOutput << "property " << typeName << " nx" << endl; - mOutput << "property " << typeName << " ny" << endl; - mOutput << "property " << typeName << " nz" << endl; - } - - // write texcoords first, just in case an importer does not support tangents - // bitangents and just skips over the rest of the line upon encountering - // unknown fields (Ply leaves pretty much every vertex component open, - // but in reality most importers only know about vertex positions, normals - // and texture coordinates). - for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) { - if (!c) { - mOutput << "property " << typeName << " s" << endl; - mOutput << "property " << typeName << " t" << endl; - } - else { - mOutput << "property " << typeName << " s" << c << endl; - mOutput << "property " << typeName << " t" << c << endl; - } - } - - for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) { - if (!c) { - mOutput << "property " << "uchar" << " red" << endl; - mOutput << "property " << "uchar" << " green" << endl; - mOutput << "property " << "uchar" << " blue" << endl; - mOutput << "property " << "uchar" << " alpha" << endl; - } - else { - mOutput << "property " << "uchar" << " red" << c << endl; - mOutput << "property " << "uchar" << " green" << c << endl; - mOutput << "property " << "uchar" << " blue" << c << endl; - mOutput << "property " << "uchar" << " alpha" << c << endl; - } - } - - if(components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) { - mOutput << "property " << typeName << " tx" << endl; - mOutput << "property " << typeName << " ty" << endl; - mOutput << "property " << typeName << " tz" << endl; - mOutput << "property " << typeName << " bx" << endl; - mOutput << "property " << typeName << " by" << endl; - mOutput << "property " << typeName << " bz" << endl; - } - - mOutput << "element face " << faces << endl; - - // uchar seems to be the most common type for the number of indices per polygon and int seems to be most common for the vertex indices. - // For instance, MeshLab fails to load meshes in which both types are uint. Houdini seems to have problems as well. - // Obviously, using uchar will not work for meshes with polygons with more than 255 indices, but how realistic is this case? - mOutput << "property list uchar int vertex_index" << endl; - - mOutput << "end_header" << endl; - - for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - if (binary) { - WriteMeshVertsBinary(pScene->mMeshes[i], components); - } - else { - WriteMeshVerts(pScene->mMeshes[i], components); - } - } - for (unsigned int i = 0, ofs = 0; i < pScene->mNumMeshes; ++i) { - if (binary) { - WriteMeshIndicesBinary(pScene->mMeshes[i], ofs); - } - else { - WriteMeshIndices(pScene->mMeshes[i], ofs); - } - ofs += pScene->mMeshes[i]->mNumVertices; - } -} - -// ------------------------------------------------------------------------------------------------ -PlyExporter::~PlyExporter() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components) -{ - static const ai_real inf = std::numeric_limits<ai_real>::infinity(); - - // If a component (for instance normal vectors) is present in at least one mesh in the scene, - // then default values are written for meshes that do not contain this component. - for (unsigned int i = 0; i < m->mNumVertices; ++i) { - mOutput << - m->mVertices[i].x << " " << - m->mVertices[i].y << " " << - m->mVertices[i].z - ; - if(components & PLY_EXPORT_HAS_NORMALS) { - if (m->HasNormals() && is_not_qnan(m->mNormals[i].x) && std::fabs(m->mNormals[i].x) != inf) { - mOutput << - " " << m->mNormals[i].x << - " " << m->mNormals[i].y << - " " << m->mNormals[i].z; - } - else { - mOutput << " 0.0 0.0 0.0"; - } - } - - for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) { - if (m->HasTextureCoords(c)) { - mOutput << - " " << m->mTextureCoords[c][i].x << - " " << m->mTextureCoords[c][i].y; - } - else { - mOutput << " -1.0 -1.0"; - } - } - - for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) { - if (m->HasVertexColors(c)) { - mOutput << - " " << (int)(m->mColors[c][i].r * 255) << - " " << (int)(m->mColors[c][i].g * 255) << - " " << (int)(m->mColors[c][i].b * 255) << - " " << (int)(m->mColors[c][i].a * 255); - } - else { - mOutput << " 0 0 0"; - } - } - - if(components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) { - if (m->HasTangentsAndBitangents()) { - mOutput << - " " << m->mTangents[i].x << - " " << m->mTangents[i].y << - " " << m->mTangents[i].z << - " " << m->mBitangents[i].x << - " " << m->mBitangents[i].y << - " " << m->mBitangents[i].z - ; - } - else { - mOutput << " 0.0 0.0 0.0 0.0 0.0 0.0"; - } - } - - mOutput << endl; - } -} - -// ------------------------------------------------------------------------------------------------ -void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components) -{ - // If a component (for instance normal vectors) is present in at least one mesh in the scene, - // then default values are written for meshes that do not contain this component. - aiVector3D defaultNormal(0, 0, 0); - aiVector2D defaultUV(-1, -1); - aiColor4D defaultColor(-1, -1, -1, -1); - for (unsigned int i = 0; i < m->mNumVertices; ++i) { - mOutput.write(reinterpret_cast<const char*>(&m->mVertices[i].x), 12); - if (components & PLY_EXPORT_HAS_NORMALS) { - if (m->HasNormals()) { - mOutput.write(reinterpret_cast<const char*>(&m->mNormals[i].x), 12); - } - else { - mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12); - } - } - - for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) { - if (m->HasTextureCoords(c)) { - mOutput.write(reinterpret_cast<const char*>(&m->mTextureCoords[c][i].x), 8); - } - else { - mOutput.write(reinterpret_cast<const char*>(&defaultUV.x), 8); - } - } - - for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) { - if (m->HasVertexColors(c)) { - mOutput.write(reinterpret_cast<const char*>(&m->mColors[c][i].r), 16); - } - else { - mOutput.write(reinterpret_cast<const char*>(&defaultColor.r), 16); - } - } - - if (components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) { - if (m->HasTangentsAndBitangents()) { - mOutput.write(reinterpret_cast<const char*>(&m->mTangents[i].x), 12); - mOutput.write(reinterpret_cast<const char*>(&m->mBitangents[i].x), 12); - } - else { - mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12); - mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12); - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -void PlyExporter::WriteMeshIndices(const aiMesh* m, unsigned int offset) -{ - for (unsigned int i = 0; i < m->mNumFaces; ++i) { - const aiFace& f = m->mFaces[i]; - mOutput << f.mNumIndices; - for(unsigned int c = 0; c < f.mNumIndices; ++c) { - mOutput << " " << (f.mIndices[c] + offset); - } - mOutput << endl; - } -} - -// Generic method in case we want to use different data types for the indices or make this configurable. -template<typename NumIndicesType, typename IndexType> -void WriteMeshIndicesBinary_Generic(const aiMesh* m, unsigned int offset, std::ostringstream& output) -{ - for (unsigned int i = 0; i < m->mNumFaces; ++i) { - const aiFace& f = m->mFaces[i]; - NumIndicesType numIndices = static_cast<NumIndicesType>(f.mNumIndices); - output.write(reinterpret_cast<const char*>(&numIndices), sizeof(NumIndicesType)); - for (unsigned int c = 0; c < f.mNumIndices; ++c) { - IndexType index = f.mIndices[c] + offset; - output.write(reinterpret_cast<const char*>(&index), sizeof(IndexType)); - } - } -} - -void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset) -{ - WriteMeshIndicesBinary_Generic<unsigned char, int>(m, offset, mOutput); -} - -} // end of namespace Assimp - -#endif // !defined(ASSIMP_BUILD_NO_EXPORT) && !defined(ASSIMP_BUILD_NO_PLY_EXPORTER) diff --git a/libs/assimp/code/AssetLib/Ply/PlyExporter.h b/libs/assimp/code/AssetLib/Ply/PlyExporter.h deleted file mode 100644 index ff3a54c..0000000 --- a/libs/assimp/code/AssetLib/Ply/PlyExporter.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file PlyExporter.h - * Declares the exporter class to write a scene to a Polygon Library (ply) - */ -#ifndef AI_PLYEXPORTER_H_INC -#define AI_PLYEXPORTER_H_INC - -#include <sstream> - -struct aiScene; -struct aiNode; -struct aiMesh; - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -/** Helper class to export a given scene to a Stanford Ply file. */ -// ------------------------------------------------------------------------------------------------ -class PlyExporter { -public: - /// The class constructor for a specific scene to export - PlyExporter(const char* filename, const aiScene* pScene, bool binary = false); - /// The class destructor, empty. - ~PlyExporter(); - -public: - /// public string-streams to write all output into: - std::ostringstream mOutput; - -private: - void WriteMeshVerts(const aiMesh* m, unsigned int components); - void WriteMeshIndices(const aiMesh* m, unsigned int ofs); - void WriteMeshVertsBinary(const aiMesh* m, unsigned int components); - void WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset); - -private: - const std::string filename; // tHE FILENAME - const std::string endl; // obviously, this endl() doesn't flush() the stream - -private: - PlyExporter( const PlyExporter & ); - PlyExporter &operator = ( const PlyExporter & ); -}; - -} // Namespace Assimp - -#endif // AI_PLYEXPORTER_H_INC diff --git a/libs/assimp/code/AssetLib/Ply/PlyLoader.cpp b/libs/assimp/code/AssetLib/Ply/PlyLoader.cpp deleted file mode 100644 index 6cf1a1c..0000000 --- a/libs/assimp/code/AssetLib/Ply/PlyLoader.cpp +++ /dev/null @@ -1,927 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2022, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file PlyLoader.cpp - * @brief Implementation of the PLY importer class - */ - -#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER - -// internal headers -#include "PlyLoader.h" -#include <assimp/IOStreamBuffer.h> -#include <assimp/importerdesc.h> -#include <assimp/scene.h> -#include <assimp/IOSystem.hpp> -#include <memory> - -using namespace ::Assimp; - -static const aiImporterDesc desc = { - "Stanford Polygon Library (PLY) Importer", - "", - "", - "", - aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportTextFlavour, - 0, - 0, - 0, - 0, - "ply" -}; - -// ------------------------------------------------------------------------------------------------ -// Internal stuff -namespace { -// ------------------------------------------------------------------------------------------------ -// Checks that property index is within range -template <class T> -inline const T &GetProperty(const std::vector<T> &props, int idx) { - if (static_cast<size_t>(idx) >= props.size()) { - throw DeadlyImportError("Invalid .ply file: Property index is out of range."); - } - - return props[idx]; -} -} // namespace - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -PLYImporter::PLYImporter() : - mBuffer(nullptr), - pcDOM(nullptr), - mGeneratedMesh(nullptr) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -PLYImporter::~PLYImporter() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. -bool PLYImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { - static const char *tokens[] = { "ply" }; - return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); -} - -// ------------------------------------------------------------------------------------------------ -const aiImporterDesc *PLYImporter::GetInfo() const { - return &desc; -} - -// ------------------------------------------------------------------------------------------------ -static bool isBigEndian(const char *szMe) { - ai_assert(nullptr != szMe); - - // binary_little_endian - // binary_big_endian - bool isBigEndian(false); -#if (defined AI_BUILD_BIG_ENDIAN) - if ('l' == *szMe || 'L' == *szMe) { - isBigEndian = true; - } -#else - if ('b' == *szMe || 'B' == *szMe) { - isBigEndian = true; - } -#endif // ! AI_BUILD_BIG_ENDIAN - - return isBigEndian; -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. -void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { - const std::string mode = "rb"; - std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode)); - if (!fileStream.get()) { - throw DeadlyImportError("Failed to open file ", pFile, "."); - } - - // Get the file-size - const size_t fileSize(fileStream->FileSize()); - if (0 == fileSize) { - throw DeadlyImportError("File ", pFile, " is empty."); - } - - IOStreamBuffer<char> streamedBuffer(1024 * 1024); - streamedBuffer.open(fileStream.get()); - - // the beginning of the file must be PLY - magic, magic - std::vector<char> headerCheck; - streamedBuffer.getNextLine(headerCheck); - - if ((headerCheck.size() < 3) || - (headerCheck[0] != 'P' && headerCheck[0] != 'p') || - (headerCheck[1] != 'L' && headerCheck[1] != 'l') || - (headerCheck[2] != 'Y' && headerCheck[2] != 'y')) { - streamedBuffer.close(); - throw DeadlyImportError("Invalid .ply file: Incorrect magic number (expected 'ply' or 'PLY')."); - } - - std::vector<char> mBuffer2; - streamedBuffer.getNextLine(mBuffer2); - mBuffer = (unsigned char *)&mBuffer2[0]; - - char *szMe = (char *)&this->mBuffer[0]; - SkipSpacesAndLineEnd(szMe, (const char **)&szMe); - - // determine the format of the file data and construct the aiMesh - PLY::DOM sPlyDom; - this->pcDOM = &sPlyDom; - - if (TokenMatch(szMe, "format", 6)) { - if (TokenMatch(szMe, "ascii", 5)) { - SkipLine(szMe, (const char **)&szMe); - if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) { - if (mGeneratedMesh != nullptr) { - delete (mGeneratedMesh); - mGeneratedMesh = nullptr; - } - - streamedBuffer.close(); - throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#1)"); - } - } else if (!::strncmp(szMe, "binary_", 7)) { - szMe += 7; - const bool bIsBE(isBigEndian(szMe)); - - // skip the line, parse the rest of the header and build the DOM - if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE)) { - if (mGeneratedMesh != nullptr) { - delete (mGeneratedMesh); - mGeneratedMesh = nullptr; - } - - streamedBuffer.close(); - throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)"); - } - } else { - if (mGeneratedMesh != nullptr) { - delete (mGeneratedMesh); - mGeneratedMesh = nullptr; - } - - streamedBuffer.close(); - throw DeadlyImportError("Invalid .ply file: Unknown file format"); - } - } else { - AI_DEBUG_INVALIDATE_PTR(this->mBuffer); - if (mGeneratedMesh != nullptr) { - delete (mGeneratedMesh); - mGeneratedMesh = nullptr; - } - - streamedBuffer.close(); - throw DeadlyImportError("Invalid .ply file: Missing format specification"); - } - - //free the file buffer - streamedBuffer.close(); - - if (mGeneratedMesh == nullptr) { - throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data "); - } - - // if no face list is existing we assume that the vertex - // list is containing a list of points - bool pointsOnly = mGeneratedMesh->mFaces == nullptr ? true : false; - if (pointsOnly) { - mGeneratedMesh->mPrimitiveTypes = aiPrimitiveType::aiPrimitiveType_POINT; - } - - // now load a list of all materials - std::vector<aiMaterial *> avMaterials; - std::string defaultTexture; - LoadMaterial(&avMaterials, defaultTexture, pointsOnly); - - // now generate the output scene object. Fill the material list - pScene->mNumMaterials = (unsigned int)avMaterials.size(); - pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; - for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) { - pScene->mMaterials[i] = avMaterials[i]; - } - - // fill the mesh list - pScene->mNumMeshes = 1; - pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; - pScene->mMeshes[0] = mGeneratedMesh; - mGeneratedMesh = nullptr; - - // generate a simple node structure - pScene->mRootNode = new aiNode(); - pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; - pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; - - for (unsigned int i = 0; i < pScene->mRootNode->mNumMeshes; ++i) { - pScene->mRootNode->mMeshes[i] = i; - } -} - -void PLYImporter::LoadVertex(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos) { - ai_assert(nullptr != pcElement); - ai_assert(nullptr != instElement); - - ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char }; - - ai_uint aiNormal[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - PLY::EDataType aiNormalTypes[3] = { EDT_Char, EDT_Char, EDT_Char }; - - unsigned int aiColors[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - PLY::EDataType aiColorsTypes[4] = { EDT_Char, EDT_Char, EDT_Char, EDT_Char }; - - unsigned int aiTexcoord[2] = { 0xFFFFFFFF, 0xFFFFFFFF }; - PLY::EDataType aiTexcoordTypes[2] = { EDT_Char, EDT_Char }; - - // now check whether which normal components are available - unsigned int _a(0), cnt(0); - for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin(); - a != pcElement->alProperties.end(); ++a, ++_a) { - if ((*a).bIsList) { - continue; - } - - // Positions - if (PLY::EST_XCoord == (*a).Semantic) { - ++cnt; - aiPositions[0] = _a; - aiTypes[0] = (*a).eType; - } else if (PLY::EST_YCoord == (*a).Semantic) { - ++cnt; - aiPositions[1] = _a; - aiTypes[1] = (*a).eType; - } else if (PLY::EST_ZCoord == (*a).Semantic) { - ++cnt; - aiPositions[2] = _a; - aiTypes[2] = (*a).eType; - } else if (PLY::EST_XNormal == (*a).Semantic) { - // Normals - ++cnt; - aiNormal[0] = _a; - aiNormalTypes[0] = (*a).eType; - } else if (PLY::EST_YNormal == (*a).Semantic) { - ++cnt; - aiNormal[1] = _a; - aiNormalTypes[1] = (*a).eType; - } else if (PLY::EST_ZNormal == (*a).Semantic) { - ++cnt; - aiNormal[2] = _a; - aiNormalTypes[2] = (*a).eType; - } else if (PLY::EST_Red == (*a).Semantic) { - // Colors - ++cnt; - aiColors[0] = _a; - aiColorsTypes[0] = (*a).eType; - } else if (PLY::EST_Green == (*a).Semantic) { - ++cnt; - aiColors[1] = _a; - aiColorsTypes[1] = (*a).eType; - } else if (PLY::EST_Blue == (*a).Semantic) { - ++cnt; - aiColors[2] = _a; - aiColorsTypes[2] = (*a).eType; - } else if (PLY::EST_Alpha == (*a).Semantic) { - ++cnt; - aiColors[3] = _a; - aiColorsTypes[3] = (*a).eType; - } else if (PLY::EST_UTextureCoord == (*a).Semantic) { - // Texture coordinates - ++cnt; - aiTexcoord[0] = _a; - aiTexcoordTypes[0] = (*a).eType; - } else if (PLY::EST_VTextureCoord == (*a).Semantic) { - ++cnt; - aiTexcoord[1] = _a; - aiTexcoordTypes[1] = (*a).eType; - } - } - - // check whether we have a valid source for the vertex data - if (0 != cnt) { - // Position - aiVector3D vOut; - if (0xFFFFFFFF != aiPositions[0]) { - vOut.x = PLY::PropertyInstance::ConvertTo<ai_real>( - GetProperty(instElement->alProperties, aiPositions[0]).avList.front(), aiTypes[0]); - } - - if (0xFFFFFFFF != aiPositions[1]) { - vOut.y = PLY::PropertyInstance::ConvertTo<ai_real>( - GetProperty(instElement->alProperties, aiPositions[1]).avList.front(), aiTypes[1]); - } - - if (0xFFFFFFFF != aiPositions[2]) { - vOut.z = PLY::PropertyInstance::ConvertTo<ai_real>( - GetProperty(instElement->alProperties, aiPositions[2]).avList.front(), aiTypes[2]); - } - - // Normals - aiVector3D nOut; - bool haveNormal = false; - if (0xFFFFFFFF != aiNormal[0]) { - nOut.x = PLY::PropertyInstance::ConvertTo<ai_real>( - GetProperty(instElement->alProperties, aiNormal[0]).avList.front(), aiNormalTypes[0]); - haveNormal = true; - } - - if (0xFFFFFFFF != aiNormal[1]) { - nOut.y = PLY::PropertyInstance::ConvertTo<ai_real>( - GetProperty(instElement->alProperties, aiNormal[1]).avList.front(), aiNormalTypes[1]); - haveNormal = true; - } - - if (0xFFFFFFFF != aiNormal[2]) { - nOut.z = PLY::PropertyInstance::ConvertTo<ai_real>( - GetProperty(instElement->alProperties, aiNormal[2]).avList.front(), aiNormalTypes[2]); - haveNormal = true; - } - - //Colors - aiColor4D cOut; - bool haveColor = false; - if (0xFFFFFFFF != aiColors[0]) { - cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties, - aiColors[0]) - .avList.front(), - aiColorsTypes[0]); - haveColor = true; - } - - if (0xFFFFFFFF != aiColors[1]) { - cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties, - aiColors[1]) - .avList.front(), - aiColorsTypes[1]); - haveColor = true; - } - - if (0xFFFFFFFF != aiColors[2]) { - cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties, - aiColors[2]) - .avList.front(), - aiColorsTypes[2]); - haveColor = true; - } - - // assume 1.0 for the alpha channel if it is not set - if (0xFFFFFFFF == aiColors[3]) { - cOut.a = 1.0; - } else { - cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties, - aiColors[3]) - .avList.front(), - aiColorsTypes[3]); - - haveColor = true; - } - - //Texture coordinates - aiVector3D tOut; - tOut.z = 0; - bool haveTextureCoords = false; - if (0xFFFFFFFF != aiTexcoord[0]) { - tOut.x = PLY::PropertyInstance::ConvertTo<ai_real>( - GetProperty(instElement->alProperties, aiTexcoord[0]).avList.front(), aiTexcoordTypes[0]); - haveTextureCoords = true; - } - - if (0xFFFFFFFF != aiTexcoord[1]) { - tOut.y = PLY::PropertyInstance::ConvertTo<ai_real>( - GetProperty(instElement->alProperties, aiTexcoord[1]).avList.front(), aiTexcoordTypes[1]); - haveTextureCoords = true; - } - - //create aiMesh if needed - if (nullptr == mGeneratedMesh) { - mGeneratedMesh = new aiMesh(); - mGeneratedMesh->mMaterialIndex = 0; - } - - if (nullptr == mGeneratedMesh->mVertices) { - mGeneratedMesh->mNumVertices = pcElement->NumOccur; - mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices]; - } - - mGeneratedMesh->mVertices[pos] = vOut; - - if (haveNormal) { - if (nullptr == mGeneratedMesh->mNormals) - mGeneratedMesh->mNormals = new aiVector3D[mGeneratedMesh->mNumVertices]; - mGeneratedMesh->mNormals[pos] = nOut; - } - - if (haveColor) { - if (nullptr == mGeneratedMesh->mColors[0]) - mGeneratedMesh->mColors[0] = new aiColor4D[mGeneratedMesh->mNumVertices]; - mGeneratedMesh->mColors[0][pos] = cOut; - } - - if (haveTextureCoords) { - if (nullptr == mGeneratedMesh->mTextureCoords[0]) { - mGeneratedMesh->mNumUVComponents[0] = 2; - mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices]; - } - mGeneratedMesh->mTextureCoords[0][pos] = tOut; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Convert a color component to [0...1] -ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) { - switch (eType) { - case EDT_Float: - return val.fFloat; - case EDT_Double: - return (ai_real)val.fDouble; - case EDT_UChar: - return (ai_real)val.iUInt / (ai_real)0xFF; - case EDT_Char: - return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF; - case EDT_UShort: - return (ai_real)val.iUInt / (ai_real)0xFFFF; - case EDT_Short: - return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF; - case EDT_UInt: - return (ai_real)val.iUInt / (ai_real)0xFFFF; - case EDT_Int: - return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f; - default: - break; - } - - return 0.0f; -} - -// ------------------------------------------------------------------------------------------------ -// Try to extract proper faces from the PLY DOM -void PLYImporter::LoadFace(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, - unsigned int pos) { - ai_assert(nullptr != pcElement); - ai_assert(nullptr != instElement); - - if (mGeneratedMesh == nullptr) { - throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces"); - } - - bool bOne = false; - - // index of the vertex index list - unsigned int iProperty = 0xFFFFFFFF; - PLY::EDataType eType = EDT_Char; - bool bIsTriStrip = false; - - // index of the material index property - //unsigned int iMaterialIndex = 0xFFFFFFFF; - //PLY::EDataType eType2 = EDT_Char; - - // texture coordinates - unsigned int iTextureCoord = 0xFFFFFFFF; - PLY::EDataType eType3 = EDT_Char; - - // face = unique number of vertex indices - if (PLY::EEST_Face == pcElement->eSemantic) { - unsigned int _a = 0; - for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin(); - a != pcElement->alProperties.end(); ++a, ++_a) { - if (PLY::EST_VertexIndex == (*a).Semantic) { - // must be a dynamic list! - if (!(*a).bIsList) { - continue; - } - - iProperty = _a; - bOne = true; - eType = (*a).eType; - } else if (PLY::EST_TextureCoordinates == (*a).Semantic) { - // must be a dynamic list! - if (!(*a).bIsList) { - continue; - } - iTextureCoord = _a; - bOne = true; - eType3 = (*a).eType; - } - } - } - // triangle strip - // TODO: triangle strip and material index support??? - else if (PLY::EEST_TriStrip == pcElement->eSemantic) { - unsigned int _a = 0; - for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin(); - a != pcElement->alProperties.end(); ++a, ++_a) { - // must be a dynamic list! - if (!(*a).bIsList) { - continue; - } - iProperty = _a; - bOne = true; - bIsTriStrip = true; - eType = (*a).eType; - break; - } - } - - // check whether we have at least one per-face information set - if (bOne) { - if (mGeneratedMesh->mFaces == nullptr) { - mGeneratedMesh->mNumFaces = pcElement->NumOccur; - mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces]; - } - - if (!bIsTriStrip) { - // parse the list of vertex indices - if (0xFFFFFFFF != iProperty) { - const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size(); - mGeneratedMesh->mFaces[pos].mNumIndices = iNum; - mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum]; - - std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p = - GetProperty(instElement->alProperties, iProperty).avList.begin(); - - for (unsigned int a = 0; a < iNum; ++a, ++p) { - mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType); - } - } - - // parse the material index - // cannot be handled without processing the whole file first - /*if (0xFFFFFFFF != iMaterialIndex) - { - mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>( - GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2); - }*/ - - if (0xFFFFFFFF != iTextureCoord) { - const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size(); - - //should be 6 coords - std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p = - GetProperty(instElement->alProperties, iTextureCoord).avList.begin(); - - if ((iNum / 3) == 2) // X Y coord - { - for (unsigned int a = 0; a < iNum; ++a, ++p) { - unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2]; - if (vindex < mGeneratedMesh->mNumVertices) { - if (mGeneratedMesh->mTextureCoords[0] == nullptr) { - mGeneratedMesh->mNumUVComponents[0] = 2; - mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices]; - } - - if (a % 2 == 0) { - mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3); - } else { - mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3); - } - - mGeneratedMesh->mTextureCoords[0][vindex].z = 0; - } - } - } - } - } else { // triangle strips - // normally we have only one triangle strip instance where - // a value of -1 indicates a restart of the strip - bool flip = false; - const std::vector<PLY::PropertyInstance::ValueUnion> &quak = GetProperty(instElement->alProperties, iProperty).avList; - //pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption - - int aiTable[2] = { -1, -1 }; - for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) { - const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType); - - if (-1 == p) { - // restart the strip ... - aiTable[0] = aiTable[1] = -1; - flip = false; - continue; - } - if (-1 == aiTable[0]) { - aiTable[0] = p; - continue; - } - if (-1 == aiTable[1]) { - aiTable[1] = p; - continue; - } - - if (mGeneratedMesh->mFaces == nullptr) { - mGeneratedMesh->mNumFaces = pcElement->NumOccur; - mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces]; - } - - mGeneratedMesh->mFaces[pos].mNumIndices = 3; - mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3]; - mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0]; - mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1]; - mGeneratedMesh->mFaces[pos].mIndices[2] = p; - - // every second pass swap the indices. - flip = !flip; - if (flip) { - std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]); - } - - aiTable[0] = aiTable[1]; - aiTable[1] = p; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Get a RGBA color in [0...1] range -void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avList, - unsigned int aiPositions[4], - PLY::EDataType aiTypes[4], - aiColor4D *clrOut) { - ai_assert(nullptr != clrOut); - - if (0xFFFFFFFF == aiPositions[0]) - clrOut->r = 0.0f; - else { - clrOut->r = NormalizeColorValue(GetProperty(avList, - aiPositions[0]) - .avList.front(), - aiTypes[0]); - } - - if (0xFFFFFFFF == aiPositions[1]) - clrOut->g = 0.0f; - else { - clrOut->g = NormalizeColorValue(GetProperty(avList, - aiPositions[1]) - .avList.front(), - aiTypes[1]); - } - - if (0xFFFFFFFF == aiPositions[2]) - clrOut->b = 0.0f; - else { - clrOut->b = NormalizeColorValue(GetProperty(avList, - aiPositions[2]) - .avList.front(), - aiTypes[2]); - } - - // assume 1.0 for the alpha channel ifit is not set - if (0xFFFFFFFF == aiPositions[3]) - clrOut->a = 1.0f; - else { - clrOut->a = NormalizeColorValue(GetProperty(avList, - aiPositions[3]) - .avList.front(), - aiTypes[3]); - } -} - -// ------------------------------------------------------------------------------------------------ -// Extract a material from the PLY DOM -void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly) { - ai_assert(nullptr != pvOut); - - // diffuse[4], specular[4], ambient[4] - // rgba order - unsigned int aaiPositions[3][4] = { - - { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }, - { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }, - }; - - PLY::EDataType aaiTypes[3][4] = { - { EDT_Char, EDT_Char, EDT_Char, EDT_Char }, - { EDT_Char, EDT_Char, EDT_Char, EDT_Char }, - { EDT_Char, EDT_Char, EDT_Char, EDT_Char } - }; - PLY::ElementInstanceList *pcList = nullptr; - - unsigned int iPhong = 0xFFFFFFFF; - PLY::EDataType ePhong = EDT_Char; - - unsigned int iOpacity = 0xFFFFFFFF; - PLY::EDataType eOpacity = EDT_Char; - - // search in the DOM for a vertex entry - unsigned int _i = 0; - for (std::vector<PLY::Element>::const_iterator i = this->pcDOM->alElements.begin(); - i != this->pcDOM->alElements.end(); ++i, ++_i) { - if (PLY::EEST_Material == (*i).eSemantic) { - pcList = &this->pcDOM->alElementData[_i]; - - // now check whether which coordinate sets are available - unsigned int _a = 0; - for (std::vector<PLY::Property>::const_iterator - a = (*i).alProperties.begin(); - a != (*i).alProperties.end(); ++a, ++_a) { - if ((*a).bIsList) continue; - - // pohng specularity ----------------------------------- - if (PLY::EST_PhongPower == (*a).Semantic) { - iPhong = _a; - ePhong = (*a).eType; - } - - // general opacity ----------------------------------- - if (PLY::EST_Opacity == (*a).Semantic) { - iOpacity = _a; - eOpacity = (*a).eType; - } - - // diffuse color channels ----------------------------------- - if (PLY::EST_DiffuseRed == (*a).Semantic) { - aaiPositions[0][0] = _a; - aaiTypes[0][0] = (*a).eType; - } else if (PLY::EST_DiffuseGreen == (*a).Semantic) { - aaiPositions[0][1] = _a; - aaiTypes[0][1] = (*a).eType; - } else if (PLY::EST_DiffuseBlue == (*a).Semantic) { - aaiPositions[0][2] = _a; - aaiTypes[0][2] = (*a).eType; - } else if (PLY::EST_DiffuseAlpha == (*a).Semantic) { - aaiPositions[0][3] = _a; - aaiTypes[0][3] = (*a).eType; - } - // specular color channels ----------------------------------- - else if (PLY::EST_SpecularRed == (*a).Semantic) { - aaiPositions[1][0] = _a; - aaiTypes[1][0] = (*a).eType; - } else if (PLY::EST_SpecularGreen == (*a).Semantic) { - aaiPositions[1][1] = _a; - aaiTypes[1][1] = (*a).eType; - } else if (PLY::EST_SpecularBlue == (*a).Semantic) { - aaiPositions[1][2] = _a; - aaiTypes[1][2] = (*a).eType; - } else if (PLY::EST_SpecularAlpha == (*a).Semantic) { - aaiPositions[1][3] = _a; - aaiTypes[1][3] = (*a).eType; - } - // ambient color channels ----------------------------------- - else if (PLY::EST_AmbientRed == (*a).Semantic) { - aaiPositions[2][0] = _a; - aaiTypes[2][0] = (*a).eType; - } else if (PLY::EST_AmbientGreen == (*a).Semantic) { - aaiPositions[2][1] = _a; - aaiTypes[2][1] = (*a).eType; - } else if (PLY::EST_AmbientBlue == (*a).Semantic) { - aaiPositions[2][2] = _a; - aaiTypes[2][2] = (*a).eType; - } else if (PLY::EST_AmbientAlpha == (*a).Semantic) { - aaiPositions[2][3] = _a; - aaiTypes[2][3] = (*a).eType; - } - } - break; - } else if (PLY::EEST_TextureFile == (*i).eSemantic) { - defaultTexture = (*i).szName; - } - } - // check whether we have a valid source for the material data - if (nullptr != pcList) { - for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin(); i != pcList->alInstances.end(); ++i) { - aiColor4D clrOut; - aiMaterial *pcHelper = new aiMaterial(); - - // build the diffuse material color - GetMaterialColor((*i).alProperties, aaiPositions[0], aaiTypes[0], &clrOut); - pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_DIFFUSE); - - // build the specular material color - GetMaterialColor((*i).alProperties, aaiPositions[1], aaiTypes[1], &clrOut); - pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_SPECULAR); - - // build the ambient material color - GetMaterialColor((*i).alProperties, aaiPositions[2], aaiTypes[2], &clrOut); - pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_AMBIENT); - - // handle phong power and shading mode - int iMode = (int)aiShadingMode_Gouraud; - if (0xFFFFFFFF != iPhong) { - ai_real fSpec = PLY::PropertyInstance::ConvertTo<ai_real>(GetProperty((*i).alProperties, iPhong).avList.front(), ePhong); - - // if shininess is 0 (and the pow() calculation would therefore always - // become 1, not depending on the angle), use gouraud lighting - if (fSpec) { - // scale this with 15 ... hopefully this is correct - fSpec *= 15; - pcHelper->AddProperty<ai_real>(&fSpec, 1, AI_MATKEY_SHININESS); - - iMode = (int)aiShadingMode_Phong; - } - } - pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL); - - // handle opacity - if (0xFFFFFFFF != iOpacity) { - ai_real fOpacity = PLY::PropertyInstance::ConvertTo<ai_real>(GetProperty((*i).alProperties, iPhong).avList.front(), eOpacity); - pcHelper->AddProperty<ai_real>(&fOpacity, 1, AI_MATKEY_OPACITY); - } - - // The face order is absolutely undefined for PLY, so we have to - // use two-sided rendering to be sure it's ok. - const int two_sided = 1; - pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); - - //default texture - if (!defaultTexture.empty()) { - const aiString name(defaultTexture.c_str()); - pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0); - } - - if (!pointsOnly) { - pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); - } - - //set to wireframe, so when using this material info we can switch to points rendering - if (pointsOnly) { - const int wireframe = 1; - pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME); - } - - // add the newly created material instance to the list - pvOut->push_back(pcHelper); - } - } else { - // generate a default material - aiMaterial *pcHelper = new aiMaterial(); - - // fill in a default material - int iMode = (int)aiShadingMode_Gouraud; - pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL); - - //generate white material most 3D engine just multiply ambient / diffuse color with actual ambient / light color - aiColor3D clr; - clr.b = clr.g = clr.r = 1.0f; - pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE); - pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR); - - clr.b = clr.g = clr.r = 1.0f; - pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT); - - // The face order is absolutely undefined for PLY, so we have to - // use two-sided rendering to be sure it's ok. - if (!pointsOnly) { - const int two_sided = 1; - pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); - } - - //default texture - if (!defaultTexture.empty()) { - const aiString name(defaultTexture.c_str()); - pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0); - } - - //set to wireframe, so when using this material info we can switch to points rendering - if (pointsOnly) { - const int wireframe = 1; - pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME); - } - - pvOut->push_back(pcHelper); - } -} - -#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER diff --git a/libs/assimp/code/AssetLib/Ply/PlyLoader.h b/libs/assimp/code/AssetLib/Ply/PlyLoader.h deleted file mode 100644 index e29da1d..0000000 --- a/libs/assimp/code/AssetLib/Ply/PlyLoader.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file PLYLoader.h - * @brief Declaration of the .ply importer class. - */ -#pragma once -#ifndef AI_PLYLOADER_H_INCLUDED -#define AI_PLYLOADER_H_INCLUDED - -#include "PlyParser.h" -#include <assimp/BaseImporter.h> -#include <assimp/types.h> -#include <vector> - -struct aiNode; -struct aiMaterial; -struct aiMesh; - -namespace Assimp { - -using namespace PLY; - -// --------------------------------------------------------------------------- -/** Importer class to load the stanford PLY file format -*/ -class PLYImporter : public BaseImporter { -public: - PLYImporter(); - ~PLYImporter() override; - - // ------------------------------------------------------------------- - /** Returns whether the class can handle the format of the given file. - * See BaseImporter::CanRead() for details. - */ - bool CanRead(const std::string &pFile, IOSystem *pIOHandler, - bool checkSig) const override; - - // ------------------------------------------------------------------- - /** Extract a vertex from the DOM - */ - void LoadVertex(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos); - - // ------------------------------------------------------------------- - /** Extract a face from the DOM - */ - void LoadFace(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos); - -protected: - // ------------------------------------------------------------------- - /** Return importer meta information. - * See #BaseImporter::GetInfo for the details - */ - const aiImporterDesc *GetInfo() const override; - - // ------------------------------------------------------------------- - /** Imports the given file into the given scene structure. - * See BaseImporter::InternReadFile() for details - */ - void InternReadFile(const std::string &pFile, aiScene *pScene, - IOSystem *pIOHandler) override; - - // ------------------------------------------------------------------- - /** Extract a material list from the DOM - */ - void LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly); - - // ------------------------------------------------------------------- - /** Static helper to parse a color from four single channels in - */ - static void GetMaterialColor( - const std::vector<PLY::PropertyInstance> &avList, - unsigned int aiPositions[4], - PLY::EDataType aiTypes[4], - aiColor4D *clrOut); - - // ------------------------------------------------------------------- - /** Static helper to parse a color channel value. The input value - * is normalized to 0-1. - */ - static ai_real NormalizeColorValue( - PLY::PropertyInstance::ValueUnion val, - PLY::EDataType eType); - - /** Buffer to hold the loaded file */ - unsigned char *mBuffer; - - /** Document object model representation extracted from the file */ - PLY::DOM *pcDOM; - - /** Mesh generated by loader */ - aiMesh *mGeneratedMesh; -}; - -} // end of namespace Assimp - -#endif // AI_3DSIMPORTER_H_INC diff --git a/libs/assimp/code/AssetLib/Ply/PlyParser.cpp b/libs/assimp/code/AssetLib/Ply/PlyParser.cpp deleted file mode 100644 index df93d5a..0000000 --- a/libs/assimp/code/AssetLib/Ply/PlyParser.cpp +++ /dev/null @@ -1,963 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2022, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Implementation of the PLY parser class */ - -#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER - -#include "PlyLoader.h" -#include <assimp/ByteSwapper.h> -#include <assimp/fast_atof.h> -#include <assimp/DefaultLogger.hpp> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -PLY::EDataType PLY::Property::ParseDataType(std::vector<char> &buffer) { - ai_assert(!buffer.empty()); - - PLY::EDataType eOut = PLY::EDT_INVALID; - - if (PLY::DOM::TokenMatch(buffer, "char", 4) || - PLY::DOM::TokenMatch(buffer, "int8", 4)) { - eOut = PLY::EDT_Char; - } else if (PLY::DOM::TokenMatch(buffer, "uchar", 5) || - PLY::DOM::TokenMatch(buffer, "uint8", 5)) { - eOut = PLY::EDT_UChar; - } else if (PLY::DOM::TokenMatch(buffer, "short", 5) || - PLY::DOM::TokenMatch(buffer, "int16", 5)) { - eOut = PLY::EDT_Short; - } else if (PLY::DOM::TokenMatch(buffer, "ushort", 6) || - PLY::DOM::TokenMatch(buffer, "uint16", 6)) { - eOut = PLY::EDT_UShort; - } else if (PLY::DOM::TokenMatch(buffer, "int32", 5) || PLY::DOM::TokenMatch(buffer, "int", 3)) { - eOut = PLY::EDT_Int; - } else if (PLY::DOM::TokenMatch(buffer, "uint32", 6) || PLY::DOM::TokenMatch(buffer, "uint", 4)) { - eOut = PLY::EDT_UInt; - } else if (PLY::DOM::TokenMatch(buffer, "float", 5) || PLY::DOM::TokenMatch(buffer, "float32", 7)) { - eOut = PLY::EDT_Float; - } else if (PLY::DOM::TokenMatch(buffer, "double64", 8) || PLY::DOM::TokenMatch(buffer, "double", 6) || - PLY::DOM::TokenMatch(buffer, "float64", 7)) { - eOut = PLY::EDT_Double; - } - if (PLY::EDT_INVALID == eOut) { - ASSIMP_LOG_INFO("Found unknown data type in PLY file. This is OK"); - } - - return eOut; -} - -// ------------------------------------------------------------------------------------------------ -PLY::ESemantic PLY::Property::ParseSemantic(std::vector<char> &buffer) { - ai_assert(!buffer.empty()); - - PLY::ESemantic eOut = PLY::EST_INVALID; - if (PLY::DOM::TokenMatch(buffer, "red", 3)) { - eOut = PLY::EST_Red; - } else if (PLY::DOM::TokenMatch(buffer, "green", 5)) { - eOut = PLY::EST_Green; - } else if (PLY::DOM::TokenMatch(buffer, "blue", 4)) { - eOut = PLY::EST_Blue; - } else if (PLY::DOM::TokenMatch(buffer, "alpha", 5)) { - eOut = PLY::EST_Alpha; - } else if (PLY::DOM::TokenMatch(buffer, "vertex_index", 12) || PLY::DOM::TokenMatch(buffer, "vertex_indices", 14)) { - eOut = PLY::EST_VertexIndex; - } else if (PLY::DOM::TokenMatch(buffer, "texcoord", 8)) // Manage uv coords on faces - { - eOut = PLY::EST_TextureCoordinates; - } else if (PLY::DOM::TokenMatch(buffer, "material_index", 14)) { - eOut = PLY::EST_MaterialIndex; - } else if (PLY::DOM::TokenMatch(buffer, "ambient_red", 11)) { - eOut = PLY::EST_AmbientRed; - } else if (PLY::DOM::TokenMatch(buffer, "ambient_green", 13)) { - eOut = PLY::EST_AmbientGreen; - } else if (PLY::DOM::TokenMatch(buffer, "ambient_blue", 12)) { - eOut = PLY::EST_AmbientBlue; - } else if (PLY::DOM::TokenMatch(buffer, "ambient_alpha", 13)) { - eOut = PLY::EST_AmbientAlpha; - } else if (PLY::DOM::TokenMatch(buffer, "diffuse_red", 11)) { - eOut = PLY::EST_DiffuseRed; - } else if (PLY::DOM::TokenMatch(buffer, "diffuse_green", 13)) { - eOut = PLY::EST_DiffuseGreen; - } else if (PLY::DOM::TokenMatch(buffer, "diffuse_blue", 12)) { - eOut = PLY::EST_DiffuseBlue; - } else if (PLY::DOM::TokenMatch(buffer, "diffuse_alpha", 13)) { - eOut = PLY::EST_DiffuseAlpha; - } else if (PLY::DOM::TokenMatch(buffer, "specular_red", 12)) { - eOut = PLY::EST_SpecularRed; - } else if (PLY::DOM::TokenMatch(buffer, "specular_green", 14)) { - eOut = PLY::EST_SpecularGreen; - } else if (PLY::DOM::TokenMatch(buffer, "specular_blue", 13)) { - eOut = PLY::EST_SpecularBlue; - } else if (PLY::DOM::TokenMatch(buffer, "specular_alpha", 14)) { - eOut = PLY::EST_SpecularAlpha; - } else if (PLY::DOM::TokenMatch(buffer, "opacity", 7)) { - eOut = PLY::EST_Opacity; - } else if (PLY::DOM::TokenMatch(buffer, "specular_power", 14)) { - eOut = PLY::EST_PhongPower; - } else if (PLY::DOM::TokenMatch(buffer, "r", 1)) { - eOut = PLY::EST_Red; - } else if (PLY::DOM::TokenMatch(buffer, "g", 1)) { - eOut = PLY::EST_Green; - } else if (PLY::DOM::TokenMatch(buffer, "b", 1)) { - eOut = PLY::EST_Blue; - } - - // NOTE: Blender3D exports texture coordinates as s,t tuples - else if (PLY::DOM::TokenMatch(buffer, "u", 1) || PLY::DOM::TokenMatch(buffer, "s", 1) || PLY::DOM::TokenMatch(buffer, "tx", 2) || PLY::DOM::TokenMatch(buffer, "texture_u", 9)) { - eOut = PLY::EST_UTextureCoord; - } else if (PLY::DOM::TokenMatch(buffer, "v", 1) || PLY::DOM::TokenMatch(buffer, "t", 1) || PLY::DOM::TokenMatch(buffer, "ty", 2) || PLY::DOM::TokenMatch(buffer, "texture_v", 9)) { - eOut = PLY::EST_VTextureCoord; - } else if (PLY::DOM::TokenMatch(buffer, "x", 1)) { - eOut = PLY::EST_XCoord; - } else if (PLY::DOM::TokenMatch(buffer, "y", 1)) { - eOut = PLY::EST_YCoord; - } else if (PLY::DOM::TokenMatch(buffer, "z", 1)) { - eOut = PLY::EST_ZCoord; - } else if (PLY::DOM::TokenMatch(buffer, "nx", 2)) { - eOut = PLY::EST_XNormal; - } else if (PLY::DOM::TokenMatch(buffer, "ny", 2)) { - eOut = PLY::EST_YNormal; - } else if (PLY::DOM::TokenMatch(buffer, "nz", 2)) { - eOut = PLY::EST_ZNormal; - } else { - ASSIMP_LOG_INFO("Found unknown property semantic in file. This is ok"); - PLY::DOM::SkipLine(buffer); - } - return eOut; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::Property::ParseProperty(std::vector<char> &buffer, PLY::Property *pOut) { - ai_assert(!buffer.empty()); - - // Forms supported: - // "property float x" - // "property list uchar int vertex_index" - - // skip leading spaces - if (!PLY::DOM::SkipSpaces(buffer)) { - return false; - } - - // skip the "property" string at the beginning - if (!PLY::DOM::TokenMatch(buffer, "property", 8)) { - // seems not to be a valid property entry - return false; - } - // get next word - if (!PLY::DOM::SkipSpaces(buffer)) { - return false; - } - if (PLY::DOM::TokenMatch(buffer, "list", 4)) { - pOut->bIsList = true; - - // seems to be a list. - if (EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(buffer))) { - // unable to parse list size data type - PLY::DOM::SkipLine(buffer); - return false; - } - if (!PLY::DOM::SkipSpaces(buffer)) return false; - if (EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(buffer))) { - // unable to parse list data type - PLY::DOM::SkipLine(buffer); - return false; - } - } else { - if (EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(buffer))) { - // unable to parse data type. Skip the property - PLY::DOM::SkipLine(buffer); - return false; - } - } - - if (!PLY::DOM::SkipSpaces(buffer)) - return false; - - pOut->Semantic = PLY::Property::ParseSemantic(buffer); - - if (PLY::EST_INVALID == pOut->Semantic) { - ASSIMP_LOG_INFO("Found unknown semantic in PLY file. This is OK"); - std::string(&buffer[0], &buffer[0] + strlen(&buffer[0])); - } - - PLY::DOM::SkipSpacesAndLineEnd(buffer); - return true; -} - -// ------------------------------------------------------------------------------------------------ -PLY::EElementSemantic PLY::Element::ParseSemantic(std::vector<char> &buffer) { - ai_assert(!buffer.empty()); - - PLY::EElementSemantic eOut = PLY::EEST_INVALID; - if (PLY::DOM::TokenMatch(buffer, "vertex", 6)) { - eOut = PLY::EEST_Vertex; - } else if (PLY::DOM::TokenMatch(buffer, "face", 4)) { - eOut = PLY::EEST_Face; - } else if (PLY::DOM::TokenMatch(buffer, "tristrips", 9)) { - eOut = PLY::EEST_TriStrip; - } -#if 0 - // TODO: maybe implement this? - else if (PLY::DOM::TokenMatch(buffer,"range_grid",10)) - { - eOut = PLY::EEST_Face; - } -#endif - else if (PLY::DOM::TokenMatch(buffer, "edge", 4)) { - eOut = PLY::EEST_Edge; - } else if (PLY::DOM::TokenMatch(buffer, "material", 8)) { - eOut = PLY::EEST_Material; - } else if (PLY::DOM::TokenMatch(buffer, "TextureFile", 11)) { - eOut = PLY::EEST_TextureFile; - } - - return eOut; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, PLY::Element *pOut) { - ai_assert(nullptr != pOut); - // Example format: "element vertex 8" - - // skip leading spaces - if (!PLY::DOM::SkipSpaces(buffer)) { - return false; - } - - // skip the "element" string at the beginning - if (!PLY::DOM::TokenMatch(buffer, "element", 7) && !PLY::DOM::TokenMatch(buffer, "comment", 7)) { - // seems not to be a valid property entry - return false; - } - // get next word - if (!PLY::DOM::SkipSpaces(buffer)) - return false; - - // parse the semantic of the element - pOut->eSemantic = PLY::Element::ParseSemantic(buffer); - if (PLY::EEST_INVALID == pOut->eSemantic) { - // if the exact semantic can't be determined, just store - // the original string identifier - pOut->szName = std::string(&buffer[0], &buffer[0] + strlen(&buffer[0])); - } - - if (!PLY::DOM::SkipSpaces(buffer)) - return false; - - if (PLY::EEST_TextureFile == pOut->eSemantic) { - char *endPos = &buffer[0] + (strlen(&buffer[0]) - 1); - pOut->szName = std::string(&buffer[0], endPos); - - // go to the next line - PLY::DOM::SkipSpacesAndLineEnd(buffer); - - return true; - } - - //parse the number of occurrences of this element - const char *pCur = (char *)&buffer[0]; - pOut->NumOccur = strtoul10(pCur, &pCur); - - // go to the next line - PLY::DOM::SkipSpacesAndLineEnd(buffer); - - // now parse all properties of the element - while (true) { - streamBuffer.getNextLine(buffer); - pCur = (char *)&buffer[0]; - - // skip all comments - PLY::DOM::SkipComments(buffer); - - PLY::Property prop; - if (!PLY::Property::ParseProperty(buffer, &prop)) - break; - - pOut->alProperties.push_back(prop); - } - - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) { - const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0]; - bool ret = false; - if (pCur) { - const char *szCur = pCur; - ret = Assimp::SkipSpaces(pCur, &pCur); - - uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur; - buffer.erase(buffer.begin(), buffer.begin() + iDiff); - return ret; - } - - return ret; -} - -bool PLY::DOM::SkipLine(std::vector<char> &buffer) { - const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0]; - bool ret = false; - if (pCur) { - const char *szCur = pCur; - ret = Assimp::SkipLine(pCur, &pCur); - - uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur; - buffer.erase(buffer.begin(), buffer.begin() + iDiff); - return ret; - } - - return ret; -} - -bool PLY::DOM::TokenMatch(std::vector<char> &buffer, const char *token, unsigned int len) { - const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0]; - bool ret = false; - if (pCur) { - const char *szCur = pCur; - ret = Assimp::TokenMatch(pCur, token, len); - - uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur; - buffer.erase(buffer.begin(), buffer.begin() + iDiff); - return ret; - } - - return ret; -} - -bool PLY::DOM::SkipSpacesAndLineEnd(std::vector<char> &buffer) { - const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0]; - bool ret = false; - if (pCur) { - const char *szCur = pCur; - ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur); - - uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur; - buffer.erase(buffer.begin(), buffer.begin() + iDiff); - return ret; - } - - return ret; -} - -bool PLY::DOM::SkipComments(std::vector<char> &buffer) { - ai_assert(!buffer.empty()); - - std::vector<char> nbuffer = buffer; - // skip spaces - if (!SkipSpaces(nbuffer)) { - return false; - } - - if (TokenMatch(nbuffer, "comment", 7)) { - if (!SkipSpaces(nbuffer)) - SkipLine(nbuffer); - - if (!TokenMatch(nbuffer, "TextureFile", 11)) { - SkipLine(nbuffer); - buffer = nbuffer; - return true; - } - - return true; - } - - return false; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, bool isBinary) { - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseHeader() begin"); - - // parse all elements - while (!buffer.empty()) { - // skip all comments - PLY::DOM::SkipComments(buffer); - - PLY::Element out; - if (PLY::Element::ParseElement(streamBuffer, buffer, &out)) { - // add the element to the list of elements - alElements.push_back(out); - } else if (TokenMatch(buffer, "end_header", 10)) { //checks for /n ending, if it doesn't end with /r/n - // we have reached the end of the header - break; - } else { - // ignore unknown header elements - streamBuffer.getNextLine(buffer); - } - } - - if (!isBinary) // it would occur an error, if binary data start with values as space or line end. - SkipSpacesAndLineEnd(buffer); - - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseHeader() succeeded"); - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::DOM::ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, PLYImporter *loader) { - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseElementInstanceLists() begin"); - alElementData.resize(alElements.size()); - - std::vector<PLY::Element>::const_iterator i = alElements.begin(); - std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin(); - - // parse all element instances - //construct vertices and faces - for (; i != alElements.end(); ++i, ++a) { - if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip) { - PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), nullptr, loader); - } else { - (*a).alInstances.resize((*i).NumOccur); - PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), &(*a), nullptr); - } - } - - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseElementInstanceLists() succeeded"); - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::DOM::ParseElementInstanceListsBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, - const char *&pCur, - unsigned int &bufferSize, - PLYImporter *loader, - bool p_bBE) { - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseElementInstanceListsBinary() begin"); - alElementData.resize(alElements.size()); - - std::vector<PLY::Element>::const_iterator i = alElements.begin(); - std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin(); - - // parse all element instances - for (; i != alElements.end(); ++i, ++a) { - if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip) { - PLY::ElementInstanceList::ParseInstanceListBinary(streamBuffer, buffer, pCur, bufferSize, &(*i), nullptr, loader, p_bBE); - } else { - (*a).alInstances.resize((*i).NumOccur); - PLY::ElementInstanceList::ParseInstanceListBinary(streamBuffer, buffer, pCur, bufferSize, &(*i), &(*a), nullptr, p_bBE); - } - } - - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseElementInstanceListsBinary() succeeded"); - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::DOM::ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM *p_pcOut, PLYImporter *loader, bool p_bBE) { - ai_assert(nullptr != p_pcOut); - ai_assert(nullptr != loader); - - std::vector<char> buffer; - streamBuffer.getNextLine(buffer); - - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstanceBinary() begin"); - - if (!p_pcOut->ParseHeader(streamBuffer, buffer, true)) { - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstanceBinary() failure"); - return false; - } - - streamBuffer.getNextBlock(buffer); - - // remove first char if it's /n in case of file with /r/n - if (((char *)&buffer[0])[0] == '\n') - buffer.erase(buffer.begin(), buffer.begin() + 1); - - unsigned int bufferSize = static_cast<unsigned int>(buffer.size()); - const char *pCur = (char *)&buffer[0]; - if (!p_pcOut->ParseElementInstanceListsBinary(streamBuffer, buffer, pCur, bufferSize, loader, p_bBE)) { - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstanceBinary() failure"); - return false; - } - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstanceBinary() succeeded"); - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::DOM::ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM *p_pcOut, PLYImporter *loader) { - ai_assert(nullptr != p_pcOut); - ai_assert(nullptr != loader); - - std::vector<char> buffer; - streamBuffer.getNextLine(buffer); - - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstance() begin"); - - if (!p_pcOut->ParseHeader(streamBuffer, buffer, false)) { - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstance() failure"); - return false; - } - - //get next line after header - streamBuffer.getNextLine(buffer); - if (!p_pcOut->ParseElementInstanceLists(streamBuffer, buffer, loader)) { - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstance() failure"); - return false; - } - ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstance() succeeded"); - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::ElementInstanceList::ParseInstanceList( - IOStreamBuffer<char> &streamBuffer, - std::vector<char> &buffer, - const PLY::Element *pcElement, - PLY::ElementInstanceList *p_pcOut, - PLYImporter *loader) { - ai_assert(nullptr != pcElement); - - // parse all elements - if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty()) { - // if the element has an unknown semantic we can skip all lines - // However, there could be comments - for (unsigned int i = 0; i < pcElement->NumOccur; ++i) { - PLY::DOM::SkipComments(buffer); - PLY::DOM::SkipLine(buffer); - streamBuffer.getNextLine(buffer); - } - } else { - const char *pCur = (const char *)&buffer[0]; - // be sure to have enough storage - for (unsigned int i = 0; i < pcElement->NumOccur; ++i) { - if (p_pcOut) - PLY::ElementInstance::ParseInstance(pCur, pcElement, &p_pcOut->alInstances[i]); - else { - ElementInstance elt; - PLY::ElementInstance::ParseInstance(pCur, pcElement, &elt); - - // Create vertex or face - if (pcElement->eSemantic == EEST_Vertex) { - //call loader instance from here - loader->LoadVertex(pcElement, &elt, i); - } else if (pcElement->eSemantic == EEST_Face) { - //call loader instance from here - loader->LoadFace(pcElement, &elt, i); - } else if (pcElement->eSemantic == EEST_TriStrip) { - //call loader instance from here - loader->LoadFace(pcElement, &elt, i); - } - } - - streamBuffer.getNextLine(buffer); - pCur = (buffer.empty()) ? nullptr : (const char *)&buffer[0]; - } - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::ElementInstanceList::ParseInstanceListBinary( - IOStreamBuffer<char> &streamBuffer, - std::vector<char> &buffer, - const char *&pCur, - unsigned int &bufferSize, - const PLY::Element *pcElement, - PLY::ElementInstanceList *p_pcOut, - PLYImporter *loader, - bool p_bBE /* = false */) { - ai_assert(nullptr != pcElement); - - // we can add special handling code for unknown element semantics since - // we can't skip it as a whole block (we don't know its exact size - // due to the fact that lists could be contained in the property list - // of the unknown element) - for (unsigned int i = 0; i < pcElement->NumOccur; ++i) { - if (p_pcOut) - PLY::ElementInstance::ParseInstanceBinary(streamBuffer, buffer, pCur, bufferSize, pcElement, &p_pcOut->alInstances[i], p_bBE); - else { - ElementInstance elt; - PLY::ElementInstance::ParseInstanceBinary(streamBuffer, buffer, pCur, bufferSize, pcElement, &elt, p_bBE); - - // Create vertex or face - if (pcElement->eSemantic == EEST_Vertex) { - //call loader instance from here - loader->LoadVertex(pcElement, &elt, i); - } else if (pcElement->eSemantic == EEST_Face) { - //call loader instance from here - loader->LoadFace(pcElement, &elt, i); - } else if (pcElement->eSemantic == EEST_TriStrip) { - //call loader instance from here - loader->LoadFace(pcElement, &elt, i); - } - } - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::ElementInstance::ParseInstance(const char *&pCur, - const PLY::Element *pcElement, - PLY::ElementInstance *p_pcOut) { - ai_assert(nullptr != pcElement); - ai_assert(nullptr != p_pcOut); - - // allocate enough storage - p_pcOut->alProperties.resize(pcElement->alProperties.size()); - - std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin(); - std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin(); - for (; i != p_pcOut->alProperties.end(); ++i, ++a) { - if (!(PLY::PropertyInstance::ParseInstance(pCur, &(*a), &(*i)))) { - ASSIMP_LOG_WARN("Unable to parse property instance. " - "Skipping this element instance"); - - PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType); - (*i).avList.push_back(v); - } - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::ElementInstance::ParseInstanceBinary( - IOStreamBuffer<char> &streamBuffer, - std::vector<char> &buffer, - const char *&pCur, - unsigned int &bufferSize, - const PLY::Element *pcElement, - PLY::ElementInstance *p_pcOut, - bool p_bBE /* = false */) { - ai_assert(nullptr != pcElement); - ai_assert(nullptr != p_pcOut); - - // allocate enough storage - p_pcOut->alProperties.resize(pcElement->alProperties.size()); - - std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin(); - std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin(); - for (; i != p_pcOut->alProperties.end(); ++i, ++a) { - if (!(PLY::PropertyInstance::ParseInstanceBinary(streamBuffer, buffer, pCur, bufferSize, &(*a), &(*i), p_bBE))) { - ASSIMP_LOG_WARN("Unable to parse binary property instance. " - "Skipping this element instance"); - - (*i).avList.push_back(PLY::PropertyInstance::DefaultValue((*a).eType)); - } - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::PropertyInstance::ParseInstance(const char *&pCur, - const PLY::Property *prop, PLY::PropertyInstance *p_pcOut) { - ai_assert(nullptr != prop); - ai_assert(nullptr != p_pcOut); - - // skip spaces at the beginning - if (!SkipSpaces(&pCur)) { - return false; - } - - if (prop->bIsList) { - // parse the number of elements in the list - PLY::PropertyInstance::ValueUnion v; - PLY::PropertyInstance::ParseValue(pCur, prop->eFirstType, &v); - - // convert to unsigned int - unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v, prop->eFirstType); - - // parse all list elements - p_pcOut->avList.resize(iNum); - for (unsigned int i = 0; i < iNum; ++i) { - if (!SkipSpaces(&pCur)) - return false; - - PLY::PropertyInstance::ParseValue(pCur, prop->eType, &p_pcOut->avList[i]); - } - } else { - // parse the property - PLY::PropertyInstance::ValueUnion v; - - PLY::PropertyInstance::ParseValue(pCur, prop->eType, &v); - p_pcOut->avList.push_back(v); - } - SkipSpacesAndLineEnd(&pCur); - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::PropertyInstance::ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, - const char *&pCur, - unsigned int &bufferSize, - const PLY::Property *prop, - PLY::PropertyInstance *p_pcOut, - bool p_bBE) { - ai_assert(nullptr != prop); - ai_assert(nullptr != p_pcOut); - - // parse all elements - if (prop->bIsList) { - // parse the number of elements in the list - PLY::PropertyInstance::ValueUnion v; - PLY::PropertyInstance::ParseValueBinary(streamBuffer, buffer, pCur, bufferSize, prop->eFirstType, &v, p_bBE); - - // convert to unsigned int - unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v, prop->eFirstType); - - // parse all list elements - p_pcOut->avList.resize(iNum); - for (unsigned int i = 0; i < iNum; ++i) { - PLY::PropertyInstance::ParseValueBinary(streamBuffer, buffer, pCur, bufferSize, prop->eType, &p_pcOut->avList[i], p_bBE); - } - } else { - // parse the property - PLY::PropertyInstance::ValueUnion v; - PLY::PropertyInstance::ParseValueBinary(streamBuffer, buffer, pCur, bufferSize, prop->eType, &v, p_bBE); - p_pcOut->avList.push_back(v); - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -PLY::PropertyInstance::ValueUnion PLY::PropertyInstance::DefaultValue(PLY::EDataType eType) { - PLY::PropertyInstance::ValueUnion out; - - switch (eType) { - case EDT_Float: - out.fFloat = 0.f; - return out; - - case EDT_Double: - out.fDouble = 0.; - return out; - - default:; - }; - out.iUInt = 0; - return out; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::PropertyInstance::ParseValue(const char *&pCur, - PLY::EDataType eType, - PLY::PropertyInstance::ValueUnion *out) { - ai_assert(nullptr != pCur); - ai_assert(nullptr != out); - - //calc element size - bool ret = true; - switch (eType) { - case EDT_UInt: - case EDT_UShort: - case EDT_UChar: - - out->iUInt = (uint32_t)strtoul10(pCur, &pCur); - break; - - case EDT_Int: - case EDT_Short: - case EDT_Char: - - out->iInt = (int32_t)strtol10(pCur, &pCur); - break; - - case EDT_Float: - // technically this should cast to float, but people tend to use float descriptors for double data - // this is the best way to not risk losing precision on import and it doesn't hurt to do this - ai_real f; - pCur = fast_atoreal_move<ai_real>(pCur, f); - out->fFloat = (ai_real)f; - break; - - case EDT_Double: - double d; - pCur = fast_atoreal_move<double>(pCur, d); - out->fDouble = (double)d; - break; - - case EDT_INVALID: - default: - ret = false; - break; - } - - return ret; -} - -// ------------------------------------------------------------------------------------------------ -bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer, - std::vector<char> &buffer, - const char *&pCur, - unsigned int &bufferSize, - PLY::EDataType eType, - PLY::PropertyInstance::ValueUnion *out, - bool p_bBE) { - ai_assert(nullptr != out); - - //calc element size - unsigned int lsize = 0; - switch (eType) { - case EDT_Char: - case EDT_UChar: - lsize = 1; - break; - - case EDT_UShort: - case EDT_Short: - lsize = 2; - break; - - case EDT_UInt: - case EDT_Int: - case EDT_Float: - lsize = 4; - break; - - case EDT_Double: - lsize = 8; - break; - - case EDT_INVALID: - default: - break; - } - - //read the next file block if needed - if (bufferSize < lsize) { - std::vector<char> nbuffer; - if (streamBuffer.getNextBlock(nbuffer)) { - //concat buffer contents - buffer = std::vector<char>(buffer.end() - bufferSize, buffer.end()); - buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end()); - nbuffer.clear(); - bufferSize = static_cast<unsigned int>(buffer.size()); - pCur = (char *)&buffer[0]; - } else { - throw DeadlyImportError("Invalid .ply file: File corrupted"); - } - } - - bool ret = true; - switch (eType) { - case EDT_UInt: { - uint32_t t; - memcpy(&t, pCur, sizeof(uint32_t)); - pCur += sizeof(uint32_t); - - // Swap endianness - if (p_bBE) ByteSwap::Swap(&t); - out->iUInt = t; - break; - } - - case EDT_UShort: { - uint16_t t; - memcpy(&t, pCur, sizeof(uint16_t)); - pCur += sizeof(uint16_t); - - // Swap endianness - if (p_bBE) ByteSwap::Swap(&t); - out->iUInt = t; - break; - } - - case EDT_UChar: { - uint8_t t; - memcpy(&t, pCur, sizeof(uint8_t)); - pCur += sizeof(uint8_t); - out->iUInt = t; - break; - } - - case EDT_Int: { - int32_t t; - memcpy(&t, pCur, sizeof(int32_t)); - pCur += sizeof(int32_t); - - // Swap endianness - if (p_bBE) ByteSwap::Swap(&t); - out->iInt = t; - break; - } - - case EDT_Short: { - int16_t t; - memcpy(&t, pCur, sizeof(int16_t)); - pCur += sizeof(int16_t); - - // Swap endianness - if (p_bBE) ByteSwap::Swap(&t); - out->iInt = t; - break; - } - - case EDT_Char: { - int8_t t; - memcpy(&t, pCur, sizeof(int8_t)); - pCur += sizeof(int8_t); - out->iInt = t; - break; - } - - case EDT_Float: { - float t; - memcpy(&t, pCur, sizeof(float)); - pCur += sizeof(float); - - // Swap endianness - if (p_bBE) ByteSwap::Swap(&t); - out->fFloat = t; - break; - } - case EDT_Double: { - double t; - memcpy(&t, pCur, sizeof(double)); - pCur += sizeof(double); - - // Swap endianness - if (p_bBE) ByteSwap::Swap(&t); - out->fDouble = t; - break; - } - default: - ret = false; - } - - bufferSize -= lsize; - - return ret; -} - -#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER diff --git a/libs/assimp/code/AssetLib/Ply/PlyParser.h b/libs/assimp/code/AssetLib/Ply/PlyParser.h deleted file mode 100644 index 8634929..0000000 --- a/libs/assimp/code/AssetLib/Ply/PlyParser.h +++ /dev/null @@ -1,488 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Defines the helper data structures for importing PLY files */ -#pragma once -#ifndef AI_PLYFILEHELPER_H_INC -#define AI_PLYFILEHELPER_H_INC - -#include <assimp/ParsingUtils.h> -#include <assimp/IOStreamBuffer.h> -#include <vector> - -namespace Assimp { - -//pre-declaration -class PLYImporter; - -// http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/ -// http://w3.impa.br/~lvelho/outgoing/sossai/old/ViHAP_D4.4.2_PLY_format_v1.1.pdf -// http://www.okino.com/conv/exp_ply.htm -namespace PLY { - -// --------------------------------------------------------------------------------- -/* -name type number of bytes ---------------------------------------- -char character 1 -uchar unsigned character 1 -short short integer 2 -ushort unsigned short integer 2 -int integer 4 -uint unsigned integer 4 -float single-precision float 4 -double double-precision float 8 - -int8 -int16 -uint8 ... forms are also used -*/ -enum EDataType { - EDT_Char = 0x0u, - EDT_UChar, - EDT_Short, - EDT_UShort, - EDT_Int, - EDT_UInt, - EDT_Float, - EDT_Double, - - // Marks invalid entries - EDT_INVALID -}; - -// --------------------------------------------------------------------------------- -/** \brief Specifies semantics for PLY element properties - * - * Semantics define the usage of a property, e.g. x coordinate -*/ -enum ESemantic { - //! vertex position x coordinate - EST_XCoord = 0x0u, - //! vertex position x coordinate - EST_YCoord, - //! vertex position x coordinate - EST_ZCoord, - - //! vertex normal x coordinate - EST_XNormal, - //! vertex normal y coordinate - EST_YNormal, - //! vertex normal z coordinate - EST_ZNormal, - - //! u texture coordinate - EST_UTextureCoord, - //! v texture coordinate - EST_VTextureCoord, - - //! vertex colors, red channel - EST_Red, - //! vertex colors, green channel - EST_Green, - //! vertex colors, blue channel - EST_Blue, - //! vertex colors, alpha channel - EST_Alpha, - - //! vertex index list - EST_VertexIndex, - - //! texture index - EST_TextureIndex, - - //! texture coordinates (stored as element of a face) - EST_TextureCoordinates, - - //! material index - EST_MaterialIndex, - - //! ambient color, red channel - EST_AmbientRed, - //! ambient color, green channel - EST_AmbientGreen, - //! ambient color, blue channel - EST_AmbientBlue, - //! ambient color, alpha channel - EST_AmbientAlpha, - - //! diffuse color, red channel - EST_DiffuseRed, - //! diffuse color, green channel - EST_DiffuseGreen, - //! diffuse color, blue channel - EST_DiffuseBlue, - //! diffuse color, alpha channel - EST_DiffuseAlpha, - - //! specular color, red channel - EST_SpecularRed, - //! specular color, green channel - EST_SpecularGreen, - //! specular color, blue channel - EST_SpecularBlue, - //! specular color, alpha channel - EST_SpecularAlpha, - - //! specular power for phong shading - EST_PhongPower, - - //! opacity between 0 and 1 - EST_Opacity, - - //! Marks invalid entries - EST_INVALID -}; - -// --------------------------------------------------------------------------------- -/** \brief Specifies semantics for PLY elements - * - * Semantics define the usage of an element, e.g. vertex or material -*/ -enum EElementSemantic { - //! The element is a vertex - EEST_Vertex = 0x0u, - - //! The element is a face description (index table) - EEST_Face, - - //! The element is a triangle-strip description (index table) - EEST_TriStrip, - - //! The element is an edge description (ignored) - EEST_Edge, - - //! The element is a material description - EEST_Material, - - //! texture path - EEST_TextureFile, - - //! Marks invalid entries - EEST_INVALID -}; - -// --------------------------------------------------------------------------------- -/** \brief Helper class for a property in a PLY file. - * - * This can e.g. be a part of the vertex declaration - */ -class Property { -public: - //! Default constructor - Property() AI_NO_EXCEPT - : eType (EDT_Int) - , Semantic() - , bIsList(false) - , eFirstType(EDT_UChar) { - // empty - } - - //! Data type of the property - EDataType eType; - - //! Semantical meaning of the property - ESemantic Semantic; - - //! Of the semantic of the property could not be parsed: - //! Contains the semantic specified in the file - std::string szName; - - //! Specifies whether the data type is a list where - //! the first element specifies the size of the list - bool bIsList; - EDataType eFirstType; - - // ------------------------------------------------------------------- - //! Parse a property from a string. The end of the - //! string is either '\n', '\r' or '\0'. Return value is false - //! if the input string is NOT a valid property (E.g. does - //! not start with the "property" keyword) - static bool ParseProperty(std::vector<char> &buffer, Property* pOut); - - // ------------------------------------------------------------------- - //! Parse a data type from a string - static EDataType ParseDataType(std::vector<char> &buffer); - - // ------------------------------------------------------------------- - //! Parse a semantic from a string - static ESemantic ParseSemantic(std::vector<char> &buffer); -}; - -// --------------------------------------------------------------------------------- -/** \brief Helper class for an element in a PLY file. - * - * This can e.g. be the vertex declaration. Elements contain a - * well-defined number of properties. - */ -class Element { -public: - //! Default constructor - Element() AI_NO_EXCEPT - : eSemantic (EEST_INVALID) - , NumOccur(0) { - // empty - } - - //! List of properties assigned to the element - //! std::vector to support operator[] - std::vector<Property> alProperties; - - //! Semantic of the element - EElementSemantic eSemantic; - - //! Of the semantic of the element could not be parsed: - //! Contains the semantic specified in the file - std::string szName; - - //! How many times will the element occur? - unsigned int NumOccur; - - - // ------------------------------------------------------------------- - //! Parse an element from a string. - //! The function will parse all properties contained in the - //! element, too. - static bool ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, Element* pOut); - - // ------------------------------------------------------------------- - //! Parse a semantic from a string - static EElementSemantic ParseSemantic(std::vector<char> &buffer); -}; - -// --------------------------------------------------------------------------------- -/** \brief Instance of a property in a PLY file - */ -class PropertyInstance -{ -public: - - //! Default constructor - PropertyInstance() AI_NO_EXCEPT { - // empty - } - - union ValueUnion - { - - //! uInt32 representation of the property. All - // uint types are automatically converted to uint32 - uint32_t iUInt; - - //! Int32 representation of the property. All - // int types are automatically converted to int32 - int32_t iInt; - - //! Float32 representation of the property - float fFloat; - - //! Float64 representation of the property - double fDouble; - - }; - - // ------------------------------------------------------------------- - //! List of all values parsed. Contains only one value - // for non-list properties - std::vector<ValueUnion> avList; - - // ------------------------------------------------------------------- - //! Parse a property instance - static bool ParseInstance(const char* &pCur, - const Property* prop, PropertyInstance* p_pcOut); - - // ------------------------------------------------------------------- - //! Parse a property instance in binary format - static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, - const char* &pCur, unsigned int &bufferSize, const Property* prop, PropertyInstance* p_pcOut, bool p_bBE); - - // ------------------------------------------------------------------- - //! Get the default value for a given data type - static ValueUnion DefaultValue(EDataType eType); - - // ------------------------------------------------------------------- - //! Parse a value - static bool ParseValue(const char* &pCur, EDataType eType, ValueUnion* out); - - // ------------------------------------------------------------------- - //! Parse a binary value - static bool ParseValueBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, - const char* &pCur, unsigned int &bufferSize, EDataType eType, ValueUnion* out, bool p_bBE); - - // ------------------------------------------------------------------- - //! Convert a property value to a given type TYPE - template <typename TYPE> - static TYPE ConvertTo(ValueUnion v, EDataType eType); -}; - -// --------------------------------------------------------------------------------- -/** \brief Class for an element instance in a PLY file - */ -class ElementInstance { -public: - //! Default constructor - ElementInstance() AI_NO_EXCEPT - : alProperties() { - // empty - } - - //! List of all parsed properties - std::vector< PropertyInstance > alProperties; - - // ------------------------------------------------------------------- - //! Parse an element instance - static bool ParseInstance(const char* &pCur, - const Element* pcElement, ElementInstance* p_pcOut); - - // ------------------------------------------------------------------- - //! Parse a binary element instance - static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, - const char* &pCur, unsigned int &bufferSize, const Element* pcElement, ElementInstance* p_pcOut, bool p_bBE); -}; - -// --------------------------------------------------------------------------------- -/** \brief Class for an element instance list in a PLY file - */ -class ElementInstanceList -{ -public: - - //! Default constructor - ElementInstanceList() AI_NO_EXCEPT - : alInstances() { - // empty - } - - //! List of all element instances - std::vector< ElementInstance > alInstances; - - // ------------------------------------------------------------------- - //! Parse an element instance list - static bool ParseInstanceList(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, - const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader); - - // ------------------------------------------------------------------- - //! Parse a binary element instance list - static bool ParseInstanceListBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, - const char* &pCur, unsigned int &bufferSize, const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader, bool p_bBE); -}; -// --------------------------------------------------------------------------------- -/** \brief Class to represent the document object model of an ASCII or binary - * (both little and big-endian) PLY file - */ -class DOM -{ -public: - - //! Default constructor - DOM() AI_NO_EXCEPT - : alElements() - , alElementData() { - - } - - - //! Contains all elements of the file format - std::vector<Element> alElements; - //! Contains the real data of each element's instance list - std::vector<ElementInstanceList> alElementData; - - //! Parse the DOM for a PLY file. The input string is assumed - //! to be terminated with zero - static bool ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader); - static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader, bool p_bBE); - - //! Skip all comment lines after this - static bool SkipComments(std::vector<char> &buffer); - - static bool SkipSpaces(std::vector<char> &buffer); - - static bool SkipLine(std::vector<char> &buffer); - - static bool TokenMatch(std::vector<char> &buffer, const char* token, unsigned int len); - - static bool SkipSpacesAndLineEnd(std::vector<char> &buffer); - -private: - - // ------------------------------------------------------------------- - //! Handle the file header and read all element descriptions - bool ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, bool p_bBE); - - // ------------------------------------------------------------------- - //! Read in all element instance lists - bool ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, PLYImporter* loader); - - // ------------------------------------------------------------------- - //! Read in all element instance lists for a binary file format - bool ParseElementInstanceListsBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, const char* &pCur, unsigned int &bufferSize, PLYImporter* loader, bool p_bBE); -}; - -// --------------------------------------------------------------------------------- -template <typename TYPE> -inline TYPE PLY::PropertyInstance::ConvertTo( - PLY::PropertyInstance::ValueUnion v, PLY::EDataType eType) -{ - switch (eType) - { - case EDT_Float: - return (TYPE)v.fFloat; - case EDT_Double: - return (TYPE)v.fDouble; - - case EDT_UInt: - case EDT_UShort: - case EDT_UChar: - return (TYPE)v.iUInt; - - case EDT_Int: - case EDT_Short: - case EDT_Char: - return (TYPE)v.iInt; - default: ; - }; - return (TYPE)0; -} - -} // Namespace PLY -} // Namespace AssImp - -#endif // !! include guard |