update assimp to 6.0.5

This commit is contained in:
AzaezelX 2026-06-09 12:46:56 -05:00
parent 2d2eb57e2e
commit f5cf21cfeb
941 changed files with 22718 additions and 12240 deletions

View file

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -39,9 +38,6 @@ 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"
@ -54,9 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exporter.hpp>
#include <assimp/qnan.h>
//using namespace Assimp;
namespace Assimp {
namespace Assimp {
// make sure type_of returns consistent output across different platforms
// also consider using: typeid(VAR).name()
@ -66,8 +60,7 @@ 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*/)
{
void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
// invoke the exporter
PlyExporter exporter(pFile, pScene);
@ -84,8 +77,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
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*/)
{
void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
// invoke the exporter
PlyExporter exporter(pFile, pScene, true);
@ -104,10 +96,8 @@ void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene*
#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")
{
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);
@ -149,19 +139,14 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina
<< aiGetVersionRevision() << ")" << endl;
// Look through materials for a diffuse texture, and add it if found
for ( unsigned int i = 0; i < pScene->mNumMaterials; ++i )
{
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 ) )
{
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);
@ -182,24 +167,12 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina
// 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 {
} else {
mOutput << "property " << "uchar" << " red" << c << endl;
mOutput << "property " << "uchar" << " green" << c << endl;
mOutput << "property " << "uchar" << " blue" << c << endl;
@ -228,16 +201,14 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
if (binary) {
WriteMeshVertsBinary(pScene->mMeshes[i], components);
}
else {
} 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 {
} else {
WriteMeshIndices(pScene->mMeshes[i], ofs);
}
ofs += pScene->mMeshes[i]->mNumVertices;
@ -245,12 +216,8 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina
}
// ------------------------------------------------------------------------------------------------
PlyExporter::~PlyExporter() = default;
// ------------------------------------------------------------------------------------------------
void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components)
{
static const ai_real inf = std::numeric_limits<ai_real>::infinity();
void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components) {
static constexpr 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.
@ -258,27 +225,33 @@ void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components)
mOutput <<
m->mVertices[i].x << " " <<
m->mVertices[i].y << " " <<
m->mVertices[i].z
;
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 {
} 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 {
if (m->mNumUVComponents[c] == 3) {
mOutput <<
" " << m->mTextureCoords[c][i].x <<
" " << m->mTextureCoords[c][i].y <<
" " << m->mTextureCoords[c][i].z;
} else if (m->mNumUVComponents[c] == 2) {
mOutput <<
" " << m->mTextureCoords[c][i].x <<
" " << m->mTextureCoords[c][i].y;
} else {
throw DeadlyExportError("Invalid number of texture coordinates detected: " + std::to_string(m->mNumUVComponents[c]));
}
} else {
mOutput << " -1.0 -1.0";
}
}
@ -290,8 +263,7 @@ void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components)
" " << (int)(m->mColors[c][i].g * 255) <<
" " << (int)(m->mColors[c][i].b * 255) <<
" " << (int)(m->mColors[c][i].a * 255);
}
else {
} else {
mOutput << " 0 0 0";
}
}
@ -299,15 +271,13 @@ void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components)
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 {
" " << 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";
}
}
@ -317,8 +287,7 @@ void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components)
}
// ------------------------------------------------------------------------------------------------
void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
{
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);
@ -329,8 +298,7 @@ void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
if (components & PLY_EXPORT_HAS_NORMALS) {
if (m->HasNormals()) {
mOutput.write(reinterpret_cast<const char*>(&m->mNormals[i].x), 12);
}
else {
} else {
mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
}
}
@ -338,8 +306,7 @@ void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
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 {
} else {
mOutput.write(reinterpret_cast<const char*>(&defaultUV.x), 8);
}
}
@ -353,12 +320,11 @@ void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
static_cast<unsigned char>(m->mColors[c][i].a * 255)
};
mOutput.write(reinterpret_cast<const char*>(&rgba), 4);
}
else {
} else {
unsigned char rgba[4] = {
static_cast<unsigned char>(defaultColor.r * 255),
static_cast<unsigned char>(defaultColor.g * 255),
static_cast<unsigned char>(defaultColor.b * 255),
static_cast<unsigned char>(defaultColor.b * 255),
static_cast<unsigned char>(defaultColor.a * 255)
};
mOutput.write(reinterpret_cast<const char*>(&rgba), 4);
@ -369,8 +335,7 @@ void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
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 {
} else {
mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
}
@ -379,8 +344,7 @@ void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
}
// ------------------------------------------------------------------------------------------------
void PlyExporter::WriteMeshIndices(const aiMesh* m, unsigned int offset)
{
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;
@ -391,10 +355,10 @@ void PlyExporter::WriteMeshIndices(const aiMesh* m, unsigned int offset)
}
}
// ------------------------------------------------------------------------------------------------
// 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)
{
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);
@ -406,8 +370,8 @@ void WriteMeshIndicesBinary_Generic(const aiMesh* m, unsigned int offset, std::o
}
}
void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset)
{
// ------------------------------------------------------------------------------------------------
void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset) {
WriteMeshIndicesBinary_Generic<unsigned char, int>(m, offset, mOutput);
}

