Compare commits
13 Commits
kimkulling
...
master
Author | SHA1 | Date |
---|---|---|
Pichas | f4c7606faf | |
Kim Kulling | 66187a77cf | |
PatrickD | 5c7acc968b | |
Lux | f81ea6986c | |
dataisland | ab12e8d8ba | |
dataisland | 3bd98611d7 | |
dataisland | d468e633b1 | |
Kim Kulling | 4024726eca | |
Kim Kulling | cd0ef869e3 | |
RichardTea | ed3fccd5db | |
Matthias Möller | ff2dc2fb2e | |
Tobias Rittig, Ph.D. | f69e55058d | |
RichardTea | c1ffbfec06 |
|
@ -643,11 +643,17 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
|||
}
|
||||
|
||||
// Allocate storage for children
|
||||
pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
|
||||
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
|
||||
|
||||
pcOut->mNumChildren = size;
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
pcOut->mChildren = new aiNode *[pcIn->mChildren.size()];
|
||||
|
||||
// Recursively process all children
|
||||
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
|
||||
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
pcOut->mChildren[i] = new aiNode();
|
||||
pcOut->mChildren[i]->mParent = pcOut;
|
||||
|
|
|
@ -372,10 +372,12 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
|
|||
}
|
||||
|
||||
// add children recursively
|
||||
if (!root.temp_children.empty()) {
|
||||
nd->mChildren = new aiNode *[root.temp_children.size()]();
|
||||
for (const Node *n : root.temp_children) {
|
||||
(nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd;
|
||||
}
|
||||
}
|
||||
|
||||
return nd;
|
||||
}
|
||||
|
|
|
@ -181,6 +181,8 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
|
|||
if (out->mNumMeshes == 0) {
|
||||
out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||
} else {
|
||||
// Apply the FBX axis metadata unless requested not to
|
||||
if (!doc.Settings().ignoreUpDirection)
|
||||
correctRootTransform(mSceneOut);
|
||||
}
|
||||
}
|
||||
|
@ -310,6 +312,8 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|||
|
||||
child->mParent = last_parent;
|
||||
last_parent = child.mNode;
|
||||
|
||||
new_abs_transform *= child->mTransformation;
|
||||
}
|
||||
|
||||
// attach geometry
|
||||
|
@ -332,6 +336,8 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|||
|
||||
postnode->mParent = last_parent;
|
||||
last_parent = postnode.mNode;
|
||||
|
||||
new_abs_transform *= postnode->mTransformation;
|
||||
}
|
||||
} else {
|
||||
// free the nodes we allocated as we don't need them
|
||||
|
@ -357,14 +363,14 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|||
if (nodes.empty()) {
|
||||
parent->mNumChildren = 0;
|
||||
parent->mChildren = nullptr;
|
||||
}
|
||||
|
||||
} else {
|
||||
parent->mChildren = new aiNode *[nodes.size()]();
|
||||
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
|
||||
for (unsigned int i = 0; i < nodes.size(); ++i) {
|
||||
parent->mChildren[i] = nodes[i].mOwnership.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertLights(const Model &model, const std::string &orig_name) {
|
||||
const std::vector<const NodeAttribute *> &node_attrs = model.GetAttributes();
|
||||
|
|
|
@ -156,6 +156,9 @@ struct ImportSettings {
|
|||
/** Set to true to perform a conversion from cm to meter after the import
|
||||
*/
|
||||
bool convertToMeters;
|
||||
|
||||
// Set to true to ignore the axis configuration in the file
|
||||
bool ignoreUpDirection = false;
|
||||
};
|
||||
|
||||
} // namespace FBX
|
||||
|
|
|
@ -117,6 +117,7 @@ void FBXImporter::SetupProperties(const Importer *pImp) {
|
|||
mSettings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
|
||||
mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
|
||||
mSettings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
|
||||
mSettings.ignoreUpDirection = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION, false);
|
||||
mSettings.useSkeleton = pImp->GetPropertyBool(AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,15 @@ static constexpr aiImporterDesc desc = {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursive parsing of LWS files
|
||||
void LWS::Element::Parse(const char *&buffer, const char *end) {
|
||||
namespace {
|
||||
constexpr int MAX_DEPTH = 1000; // Define the maximum depth allowed
|
||||
}
|
||||
|
||||
void LWS::Element::Parse(const char *&buffer, const char *end, int depth) {
|
||||
if (depth > MAX_DEPTH) {
|
||||
throw std::runtime_error("Maximum recursion depth exceeded in LWS::Element::Parse");
|
||||
}
|
||||
|
||||
for (; SkipSpacesAndLineEnd(&buffer, end); SkipLine(&buffer, end)) {
|
||||
|
||||
// begin of a new element with children
|
||||
|
@ -121,7 +129,7 @@ void LWS::Element::Parse(const char *&buffer, const char *end) {
|
|||
|
||||
// parse more elements recursively
|
||||
if (sub) {
|
||||
children.back().Parse(buffer, end);
|
||||
children.back().Parse(buffer, end, depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
std::list<Element> children;
|
||||
|
||||
//! Recursive parsing function
|
||||
void Parse(const char *&buffer, const char *end);
|
||||
void Parse(const char *&buffer, const char *end, int depth = 0);
|
||||
};
|
||||
|
||||
#define AI_LWS_MASK (0xffffffff >> 4u)
|
||||
|
|
|
@ -724,6 +724,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
std::vector<unsigned char> mBuffer2(fileSize);
|
||||
file->Read(&mBuffer2[0], 1, fileSize);
|
||||
mBuffer = &mBuffer2[0];
|
||||
const unsigned char* bufferEnd = mBuffer + fileSize;
|
||||
|
||||
pcHeader = (BE_NCONST MD3::Header *)mBuffer;
|
||||
|
||||
|
@ -749,9 +750,15 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
|
||||
// Navigate to the list of surfaces
|
||||
BE_NCONST MD3::Surface *pcSurfaces = (BE_NCONST MD3::Surface *)(mBuffer + pcHeader->OFS_SURFACES);
|
||||
if ((const unsigned char*)pcSurfaces + sizeof(MD3::Surface) * pcHeader->NUM_SURFACES > bufferEnd) {
|
||||
throw DeadlyImportError("MD3 surface headers are outside the file");
|
||||
}
|
||||
|
||||
// Navigate to the list of tags
|
||||
BE_NCONST MD3::Tag *pcTags = (BE_NCONST MD3::Tag *)(mBuffer + pcHeader->OFS_TAGS);
|
||||
if ((const unsigned char*)pcTags + sizeof(MD3::Tag) * pcHeader->NUM_TAGS > bufferEnd) {
|
||||
throw DeadlyImportError("MD3 tags are outside the file");
|
||||
}
|
||||
|
||||
// Allocate output storage
|
||||
pScene->mNumMeshes = pcHeader->NUM_SURFACES;
|
||||
|
@ -1026,6 +1033,10 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
|
||||
for (unsigned int i = 0; i < pcHeader->NUM_TAGS; ++i, ++pcTags) {
|
||||
aiNode *nd = pScene->mRootNode->mChildren[i] = new aiNode();
|
||||
if ((const unsigned char*)pcTags + sizeof(MD3::Tag) > bufferEnd) {
|
||||
throw DeadlyImportError("MD3 tag is outside the file");
|
||||
}
|
||||
|
||||
nd->mName.Set((const char *)pcTags->NAME);
|
||||
nd->mParent = pScene->mRootNode;
|
||||
|
||||
|
|
|
@ -48,10 +48,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/ByteSwapper.h>
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
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" };
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
PLY::EDataType PLY::Property::ParseDataType(std::vector<char> &buffer) {
|
||||
ai_assert(!buffer.empty());
|
||||
|
@ -281,6 +300,8 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
|
|||
// 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]));
|
||||
auto pos = pOut->szName.find_last_of(' ');
|
||||
pOut->szName.erase(pos, pOut->szName.size());
|
||||
}
|
||||
|
||||
if (!PLY::DOM::SkipSpaces(buffer))
|
||||
|
@ -413,6 +434,7 @@ bool PLY::DOM::SkipComments(std::vector<char> buffer) {
|
|||
bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, bool isBinary) {
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseHeader() begin");
|
||||
|
||||
std::unordered_set<std::string> definedAlElements;
|
||||
// parse all elements
|
||||
while (!buffer.empty()) {
|
||||
// skip all comments
|
||||
|
@ -421,6 +443,13 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char>
|
|||
PLY::Element out;
|
||||
if (PLY::Element::ParseElement(streamBuffer, buffer, &out)) {
|
||||
// add the element to the list of elements
|
||||
|
||||
const auto propertyName = (out.szName.empty()) ? to_string(out.eSemantic) : out.szName;
|
||||
auto alreadyDefined = definedAlElements.find(propertyName);
|
||||
if (alreadyDefined != definedAlElements.end()) {
|
||||
throw DeadlyImportError("Property '" + propertyName + "' in header already defined ");
|
||||
}
|
||||
definedAlElements.insert(propertyName);
|
||||
alElements.push_back(out);
|
||||
} else if (TokenMatch(buffer, "end_header", 10)) {
|
||||
// we have reached the end of the header
|
||||
|
|
|
@ -400,6 +400,10 @@ void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent) {
|
|||
}
|
||||
}
|
||||
|
||||
// nothing to do
|
||||
if (pcNode->mNumChildren == 0)
|
||||
return;
|
||||
|
||||
// now allocate the output array
|
||||
pcNode->mChildren = new aiNode *[pcNode->mNumChildren];
|
||||
|
||||
|
|
|
@ -1053,7 +1053,7 @@ ENDIF() # IF (ASSIMP_BUILD_USD_IMPORTER)
|
|||
IF(ASSIMP_HUNTER_ENABLED)
|
||||
hunter_add_package(pugixml)
|
||||
find_package(pugixml CONFIG REQUIRED)
|
||||
ELSE()
|
||||
ELSEIF(NOT TARGET pugixml::pugixml)
|
||||
SET( Pugixml_SRCS
|
||||
../contrib/pugixml/src/pugiconfig.hpp
|
||||
../contrib/pugixml/src/pugixml.hpp
|
||||
|
@ -1396,6 +1396,7 @@ IF (ASSIMP_WARNINGS_AS_ERRORS)
|
|||
-Wno-unused-template
|
||||
-Wno-undefined-func-template
|
||||
-Wno-declaration-after-statement
|
||||
-Wno-deprecated-declarations
|
||||
)
|
||||
ELSE()
|
||||
TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
|
||||
|
@ -1417,9 +1418,7 @@ TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
|
|||
IF(ASSIMP_HUNTER_ENABLED)
|
||||
TARGET_LINK_LIBRARIES(assimp
|
||||
PUBLIC
|
||||
#polyclipping::polyclipping
|
||||
openddlparser::openddl_parser
|
||||
#poly2tri::poly2tri
|
||||
minizip::minizip
|
||||
ZLIB::zlib
|
||||
RapidJSON::rapidjson
|
||||
|
@ -1439,6 +1438,9 @@ ELSE()
|
|||
if (ASSIMP_BUILD_DRACO)
|
||||
target_link_libraries(assimp ${draco_LIBRARIES})
|
||||
endif()
|
||||
if(TARGET pugixml::pugixml)
|
||||
target_link_libraries(assimp pugixml::pugixml)
|
||||
endif()
|
||||
ENDIF()
|
||||
|
||||
if(ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
|
|
|
@ -359,20 +359,25 @@ void CallbackToLogRedirector(const char *msg, char *dt) {
|
|||
s->write(msg);
|
||||
}
|
||||
|
||||
static LogStream *DefaultStream = nullptr;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream, const char *file) {
|
||||
aiLogStream sout;
|
||||
|
||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||
LogStream *stream = LogStream::createDefaultStream(pStream, file);
|
||||
if (!stream) {
|
||||
if (DefaultStream == nullptr) {
|
||||
DefaultStream = LogStream::createDefaultStream(pStream, file);
|
||||
}
|
||||
|
||||
if (!DefaultStream) {
|
||||
sout.callback = nullptr;
|
||||
sout.user = nullptr;
|
||||
} else {
|
||||
sout.callback = &CallbackToLogRedirector;
|
||||
sout.user = (char *)stream;
|
||||
sout.user = (char *)DefaultStream;
|
||||
}
|
||||
gPredefinedStreams.push_back(stream);
|
||||
gPredefinedStreams.push_back(DefaultStream);
|
||||
ASSIMP_END_EXCEPTION_REGION(aiLogStream);
|
||||
return sout;
|
||||
}
|
||||
|
|
|
@ -848,11 +848,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) {
|
|||
break;
|
||||
}
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
|
||||
#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
|
||||
continue;
|
||||
#endif // no validation
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
|
||||
// If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
|
||||
if (pimpl->bExtraVerbose) {
|
||||
ASSIMP_LOG_DEBUG("Verbose Import: re-validating data structures");
|
||||
|
@ -864,6 +860,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif // no validation
|
||||
#endif // ! DEBUG
|
||||
}
|
||||
pimpl->mProgressHandler->UpdatePostProcess( static_cast<int>(pimpl->mPostProcessingSteps.size()),
|
||||
|
@ -939,6 +936,7 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess
|
|||
profiler->EndRegion( "postprocess" );
|
||||
}
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
|
||||
// If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
|
||||
if ( pimpl->bExtraVerbose || requestValidation ) {
|
||||
ASSIMP_LOG_DEBUG( "Verbose Import: revalidating data structures" );
|
||||
|
@ -949,6 +947,7 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess
|
|||
ASSIMP_LOG_ERROR( "Verbose Import: failed to revalidate data structures" );
|
||||
}
|
||||
}
|
||||
#endif // no validation
|
||||
|
||||
// clear any data allocated by post-process steps
|
||||
pimpl->mPPShared->Clean();
|
||||
|
|
|
@ -65,37 +65,47 @@ void SortByPTypeProcess::SetupProperties(const Importer *pImp) {
|
|||
mConfigRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, 0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void clearMeshesInNode(aiNode *node) {
|
||||
delete[] node->mMeshes;
|
||||
node->mNumMeshes = 0;
|
||||
node->mMeshes = nullptr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Update changed meshes in all nodes
|
||||
void UpdateNodes(const std::vector<unsigned int> &replaceMeshIndex, aiNode *node) {
|
||||
ai_assert(node != nullptr);
|
||||
|
||||
if (node->mNumMeshes) {
|
||||
unsigned int newSize = 0;
|
||||
for (unsigned int m = 0; m < node->mNumMeshes; ++m) {
|
||||
unsigned int add = node->mMeshes[m] << 2;
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
if (UINT_MAX != replaceMeshIndex[add + i]) ++newSize;
|
||||
if (UINT_MAX != replaceMeshIndex[add + i]) {
|
||||
++newSize;
|
||||
}
|
||||
}
|
||||
if (!newSize) {
|
||||
delete[] node->mMeshes;
|
||||
node->mNumMeshes = 0;
|
||||
node->mMeshes = nullptr;
|
||||
} else {
|
||||
}
|
||||
if (newSize == 0) {
|
||||
clearMeshesInNode(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to reuse the old array if possible
|
||||
unsigned int *newMeshes = (newSize > node->mNumMeshes ? new unsigned int[newSize] : node->mMeshes);
|
||||
|
||||
for (unsigned int m = 0; m < node->mNumMeshes; ++m) {
|
||||
unsigned int add = node->mMeshes[m] << 2;
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
if (UINT_MAX != replaceMeshIndex[add + i])
|
||||
if (UINT_MAX != replaceMeshIndex[add + i]) {
|
||||
*newMeshes++ = replaceMeshIndex[add + i];
|
||||
}
|
||||
}
|
||||
if (newSize > node->mNumMeshes)
|
||||
delete[] node->mMeshes;
|
||||
|
||||
node->mMeshes = newMeshes - (node->mNumMeshes = newSize);
|
||||
}
|
||||
if (newSize > node->mNumMeshes) {
|
||||
clearMeshesInNode(node);
|
||||
}
|
||||
node->mMeshes = newMeshes - (node->mNumMeshes = newSize);
|
||||
}
|
||||
|
||||
// call all subnodes recursively
|
||||
|
@ -167,6 +177,10 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
|
|||
// with the largest number of primitives
|
||||
unsigned int aiNumPerPType[4] = { 0, 0, 0, 0 };
|
||||
aiFace *pFirstFace = mesh->mFaces;
|
||||
if (pFirstFace == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aiFace *const pLastFace = pFirstFace + mesh->mNumFaces;
|
||||
|
||||
unsigned int numPolyVerts = 0;
|
||||
|
|
|
@ -891,6 +891,9 @@ void ValidateDSProcess::Validate(const aiNode *pNode) {
|
|||
ReportError("aiNode \"%s\" child %i \"%s\" parent is someone else: \"%s\"", pNode->mName.C_Str(), i, pChild->mName.C_Str(), parentName);
|
||||
}
|
||||
}
|
||||
} else if (pNode->mChildren) {
|
||||
ReportError("aiNode::mChildren is not nullptr for empty node %s (aiNode::mNumChildren is %i)",
|
||||
nodeName, pNode->mNumChildren);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4273)
|
||||
# define P2T_COMPILER_DLLEXPORT __declspec(dllexport)
|
||||
# define P2T_COMPILER_DLLIMPORT __declspec(dllimport)
|
||||
|
|
|
@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
using namespace Assimp;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) {
|
||||
aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
|
||||
aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, nullptr);
|
||||
aiAttachLogStream(&stream);
|
||||
|
||||
Importer importer;
|
||||
|
|
|
@ -676,6 +676,19 @@ enum aiComponent
|
|||
#define AI_CONFIG_FBX_CONVERT_TO_M \
|
||||
"AI_CONFIG_FBX_CONVERT_TO_M"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief Set whether the FBX importer shall ignore the provided axis configuration
|
||||
*
|
||||
* If this property is set to true, the axis directions provided in the FBX file
|
||||
* will be ignored and the file will be loaded as is.
|
||||
*
|
||||
* Set to true for Assimp 5.3.x and earlier behavior
|
||||
* Equivalent to AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION
|
||||
* Property type: Bool. Default value: false.
|
||||
*/
|
||||
#define AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION \
|
||||
"AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief Will enable the skeleton struct to store bone data.
|
||||
*
|
||||
|
|
|
@ -55,8 +55,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/config.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/* Define ASSIMP_BUILD_NO_XX_IMPORTER to disable a specific
|
||||
* file format loader. The loader is be excluded from the
|
||||
/**
|
||||
* @brief Define ASSIMP_BUILD_NO_XX_IMPORTER to disable a specific file format loader.
|
||||
*
|
||||
* The loader is be excluded from the
|
||||
* build in this case. 'XX' stands for the most common file
|
||||
* extension of the file format. E.g.:
|
||||
* ASSIMP_BUILD_NO_X_IMPORTER disables the X loader.
|
||||
|
@ -93,17 +95,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# define ASSIMP_BUILD_NEED_UNZIP
|
||||
#endif
|
||||
|
||||
// We need those constants, workaround for any platforms where nobody defined them yet
|
||||
/**
|
||||
* @brief We need those constants, workaround for any platforms where nobody defined them yet.
|
||||
*/
|
||||
#if (!defined SIZE_MAX)
|
||||
# define SIZE_MAX (~((size_t)0))
|
||||
#endif
|
||||
|
||||
/*#if (!defined UINT_MAX)
|
||||
#define UINT_MAX (~((unsigned int)0))
|
||||
#endif*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/* Define ASSIMP_BUILD_NO_XX_PROCESS to disable a specific
|
||||
/** @brief Define ASSIMP_BUILD_NO_XX_PROCESS to disable a specific
|
||||
*
|
||||
* post processing step. This is the current list of process names ('XX'):
|
||||
* CALCTANGENTS
|
||||
* JOINVERTICES
|
||||
|
@ -134,22 +135,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
* OPTIMIZEGRAPH
|
||||
* GENENTITYMESHES
|
||||
* FIXTEXTUREPATHS
|
||||
* GENBOUNDINGBOXES */
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
* GENBOUNDINGBOXES
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/** @brief Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library
|
||||
*
|
||||
* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in
|
||||
* an external DLL under Windows. Default is static linkage.
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#ifdef _WIN32
|
||||
# undef ASSIMP_API
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/* Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library */
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
# ifdef ASSIMP_BUILD_DLL_EXPORT
|
||||
# define ASSIMP_API __declspec(dllexport)
|
||||
# define ASSIMP_API_WINONLY __declspec(dllexport)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in
|
||||
* an external DLL under Windows. Default is static linkage. */
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
# elif (defined ASSIMP_DLL)
|
||||
# define ASSIMP_API __declspec(dllimport)
|
||||
# define ASSIMP_API_WINONLY __declspec(dllimport)
|
||||
|
@ -157,23 +157,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# define ASSIMP_API
|
||||
# define ASSIMP_API_WINONLY
|
||||
# endif
|
||||
#elif defined(SWIG)
|
||||
/* Do nothing, the relevant defines are all in AssimpSwigPort.i */
|
||||
#else
|
||||
# define ASSIMP_API __attribute__((visibility("default")))
|
||||
# define ASSIMP_API_WINONLY
|
||||
#endif // _WIN32
|
||||
|
||||
/**
|
||||
* @brief Helper macros
|
||||
*
|
||||
* @def AI_FORCE_INLINE
|
||||
* @brief Force the compiler to inline a function, if possible
|
||||
*
|
||||
* @def AI_WONT_RETURN
|
||||
* @brief Tells the compiler that a function never returns.
|
||||
*
|
||||
* Used in code analysis to skip dead paths (e.g. after an assertion evaluated to false).
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4521 4512 4714 4127 4351 4510)
|
||||
#ifdef ASSIMP_BUILD_DLL_EXPORT
|
||||
#pragma warning(disable : 4251)
|
||||
#endif
|
||||
/* Force the compiler to inline a function, if possible */
|
||||
#define AI_FORCE_INLINE inline
|
||||
|
||||
/* Tells the compiler that a function never returns. Used in code analysis
|
||||
* to skip dead paths (e.g. after an assertion evaluated to false). */
|
||||
#define AI_WONT_RETURN __declspec(noreturn)
|
||||
#elif defined(SWIG)
|
||||
/* Do nothing, the relevant defines are all in AssimpSwigPort.i */
|
||||
|
@ -236,9 +241,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/* Define ASSIMP_BUILD_SINGLETHREADED to compile assimp
|
||||
/**
|
||||
* Define ASSIMP_BUILD_SINGLETHREADED to compile assimp
|
||||
* without threading support. The library doesn't utilize
|
||||
* threads then and is itself not threadsafe. */
|
||||
* threads then and is itself not threadsafe.
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||
# define ASSIMP_BUILD_SINGLETHREADED
|
||||
|
@ -294,7 +301,11 @@ constexpr ai_real ai_epsilon = (ai_real) 1e-6;
|
|||
# define ai_epsilon ((ai_real)1e-6)
|
||||
#endif
|
||||
|
||||
/* Support for big-endian builds */
|
||||
/**
|
||||
* @brief Support for big-endian builds
|
||||
*
|
||||
* This will check which byte ordering is used on the target architecture.
|
||||
*/
|
||||
#if defined(__BYTE_ORDER__)
|
||||
# if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
# if !defined(__BIG_ENDIAN__)
|
||||
|
@ -311,7 +322,8 @@ constexpr ai_real ai_epsilon = (ai_real) 1e-6;
|
|||
#endif
|
||||
|
||||
/**
|
||||
* To avoid running out of memory
|
||||
* @brief To avoid running out of memory
|
||||
*
|
||||
* This can be adjusted for specific use cases
|
||||
* It's NOT a total limit, just a limit for individual allocations
|
||||
*/
|
||||
|
@ -332,7 +344,7 @@ constexpr ai_real ai_epsilon = (ai_real) 1e-6;
|
|||
#endif // _MSC_VER
|
||||
|
||||
/**
|
||||
* Helper macro to set a pointer to NULL in debug builds
|
||||
* @brief Helper macro to set a pointer to NULL in debug builds
|
||||
*/
|
||||
#if (defined ASSIMP_BUILD_DEBUG)
|
||||
# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
|
||||
|
@ -342,4 +354,18 @@ constexpr ai_real ai_epsilon = (ai_real) 1e-6;
|
|||
|
||||
#define AI_COUNT_OF(X) (sizeof(X) / sizeof((X)[0]))
|
||||
|
||||
/**
|
||||
* @brief Will mark functions or classes as deprecated.
|
||||
*
|
||||
* Deprecation means that we will remove this function, class or methods in the next m
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# define AI_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
# define AI_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
# pragma message("WARNING: You need to implement DEPRECATED for this compiler")
|
||||
# define AI_DEPRECATED
|
||||
#endif
|
||||
|
||||
#endif // !! AI_DEFINES_H_INC
|
||||
|
|
|
@ -701,7 +701,7 @@ struct aiMaterialProperty {
|
|||
* Material data is stored using a key-value structure. A single key-value
|
||||
* pair is called a 'material property'. C++ users should use the provided
|
||||
* member functions of aiMaterial to process material properties, C users
|
||||
* have to stick with the aiMaterialGetXXX family of unbound functions.
|
||||
* have to stick with the aiGetMaterialXXX family of unbound functions.
|
||||
* The library defines a set of standard keys (AI_MATKEY_XXX).
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -100,6 +100,7 @@ SET( COMMON
|
|||
unit/Common/utBase64.cpp
|
||||
unit/Common/utHash.cpp
|
||||
unit/Common/utBaseProcess.cpp
|
||||
unit/Common/utLogger.cpp
|
||||
)
|
||||
|
||||
SET(Geometry
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, 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.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "UnitTestPCH.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
|
||||
using namespace Assimp;
|
||||
class utLogger : public ::testing::Test {};
|
||||
|
||||
TEST_F(utLogger, aiGetPredefinedLogStream_leak_test) {
|
||||
aiLogStream stream1 = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, nullptr);
|
||||
aiLogStream stream2 = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, nullptr);
|
||||
ASSERT_EQ(stream1.callback, stream2.callback);
|
||||
}
|
|
@ -311,6 +311,37 @@ TEST_F(utFBXImporterExporter, sceneMetadata) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_F(utFBXImporterExporter, importCustomAxes) {
|
||||
// see https://github.com/assimp/assimp/issues/5494
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/embedded_ascii/box.FBX", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
|
||||
// The ASCII box has customised the Up and Forward axes, verify that the RootNode transform has applied it
|
||||
ASSERT_FALSE(scene->mRootNode->mTransformation.IsIdentity()) << "Did not apply the custom axis transform";
|
||||
|
||||
aiVector3D upVec{ 0, 0, 1 }; // Up is +Z
|
||||
aiVector3D forwardVec{ 0, -1, 0 }; // Forward is -Y
|
||||
aiVector3D rightVec{ 1, 0, 0 }; // Right is +X
|
||||
aiMatrix4x4 mat(rightVec.x, rightVec.y, rightVec.z, 0.0f,
|
||||
upVec.x, upVec.y, upVec.z, 0.0f,
|
||||
forwardVec.x, forwardVec.y, forwardVec.z, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
EXPECT_EQ(mat, scene->mRootNode->mTransformation);
|
||||
}
|
||||
|
||||
TEST_F(utFBXImporterExporter, importIgnoreCustomAxes) {
|
||||
// see https://github.com/assimp/assimp/issues/5494
|
||||
Assimp::Importer importer;
|
||||
importer.SetPropertyBool(AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION, true);
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/embedded_ascii/box.FBX", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
|
||||
// Verify that the RootNode transform has NOT applied the custom axes
|
||||
EXPECT_TRUE(scene->mRootNode->mTransformation.IsIdentity());
|
||||
}
|
||||
|
||||
TEST_F(utFBXImporterExporter, importCubesWithOutOfRangeFloat) {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_with_outofrange_float.fbx", aiProcess_ValidateDataStructure);
|
||||
|
|
|
@ -209,3 +209,55 @@ TEST_F(utPLYImportExport, payload_JVN42386607) {
|
|||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/payload_JVN42386607", 0);
|
||||
EXPECT_EQ(nullptr, scene);
|
||||
}
|
||||
|
||||
// Tests Issue #5729. Test, if properties defined multiple times. Unclear what to do, better to abort than to crash entirely
|
||||
TEST_F(utPLYImportExport, parseInvalidDoubleProperty) {
|
||||
const char data[] = "ply\n"
|
||||
"format ascii 1.0\n"
|
||||
"element vertex 4\n"
|
||||
"property float x\n"
|
||||
"property float y\n"
|
||||
"property float z\n"
|
||||
"element vertex 8\n"
|
||||
"property float x\n"
|
||||
"property float y\n"
|
||||
"property float z\n"
|
||||
"end_header\n"
|
||||
"0.0 0.0 0.0 0.0 0.0 0.0\n"
|
||||
"0.0 0.0 1.0 0.0 0.0 1.0\n"
|
||||
"0.0 1.0 0.0 0.0 1.0 0.0\n"
|
||||
"0.0 0.0 1.0\n"
|
||||
"0.0 1.0 0.0 0.0 0.0 1.0\n"
|
||||
"0.0 1.0 1.0 0.0 1.0 1.0\n";
|
||||
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFileFromMemory(data, sizeof(data), 0);
|
||||
EXPECT_EQ(nullptr, scene);
|
||||
}
|
||||
|
||||
// Tests Issue #5729. Test, if properties defined multiple times. Unclear what to do, better to abort than to crash entirely
|
||||
TEST_F(utPLYImportExport, parseInvalidDoubleCustomProperty) {
|
||||
const char data[] = "ply\n"
|
||||
"format ascii 1.0\n"
|
||||
"element vertex 4\n"
|
||||
"property float x\n"
|
||||
"property float y\n"
|
||||
"property float z\n"
|
||||
"element name 8\n"
|
||||
"property float x\n"
|
||||
"element name 5\n"
|
||||
"property float x\n"
|
||||
"end_header\n"
|
||||
"0.0 0.0 0.0 100.0 10.0\n"
|
||||
"0.0 0.0 1.0 200.0 20.0\n"
|
||||
"0.0 1.0 0.0 300.0 30.0\n"
|
||||
"0.0 1.0 1.0 400.0 40.0\n"
|
||||
"0.0 0.0 0.0 500.0 50.0\n"
|
||||
"0.0 0.0 1.0 600.0 60.0\n"
|
||||
"0.0 1.0 0.0 700.0 70.0\n"
|
||||
"0.0 1.0 1.0 800.0 80.0\n";
|
||||
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFileFromMemory(data, sizeof(data), 0);
|
||||
EXPECT_EQ(nullptr, scene);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue