diff options
Diffstat (limited to 'src/mesh/assimp-master/code/AssetLib/Ply/PlyLoader.cpp')
-rw-r--r-- | src/mesh/assimp-master/code/AssetLib/Ply/PlyLoader.cpp | 927 |
1 files changed, 0 insertions, 927 deletions
diff --git a/src/mesh/assimp-master/code/AssetLib/Ply/PlyLoader.cpp b/src/mesh/assimp-master/code/AssetLib/Ply/PlyLoader.cpp deleted file mode 100644 index 6cf1a1c..0000000 --- a/src/mesh/assimp-master/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 |