View file

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -62,7 +61,10 @@ 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();
~PlyExporter() = default;
PlyExporter( const PlyExporter & ) = delete;
PlyExporter &operator = ( const PlyExporter & ) = delete;
public:
/// public string-streams to write all output into:
@ -77,10 +79,6 @@ private:
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

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -60,70 +60,60 @@ namespace Assimp {
using namespace PLY;
// ---------------------------------------------------------------------------
/** Importer class to load the stanford PLY file format
*/
/// @brief Importer class to load the stanford PLY file format
// ---------------------------------------------------------------------------
class PLYImporter final : public BaseImporter {
public:
PLYImporter();
/// @brief Default constructor
PLYImporter() = default;
/// @brief Destructor
~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;
/// 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
*/
/// 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
*/
/// @brief Extract a face from the DOM
/// The function will also take care of the correct winding order of the triangles.
/// @param pcElement The element containing the face data
/// @param instElement The element instance containing the face data
/// @param pos The position of the face in the element instance. This is needed to correctly assign the face to the mesh.
void LoadFace(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos);
/// @brief Will create a triangle from a triangle strip.
/// The function will use the first three vertices of the strip to create the first triangle, then the second,
/// third and fourth vertex to create the second triangle and so on. The function will also take care of the correct
/// winding order of the triangles.
/// @param instElement The element instance containing the triangle strip data
/// @param iProperty The index of the property containing the triangle strip data
/// @param eType The data type of the triangle strip data
void createFromeTriStrip(const Assimp::PLY::ElementInstance *instElement, unsigned int iProperty, Assimp::PLY::EDataType eType);
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;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
// -------------------------------------------------------------------
/** Extract a material list from the DOM
*/
/// @brief Extract a material list from the DOM
/// @param pvOut The output material list. The function will fill the list with the extracted materials.
/// @param defaultTexture The default texture to use for the materials. This is needed to correctly assign the texture to the materials.
/// @param pointsOnly Whether the file contains only points. This is needed to correctly assign the material properties.
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);
private:
unsigned char *mBuffer;
PLY::DOM *pcDOM;
aiMesh *mGeneratedMesh;
unsigned char *mBuffer{nullptr};
PLY::DOM *pcDOM{nullptr};
aiMesh *mGeneratedMesh{nullptr};
};
} // end of namespace Assimp

View file

@ -3,8 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -53,53 +52,53 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
std::string to_string(EElementSemantic e) {
// ------------------------------------------------------------------------------------------------
static std::string to_string(EElementSemantic e) {
switch (e) {
case EEST_Vertex:
return std::string{ "vertex" };
case EEST_TriStrip:
return std::string{ "tristrips" };
case EEST_Edge:
return std::string{ "edge" };
case EEST_Material:
return std::string{ "material" };
case EEST_TextureFile:
return std::string{ "TextureFile" };
default:
return std::string{ "invalid" };
case EEST_Vertex:
return std::string{ "vertex" };
case EEST_TriStrip:
return std::string{ "tristrips" };
case EEST_Edge:
return std::string{ "edge" };
case EEST_Material:
return std::string{ "material" };
case EEST_TextureFile:
return std::string{ "TextureFile" };
default:
return std::string{ "invalid" };
}
}
// ------------------------------------------------------------------------------------------------
PLY::EDataType PLY::Property::ParseDataType(std::vector<char> &buffer) {
EDataType Property::ParseDataType(std::vector<char> &buffer) {
ai_assert(!buffer.empty());
PLY::EDataType eOut = PLY::EDT_INVALID;
EDataType eOut = 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 (DOM::TokenMatch(buffer, "char", 4) ||
DOM::TokenMatch(buffer, "int8", 4)) {
eOut = EDT_Char;
} else if (DOM::TokenMatch(buffer, "uchar", 5) ||
DOM::TokenMatch(buffer, "uint8", 5)) {
eOut = EDT_UChar;
} else if (DOM::TokenMatch(buffer, "short", 5) ||
DOM::TokenMatch(buffer, "int16", 5)) {
eOut = EDT_Short;
} else if (DOM::TokenMatch(buffer, "ushort", 6) ||
DOM::TokenMatch(buffer, "uint16", 6)) {
eOut = EDT_UShort;
} else if (DOM::TokenMatch(buffer, "int32", 5) || DOM::TokenMatch(buffer, "int", 3)) {
eOut = EDT_Int;
} else if (DOM::TokenMatch(buffer, "uint32", 6) || DOM::TokenMatch(buffer, "uint", 4)) {
eOut = EDT_UInt;
} else if (DOM::TokenMatch(buffer, "float", 5) || DOM::TokenMatch(buffer, "float32", 7)) {
eOut = EDT_Float;
} else if (DOM::TokenMatch(buffer, "double64", 8) || DOM::TokenMatch(buffer, "double", 6) ||
DOM::TokenMatch(buffer, "float64", 7)) {
eOut = EDT_Double;
}
if (PLY::EDT_INVALID == eOut) {
if (EDT_INVALID == eOut) {
ASSIMP_LOG_INFO("Found unknown data type in PLY file. This is OK");
}
@ -107,81 +106,81 @@ PLY::EDataType PLY::Property::ParseDataType(std::vector<char> &buffer) {
}
// ------------------------------------------------------------------------------------------------
PLY::ESemantic PLY::Property::ParseSemantic(std::vector<char> &buffer) {
ESemantic 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
ESemantic eOut = PLY::EST_INVALID;
if (DOM::TokenMatch(buffer, "red", 3)) {
eOut = EST_Red;
} else if (DOM::TokenMatch(buffer, "green", 5)) {
eOut = EST_Green;
} else if (DOM::TokenMatch(buffer, "blue", 4)) {
eOut = EST_Blue;
} else if (DOM::TokenMatch(buffer, "alpha", 5)) {
eOut = EST_Alpha;
} else if (DOM::TokenMatch(buffer, "vertex_index", 12) || PLY::DOM::TokenMatch(buffer, "vertex_indices", 14)) {
eOut = EST_VertexIndex;
} else if (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;
eOut = EST_TextureCoordinates;
} else if (DOM::TokenMatch(buffer, "material_index", 14)) {
eOut = EST_MaterialIndex;
} else if (DOM::TokenMatch(buffer, "ambient_red", 11)) {
eOut = EST_AmbientRed;
} else if (DOM::TokenMatch(buffer, "ambient_green", 13)) {
eOut = EST_AmbientGreen;
} else if (DOM::TokenMatch(buffer, "ambient_blue", 12)) {
eOut = EST_AmbientBlue;
} else if (DOM::TokenMatch(buffer, "ambient_alpha", 13)) {
eOut = EST_AmbientAlpha;
} else if (DOM::TokenMatch(buffer, "diffuse_red", 11)) {
eOut = EST_DiffuseRed;
} else if (DOM::TokenMatch(buffer, "diffuse_green", 13)) {
eOut = EST_DiffuseGreen;
} else if (DOM::TokenMatch(buffer, "diffuse_blue", 12)) {
eOut = EST_DiffuseBlue;
} else if (DOM::TokenMatch(buffer, "diffuse_alpha", 13)) {
eOut = EST_DiffuseAlpha;
} else if (DOM::TokenMatch(buffer, "specular_red", 12)) {
eOut = EST_SpecularRed;
} else if (DOM::TokenMatch(buffer, "specular_green", 14)) {
eOut = EST_SpecularGreen;
} else if (DOM::TokenMatch(buffer, "specular_blue", 13)) {
eOut = EST_SpecularBlue;
} else if (DOM::TokenMatch(buffer, "specular_alpha", 14)) {
eOut = EST_SpecularAlpha;
} else if (DOM::TokenMatch(buffer, "opacity", 7)) {
eOut = EST_Opacity;
} else if (DOM::TokenMatch(buffer, "specular_power", 14)) {
eOut = EST_PhongPower;
} else if (DOM::TokenMatch(buffer, "r", 1)) {
eOut = EST_Red;
} else if (DOM::TokenMatch(buffer, "g", 1)) {
eOut = EST_Green;
} else if (DOM::TokenMatch(buffer, "b", 1)) {
eOut = 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 if (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 = EST_UTextureCoord;
} else if (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 = EST_VTextureCoord;
} else if (DOM::TokenMatch(buffer, "x", 1)) {
eOut = EST_XCoord;
} else if (DOM::TokenMatch(buffer, "y", 1)) {
eOut = EST_YCoord;
} else if (DOM::TokenMatch(buffer, "z", 1)) {
eOut = EST_ZCoord;
} else if (DOM::TokenMatch(buffer, "nx", 2)) {
eOut = EST_XNormal;
} else if (DOM::TokenMatch(buffer, "ny", 2)) {
eOut = EST_YNormal;
} else if (DOM::TokenMatch(buffer, "nz", 2)) {
eOut = EST_ZNormal;
} else {
ASSIMP_LOG_INFO("Found unknown property semantic in file. This is ok");
PLY::DOM::SkipLine(buffer);
DOM::SkipLine(buffer);
}
return eOut;
}
@ -195,12 +194,12 @@ bool PLY::Property::ParseProperty(std::vector<char> &buffer, PLY::Property *pOut
// "property list uchar int vertex_index"
// skip leading spaces
if (!PLY::DOM::SkipSpaces(buffer)) {
if (!DOM::SkipSpaces(buffer)) {
return false;
}
// skip the "property" string at the beginning
if (!PLY::DOM::TokenMatch(buffer, "property", 8)) {
if (!DOM::TokenMatch(buffer, "property", 8)) {
// seems not to be a valid property entry
return false;
}
@ -301,7 +300,9 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
// the original string identifier
pOut->szName = std::string(&buffer[0], &buffer[0] + strlen(&buffer[0]));
auto pos = pOut->szName.find_last_of(' ');
pOut->szName.erase(pos, pOut->szName.size());
if (pos != std::string::npos) {
pOut->szName.erase(pos, pOut->szName.size());
}
}
if (!PLY::DOM::SkipSpaces(buffer))
@ -342,6 +343,7 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
return true;
}
// ------------------------------------------------------------------------------------------------
bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
@ -358,6 +360,7 @@ bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) {
return ret;
}
// ------------------------------------------------------------------------------------------------
bool PLY::DOM::SkipLine(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
@ -374,6 +377,7 @@ bool PLY::DOM::SkipLine(std::vector<char> &buffer) {
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;
@ -389,6 +393,7 @@ bool PLY::DOM::TokenMatch(std::vector<char> &buffer, const char *token, unsigned
return ret;
}
// ------------------------------------------------------------------------------------------------
bool PLY::DOM::SkipSpacesAndLineEnd(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
@ -405,6 +410,7 @@ bool PLY::DOM::SkipSpacesAndLineEnd(std::vector<char> &buffer) {
return ret;
}
// ------------------------------------------------------------------------------------------------
bool PLY::DOM::SkipComments(std::vector<char> buffer) {
ai_assert(!buffer.empty());
@ -827,14 +833,14 @@ bool PLY::PropertyInstance::ParseValue(const char *&pCur,
// 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);
pCur = fast_atoreal_move(pCur, f);
out->fFloat = (ai_real)f;
break;
case EDT_Double:
double d;
pCur = fast_atoreal_move<double>(pCur, d);
out->fDouble = (double)d;
pCur = fast_atoreal_move(pCur, d);
out->fDouble = d;
break;
case EDT_INVALID:
@ -847,12 +853,12 @@ bool PLY::PropertyInstance::ParseValue(const char *&pCur,
}
// ------------------------------------------------------------------------------------------------
bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
bool PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
std::vector<char> &buffer,
const char *&pCur,
unsigned int &bufferSize,
PLY::EDataType eType,
PLY::PropertyInstance::ValueUnion *out,
EDataType eType,
PropertyInstance::ValueUnion *out,
bool p_bBE) {
ai_assert(nullptr != out);
@ -990,6 +996,8 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
return ret;
}
// ------------------------------------------------------------------------------------------------
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2026, assimp team
All rights reserved.
@ -291,16 +291,13 @@ public:
// ---------------------------------------------------------------------------------
/** \brief Instance of a property in a PLY file
*/
class PropertyInstance
{
class PropertyInstance {
public:
//! Default constructor
PropertyInstance() AI_NO_EXCEPT = default;
union ValueUnion
{
//! uInt32 representation of the property. All
// uint types are automatically converted to uint32
uint32_t iUInt;
@ -351,9 +348,11 @@ public:
static TYPE ConvertTo(ValueUnion v, EDataType eType);
};
using PropertyInstVec = std::vector<PropertyInstance::ValueUnion>;
// ---------------------------------------------------------------------------------
/// @brief Class for an element instance in a PLY file
// ---------------------------------------------------------------------------------
/** \brief Class for an element instance in a PLY file
*/
class ElementInstance {
public:
//! Default constructor
@ -374,20 +373,18 @@ public:
};
// ---------------------------------------------------------------------------------
/** \brief Class for an element instance list in a PLY file
*/
class ElementInstanceList
{
/// @brief Class for an element instance list in a PLY file
// ---------------------------------------------------------------------------------
class ElementInstanceList {
public:
//! Default constructor
/// Default constructor
ElementInstanceList() AI_NO_EXCEPT = default;
//! List of all element instances
/// List of all element instances
std::vector< ElementInstance > alInstances;
// -------------------------------------------------------------------
//! Parse an element instance list
/// Parse an element instance list
static bool ParseInstanceList(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader);
@ -400,17 +397,15 @@ public:
/** \brief Class to represent the document object model of an ASCII or binary
* (both little and big-endian) PLY file
*/
class DOM
{
class DOM {
public:
//! Default constructor
/// Default constructor
DOM() AI_NO_EXCEPT = default;
//! Contains all elements of the file format
/// Contains all elements of the file format
std::vector<Element> alElements;
//! Contains the real data of each element's instance list
/// 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
@ -446,11 +441,8 @@ private:
// ---------------------------------------------------------------------------------
template <typename TYPE>
inline TYPE PLY::PropertyInstance::ConvertTo(
PLY::PropertyInstance::ValueUnion v, PLY::EDataType eType)
{
switch (eType)
{
inline TYPE PLY::PropertyInstance::ConvertTo(PLY::PropertyInstance::ValueUnion v, PLY::EDataType eType) {
switch (eType) {
case EDT_Float:
return (TYPE)v.fFloat;
case EDT_Double: