diff --git a/CMakeLists.txt b/CMakeLists.txt index 97a3641f5..7027e3300 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -527,12 +527,12 @@ ENDIF() MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER ) SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL - "Build the C4D importer, which relies on the non-free Melange SDK." + "Build the C4D importer, which relies on the non-free Cineware SDK." ) IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER) IF ( MSVC ) - SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/includes") + SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/includes") # pick the correct prebuilt library IF(MSVC15) @@ -551,22 +551,23 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER) ) ENDIF() - SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/libraries/win") + SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/libraries/win") SET(C4D_DEBUG_LIBRARIES - "${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_debug.lib" + "${C4D_LIB_BASE_PATH}/cinewarelib${C4D_LIB_POSTFIX}/cinewarelib_debug.lib" "${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_debug.lib" ) SET(C4D_RELEASE_LIBRARIES - "${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_release.lib" + "${C4D_LIB_BASE_PATH}/cinewarelib${C4D_LIB_POSTFIX}/cinewarelib_release.lib" "${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_release.lib" ) - # winsock and winmm are necessary dependencies of melange (this is undocumented, but true.) + # winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because + # it can be used to communicate with a running Cinema 4D instance SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib) ELSE () MESSAGE( FATAL_ERROR - "C4D is currently only available on Windows with melange SDK installed in contrib/Melange" + "C4D is currently only available on Windows with Cineware SDK installed in contrib/Cineware" ) ENDIF () ELSE () diff --git a/Readme.md b/Readme.md index 81fd9fd9d..f2ea4b094 100644 --- a/Readme.md +++ b/Readme.md @@ -66,9 +66,9 @@ Open Asset Import Library is implemented in C++. The directory structure looks l The source code is organized in the following way: - code/Common The base implementation for importers and the infrastructure - code/PostProcessing The post-processing steps - code/ Implementation for import and export for the format + code/Common The base implementation for importers and the infrastructure + code/PostProcessing The post-processing steps + code/AssetLib/ Implementation for import and export for the format ### Where to get help ### For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format. diff --git a/code/AssetLib/3DS/3DSConverter.cpp b/code/AssetLib/3DS/3DSConverter.cpp index 12ac7e69e..aca16b0d6 100644 --- a/code/AssetLib/3DS/3DSConverter.cpp +++ b/code/AssetLib/3DS/3DSConverter.cpp @@ -69,7 +69,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() { for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) { std::string s = mScene->mMaterials[i].mName; for (std::string::iterator it = s.begin(); it != s.end(); ++it) { - *it = static_cast(::tolower(*it)); + *it = static_cast(::tolower(static_cast(*it))); } if (std::string::npos == s.find("default")) continue; @@ -212,7 +212,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat, mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE); // Be sure this is only done for the first material - mBackgroundImage = std::string(""); + mBackgroundImage = std::string(); } // At first add the base ambient color of the scene to the material diff --git a/code/AssetLib/3DS/3DSExporter.cpp b/code/AssetLib/3DS/3DSExporter.cpp index 108d917d1..92a6d5aa7 100644 --- a/code/AssetLib/3DS/3DSExporter.cpp +++ b/code/AssetLib/3DS/3DSExporter.cpp @@ -102,13 +102,14 @@ private: // preserves the mesh's given name if it has one. |index| is the index // of the mesh in |aiScene::mMeshes|. std::string GetMeshName(const aiMesh &mesh, unsigned int index, const aiNode &node) { - static const std::string underscore = "_"; + static const char underscore = '_'; char postfix[10] = { 0 }; ASSIMP_itoa10(postfix, index); std::string result = node.mName.C_Str(); if (mesh.mName.length > 0) { - result += underscore + mesh.mName.C_Str(); + result += underscore; + result += mesh.mName.C_Str(); } return result + underscore + postfix; } @@ -378,7 +379,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type // TODO: handle embedded textures properly if (path.data[0] == '*') { - ASSIMP_LOG_ERROR("Ignoring embedded texture for export: " + std::string(path.C_Str())); + ASSIMP_LOG_ERROR("Ignoring embedded texture for export: ", path.C_Str()); return; } diff --git a/code/AssetLib/3DS/3DSHelper.h b/code/AssetLib/3DS/3DSHelper.h index f3f9efb25..1930c0c40 100644 --- a/code/AssetLib/3DS/3DSHelper.h +++ b/code/AssetLib/3DS/3DSHelper.h @@ -61,20 +61,10 @@ namespace D3DS { #include // --------------------------------------------------------------------------- -/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks -* and data structures. +/** Defines chunks and data structures. */ -class Discreet3DS { -private: - Discreet3DS() AI_NO_EXCEPT { - // empty - } +namespace Discreet3DS { - ~Discreet3DS() { - // empty - } - -public: //! data structure for a single chunk in a .3ds file struct Chunk { uint16_t Flag; @@ -314,7 +304,7 @@ public: // camera sub-chunks CHUNK_CAM_RANGES = 0x4720 }; -}; +} // --------------------------------------------------------------------------- /** Helper structure representing a 3ds mesh face */ diff --git a/code/AssetLib/3DS/3DSLoader.cpp b/code/AssetLib/3DS/3DSLoader.cpp index 0a64f6870..b5e6f749b 100644 --- a/code/AssetLib/3DS/3DSLoader.cpp +++ b/code/AssetLib/3DS/3DSLoader.cpp @@ -143,7 +143,13 @@ void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) { // Imports the given file into the given scene structure. void Discreet3DSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { - StreamReaderLE theStream(pIOHandler->Open(pFile, "rb")); + + auto theFile = pIOHandler->Open(pFile, "rb"); + if (!theFile) { + throw DeadlyImportError("3DS: Could not open ", pFile); + } + + StreamReaderLE theStream(theFile); // We should have at least one chunk if (theStream.GetRemainingSize() < 16) { @@ -164,7 +170,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile, mRootNode->mHierarchyIndex = -1; mRootNode->mParent = nullptr; mMasterScale = 1.0f; - mBackgroundImage = ""; + mBackgroundImage = std::string(); bHasBG = false; bIsPrj = false; @@ -299,7 +305,7 @@ void Discreet3DSImporter::ParseEditorChunk() { // print the version number char buff[10]; ASSIMP_itoa10(buff, stream->GetI2()); - ASSIMP_LOG_INFO_F(std::string("3DS file format version: "), buff); + ASSIMP_LOG_INFO("3DS file format version: ", buff); } break; }; ASSIMP_3DS_END_CHUNK(); @@ -928,7 +934,7 @@ void Discreet3DSImporter::ParseFaceChunk() { } } if (0xcdcdcdcd == idx) { - ASSIMP_LOG_ERROR_F("3DS: Unknown material: ", sz); + ASSIMP_LOG_ERROR("3DS: Unknown material: ", sz); } // Now continue and read all material indices @@ -981,9 +987,9 @@ void Discreet3DSImporter::ParseMeshChunk() { mMesh.mMat.a3 = stream->GetF4(); mMesh.mMat.b3 = stream->GetF4(); mMesh.mMat.c3 = stream->GetF4(); - mMesh.mMat.d1 = stream->GetF4(); - mMesh.mMat.d2 = stream->GetF4(); - mMesh.mMat.d3 = stream->GetF4(); + mMesh.mMat.a4 = stream->GetF4(); + mMesh.mMat.b4 = stream->GetF4(); + mMesh.mMat.c4 = stream->GetF4(); } break; case Discreet3DS::CHUNK_MAPLIST: { diff --git a/code/AssetLib/3MF/3MFXmlTags.h b/code/AssetLib/3MF/3MFXmlTags.h index 3996c60e5..d447556d6 100644 --- a/code/AssetLib/3MF/3MFXmlTags.h +++ b/code/AssetLib/3MF/3MFXmlTags.h @@ -44,63 +44,66 @@ namespace Assimp { namespace D3MF { namespace XmlTag { + // Root tag + const char* const RootTag = "3MF"; + // Meta-data - static const std::string meta = "metadata"; - static const std::string meta_name = "name"; + const char* const meta = "metadata"; + const char* const meta_name = "name"; // Model-data specific tags - static const std::string model = "model"; - static const std::string model_unit = "unit"; - static const std::string metadata = "metadata"; - static const std::string resources = "resources"; - static const std::string object = "object"; - static const std::string mesh = "mesh"; - static const std::string components = "components"; - static const std::string component = "component"; - static const std::string vertices = "vertices"; - static const std::string vertex = "vertex"; - static const std::string triangles = "triangles"; - static const std::string triangle = "triangle"; - static const std::string x = "x"; - static const std::string y = "y"; - static const std::string z = "z"; - static const std::string v1 = "v1"; - static const std::string v2 = "v2"; - static const std::string v3 = "v3"; - static const std::string id = "id"; - static const std::string pid = "pid"; - static const std::string pindex = "pindex"; - static const std::string p1 = "p1"; - static const std::string name = "name"; - static const std::string type = "type"; - static const std::string build = "build"; - static const std::string item = "item"; - static const std::string objectid = "objectid"; - static const std::string transform = "transform"; + const char* const model = "model"; + const char* const model_unit = "unit"; + const char* const metadata = "metadata"; + const char* const resources = "resources"; + const char* const object = "object"; + const char* const mesh = "mesh"; + const char* const components = "components"; + const char* const component = "component"; + const char* const vertices = "vertices"; + const char* const vertex = "vertex"; + const char* const triangles = "triangles"; + const char* const triangle = "triangle"; + const char* const x = "x"; + const char* const y = "y"; + const char* const z = "z"; + const char* const v1 = "v1"; + const char* const v2 = "v2"; + const char* const v3 = "v3"; + const char* const id = "id"; + const char* const pid = "pid"; + const char* const pindex = "pindex"; + const char* const p1 = "p1"; + const char* const name = "name"; + const char* const type = "type"; + const char* const build = "build"; + const char* const item = "item"; + const char* const objectid = "objectid"; + const char* const transform = "transform"; // Material definitions - static const std::string basematerials = "basematerials"; - static const std::string basematerials_id = "id"; - static const std::string basematerials_base = "base"; - static const std::string basematerials_name = "name"; - static const std::string basematerials_displaycolor = "displaycolor"; + const char* const basematerials = "basematerials"; + const char* const basematerials_id = "id"; + const char* const basematerials_base = "base"; + const char* const basematerials_name = "name"; + const char* const basematerials_displaycolor = "displaycolor"; // Meta info tags - static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml"; - static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels"; - static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types"; - static const std::string SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships"; - static const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships"; - static const std::string RELS_RELATIONSHIP_NODE = "Relationship"; - static const std::string RELS_ATTRIB_TARGET = "Target"; - static const std::string RELS_ATTRIB_TYPE = "Type"; - static const std::string RELS_ATTRIB_ID = "Id"; - static const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel"; - static const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket"; - static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"; - static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; - static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"; -} + const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml"; + const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels"; + const char* const SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types"; + const char* const SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships"; + const char* const RELS_RELATIONSHIP_CONTAINER = "Relationships"; + const char* const RELS_RELATIONSHIP_NODE = "Relationship"; + const char* const RELS_ATTRIB_TARGET = "Target"; + const char* const RELS_ATTRIB_TYPE = "Type"; + const char* const RELS_ATTRIB_ID = "Id"; + const char* const PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel"; + const char* const PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket"; + const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"; + const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; + const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"; + } } // Namespace D3MF } // Namespace Assimp diff --git a/code/AssetLib/3MF/D3MFExporter.cpp b/code/AssetLib/3MF/D3MFExporter.cpp index 4a16a0ad3..76a601cbe 100644 --- a/code/AssetLib/3MF/D3MFExporter.cpp +++ b/code/AssetLib/3MF/D3MFExporter.cpp @@ -307,18 +307,26 @@ void D3MFExporter::writeMesh(aiMesh *mesh) { return; } - mModelOutput << "<" << XmlTag::mesh << ">" << std::endl; - mModelOutput << "<" << XmlTag::vertices << ">" << std::endl; + mModelOutput << "<" + << XmlTag::mesh + << ">" << "\n"; + mModelOutput << "<" + << XmlTag::vertices + << ">" << "\n"; for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { writeVertex(mesh->mVertices[i]); } - mModelOutput << "" << std::endl; + mModelOutput << "" + << "\n"; const unsigned int matIdx(mesh->mMaterialIndex); writeFaces(mesh, matIdx); - mModelOutput << "" << std::endl; + mModelOutput << "" + << "\n"; } void D3MFExporter::writeVertex(const aiVector3D &pos) { @@ -334,27 +342,34 @@ void D3MFExporter::writeFaces(aiMesh *mesh, unsigned int matIdx) { if (!mesh->HasFaces()) { return; } - mModelOutput << "<" << XmlTag::triangles << ">" << std::endl; + mModelOutput << "<" + << XmlTag::triangles << ">" + << "\n"; for (unsigned int i = 0; i < mesh->mNumFaces; ++i) { aiFace ¤tFace = mesh->mFaces[i]; mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[0] << "\" v2=\"" << currentFace.mIndices[1] << "\" v3=\"" << currentFace.mIndices[2] << "\" pid=\"1\" p1=\"" + ai_to_string(matIdx) + "\" />"; - mModelOutput << std::endl; + mModelOutput << "\n"; } - mModelOutput << ""; - mModelOutput << std::endl; + mModelOutput << ""; + mModelOutput << "\n"; } void D3MFExporter::writeBuild() { - mModelOutput << "<" << XmlTag::build << ">" << std::endl; + mModelOutput << "<" + << XmlTag::build + << ">" + << "\n"; for (size_t i = 0; i < mBuildItems.size(); ++i) { mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 2 << "\"/>"; - mModelOutput << std::endl; + mModelOutput << "\n"; } mModelOutput << ""; - mModelOutput << std::endl; + mModelOutput << "\n"; } void D3MFExporter::zipContentType(const std::string &filename) { diff --git a/code/AssetLib/3MF/D3MFImporter.cpp b/code/AssetLib/3MF/D3MFImporter.cpp index f4ddb6054..747af7cfc 100644 --- a/code/AssetLib/3MF/D3MFImporter.cpp +++ b/code/AssetLib/3MF/D3MFImporter.cpp @@ -42,6 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_3MF_IMPORTER #include "D3MFImporter.h" +#include "3MFXmlTags.h" +#include "D3MFOpcPackage.h" #include #include @@ -51,17 +53,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include + #include #include #include #include #include - -#include "3MFXmlTags.h" -#include "D3MFOpcPackage.h" -#include - #include +#include namespace Assimp { namespace D3MF { @@ -72,32 +72,39 @@ enum class ResourceType { RT_Unknown }; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...) -class Resource -{ +class Resource { public: - Resource(int id) : - mId(id) {} - - virtual ~Resource() {} - int mId; - virtual ResourceType getType() { + Resource(int id) : + mId(id) { + // empty + } + + virtual ~Resource() { + // empty + } + + virtual ResourceType getType() const { return ResourceType::RT_Unknown; } }; class BaseMaterials : public Resource { public: - BaseMaterials(int id) : - Resource(id), - mMaterials(), - mMaterialIndex() {} - std::vector mMaterials; std::vector mMaterialIndex; - virtual ResourceType getType() { + BaseMaterials(int id) : + Resource(id), + mMaterials(), + mMaterialIndex() { + // empty + } + + ~BaseMaterials() = default; + + ResourceType getType() const override { return ResourceType::RT_BaseMaterials; } }; @@ -109,24 +116,26 @@ struct Component { class Object : public Resource { public: - std::vector mMeshes; + std::vector mMeshes; std::vector mMeshIndex; std::vector mComponents; std::string mName; Object(int id) : Resource(id), - mName(std::string("Object_") + ai_to_string(id)) {} + mName(std::string("Object_") + ai_to_string(id)) { + // empty + } - virtual ResourceType getType() { + ~Object() = default; + + ResourceType getType() const override { return ResourceType::RT_Object; } }; - class XmlSerializer { public: - XmlSerializer(XmlParser *xmlParser) : mResourcesDictionnary(), mMaterialCount(0), @@ -136,7 +145,7 @@ public: } ~XmlSerializer() { - for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) { + for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it ) { delete it->second; } } @@ -146,28 +155,28 @@ public: return; } - scene->mRootNode = new aiNode("3MF"); + scene->mRootNode = new aiNode(XmlTag::RootTag); - XmlNode node = mXmlParser->getRootNode().child("model"); + XmlNode node = mXmlParser->getRootNode().child(XmlTag::model); if (node.empty()) { return; } - XmlNode resNode = node.child("resources"); - for (XmlNode currentNode = resNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string ¤tNodeName = currentNode.name(); - if (currentNodeName == D3MF::XmlTag::object) { - ReadObject(currentNode);; - } else if (currentNodeName == D3MF::XmlTag::basematerials) { + XmlNode resNode = node.child(XmlTag::resources); + for (auto ¤tNode : resNode.children()) { + const std::string currentNodeName = currentNode.name(); + if (currentNodeName == XmlTag::object) { + ReadObject(currentNode); + } else if (currentNodeName == XmlTag::basematerials) { ReadBaseMaterials(currentNode); - } else if (currentNodeName == D3MF::XmlTag::meta) { + } else if (currentNodeName == XmlTag::meta) { ReadMetadata(currentNode); } } - XmlNode buildNode = node.child("build"); - for (XmlNode currentNode = buildNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string ¤tNodeName = currentNode.name(); - if (currentNodeName == D3MF::XmlTag::item) { + XmlNode buildNode = node.child(XmlTag::build); + for (auto ¤tNode : buildNode.children()) { + const std::string currentNodeName = currentNode.name(); + if (currentNodeName == XmlTag::item) { int objectId = -1; std::string transformationMatrixStr; aiMatrix4x4 transformationMatrix; @@ -186,10 +195,9 @@ public: } } - // import the metadata if (!mMetaData.empty()) { - const size_t numMeta(mMetaData.size()); + const size_t numMeta = mMetaData.size(); scene->mMetaData = aiMetadata::Alloc(static_cast(numMeta)); for (size_t i = 0; i < numMeta; ++i) { aiString val(mMetaData[i].value); @@ -201,22 +209,22 @@ public: scene->mNumMeshes = static_cast(mMeshCount); if (scene->mNumMeshes != 0) { scene->mMeshes = new aiMesh *[scene->mNumMeshes](); - for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) { + for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) { if (it->second->getType() == ResourceType::RT_Object) { - Object *obj = static_cast(it->second); + Object *obj = static_cast(it->second); + ai_assert(nullptr != obj); for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) { scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i]; } } } } - // import the materials - scene->mNumMaterials = static_cast(mMaterialCount); + scene->mNumMaterials = mMaterialCount; if (scene->mNumMaterials != 0) { scene->mMaterials = new aiMaterial *[scene->mNumMaterials]; - for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) { + for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) { if (it->second->getType() == ResourceType::RT_BaseMaterials) { BaseMaterials *baseMaterials = static_cast(it->second); for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) { @@ -228,35 +236,36 @@ public: } private: + void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) { + ai_assert(nullptr != obj); - void addObjectToNode(aiNode* parent, Object* obj, aiMatrix4x4 nodeTransform) { aiNode *sceneNode = new aiNode(obj->mName); sceneNode->mNumMeshes = static_cast(obj->mMeshes.size()); sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes]; std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes); sceneNode->mTransformation = nodeTransform; - - parent->addChildren(1, &sceneNode); + if (nullptr != parent) { + parent->addChildren(1, &sceneNode); + } for (size_t i = 0; i < obj->mComponents.size(); ++i) { Component c = obj->mComponents[i]; auto it = mResourcesDictionnary.find(c.mObjectId); if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) { - addObjectToNode(sceneNode, static_cast(it->second), c.mTransformation); + addObjectToNode(sceneNode, static_cast(it->second), c.mTransformation); } - } } - bool getNodeAttribute(const XmlNode& node, const std::string& attribute, std::string& value) { + bool getNodeAttribute(const XmlNode &node, const std::string &attribute, std::string &value) { pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str()); if (!objectAttribute.empty()) { value = objectAttribute.as_string(); return true; - } else { - return false; } + + return false; } bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) { @@ -265,9 +274,9 @@ private: if (ret) { value = std::atoi(strValue.c_str()); return true; - } else { - return false; - } + } + + return false; } aiMatrix4x4 parseTransformMatrix(std::string matrixStr) { @@ -287,7 +296,7 @@ private: } } if (currentNumber.size() > 0) { - float f = std::stof(currentNumber); + const float f = std::stof(currentNumber); numbers.push_back(f); } @@ -311,29 +320,26 @@ private: transformMatrix.b4 = numbers[10]; transformMatrix.c4 = numbers[11]; transformMatrix.d4 = 1; + return transformMatrix; } void ReadObject(XmlNode &node) { int id = -1, pid = -1, pindex = -1; - bool hasId = getNodeAttribute(node, D3MF::XmlTag::id, id); - //bool hasType = getNodeAttribute(node, D3MF::XmlTag::type, type); not used currently - bool hasPid = getNodeAttribute(node, D3MF::XmlTag::pid, pid); - bool hasPindex = getNodeAttribute(node, D3MF::XmlTag::pindex, pindex); - - std::string idStr = ai_to_string(id); - + bool hasId = getNodeAttribute(node, XmlTag::id, id); + bool hasPid = getNodeAttribute(node, XmlTag::pid, pid); + bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex); if (!hasId) { return; } Object *obj = new Object(id); - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == D3MF::XmlTag::mesh) { auto mesh = ReadMesh(currentNode); - mesh->mName.Set(idStr); + mesh->mName.Set(ai_to_string(id)); if (hasPid) { auto it = mResourcesDictionnary.find(pid); @@ -347,8 +353,9 @@ private: obj->mMeshIndex.push_back(mMeshCount); mMeshCount++; } else if (currentName == D3MF::XmlTag::components) { - for (XmlNode currentSubNode = currentNode.first_child(); currentSubNode; currentSubNode = currentSubNode.next_sibling()) { - if (currentSubNode.name() == D3MF::XmlTag::component) { + for (XmlNode ¤tSubNode : currentNode.children()) { + const std::string subNodeName = currentSubNode.name(); + if (subNodeName == D3MF::XmlTag::component) { int objectId = -1; std::string componentTransformStr; aiMatrix4x4 componentTransform; @@ -356,8 +363,9 @@ private: componentTransform = parseTransformMatrix(componentTransformStr); } - if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) + if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) { obj->mComponents.push_back({ objectId, componentTransform }); + } } } } @@ -369,21 +377,20 @@ private: aiMesh *ReadMesh(XmlNode &node) { aiMesh *mesh = new aiMesh(); - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string ¤tName = currentNode.name(); - if (currentName == D3MF::XmlTag::vertices) { + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == XmlTag::vertices) { ImportVertices(currentNode, mesh); - } else if (currentName == D3MF::XmlTag::triangles) { + } else if (currentName == XmlTag::triangles) { ImportTriangles(currentNode, mesh); } - } return mesh; } void ReadMetadata(XmlNode &node) { - pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name.c_str()); + pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name); const std::string name = attribute.as_string(); const std::string value = node.value(); if (name.empty()) { @@ -398,9 +405,9 @@ private: void ImportVertices(XmlNode &node, aiMesh *mesh) { std::vector vertices; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string ¤tName = currentNode.name(); - if (currentName == D3MF::XmlTag::vertex) { + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == XmlTag::vertex) { vertices.push_back(ReadVertex(currentNode)); } } @@ -412,29 +419,28 @@ private: aiVector3D ReadVertex(XmlNode &node) { aiVector3D vertex; - vertex.x = ai_strtof(node.attribute(D3MF::XmlTag::x.c_str()).as_string(), nullptr); - vertex.y = ai_strtof(node.attribute(D3MF::XmlTag::y.c_str()).as_string(), nullptr); - vertex.z = ai_strtof(node.attribute(D3MF::XmlTag::z.c_str()).as_string(), nullptr); + vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr); + vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr); + vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr); return vertex; } void ImportTriangles(XmlNode &node, aiMesh *mesh) { std::vector faces; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string ¤tName = currentNode.name(); - if (currentName == D3MF::XmlTag::triangle) { + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == XmlTag::triangle) { aiFace face = ReadTriangle(currentNode); faces.push_back(face); - int pid = 0, p1; + int pid = 0, p1 = 0; bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid); bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1); if (hasPid && hasP1) { auto it = mResourcesDictionnary.find(pid); - if (it != mResourcesDictionnary.end()) - { + if (it != mResourcesDictionnary.end()) { if (it->second->getType() == ResourceType::RT_BaseMaterials) { BaseMaterials *baseMaterials = static_cast(it->second); mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1]; @@ -457,9 +463,9 @@ private: face.mNumIndices = 3; face.mIndices = new unsigned int[face.mNumIndices]; - face.mIndices[0] = static_cast(std::atoi(node.attribute(D3MF::XmlTag::v1.c_str()).as_string())); - face.mIndices[1] = static_cast(std::atoi(node.attribute(D3MF::XmlTag::v2.c_str()).as_string())); - face.mIndices[2] = static_cast(std::atoi(node.attribute(D3MF::XmlTag::v3.c_str()).as_string())); + face.mIndices[0] = static_cast(std::atoi(node.attribute(XmlTag::v1).as_string())); + face.mIndices[1] = static_cast(std::atoi(node.attribute(XmlTag::v2).as_string())); + face.mIndices[2] = static_cast(std::atoi(node.attribute(XmlTag::v3).as_string())); return face; } @@ -467,14 +473,14 @@ private: void ReadBaseMaterials(XmlNode &node) { int id = -1; if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) { - BaseMaterials* baseMaterials = new BaseMaterials(id); + BaseMaterials *baseMaterials = new BaseMaterials(id); - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) - { - if (currentNode.name() == D3MF::XmlTag::basematerials_base) { + for (XmlNode ¤tNode : node.children()) { + const std::string currentName = currentNode.name(); + if (currentName == XmlTag::basematerials_base) { baseMaterials->mMaterialIndex.push_back(mMaterialCount); baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id)); - mMaterialCount++; + ++mMaterialCount; } } @@ -488,7 +494,7 @@ private: } //format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1) - const size_t len(strlen(color)); + const size_t len = strlen(color); if (9 != len && 7 != len) { return false; } @@ -517,7 +523,7 @@ private: } void assignDiffuseColor(XmlNode &node, aiMaterial *mat) { - const char *color = node.attribute(D3MF::XmlTag::basematerials_displaycolor.c_str()).as_string(); + const char *color = node.attribute(XmlTag::basematerials_displaycolor).as_string(); aiColor4D diffuse; if (parseColor(color, diffuse)) { mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); @@ -531,7 +537,7 @@ private: bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name); std::string stdMaterialName; - std::string strId(ai_to_string(basematerialsId)); + const std::string strId(ai_to_string(basematerialsId)); stdMaterialName += "id"; stdMaterialName += strId; stdMaterialName += "_"; @@ -556,13 +562,15 @@ private: std::string value; }; std::vector mMetaData; - std::map mResourcesDictionnary; + std::map mResourcesDictionnary; unsigned int mMaterialCount, mMeshCount; XmlParser *mXmlParser; }; } //namespace D3MF +using namespace D3MF; + static const aiImporterDesc desc = { "3mf Importer", "", @@ -596,7 +604,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) { return false; } - D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename); + D3MFOpcPackage opcPackage(pIOHandler, filename); return opcPackage.validate(); } @@ -612,11 +620,11 @@ const aiImporterDesc *D3MFImporter::GetInfo() const { } void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) { - D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename); + D3MFOpcPackage opcPackage(pIOHandler, filename); XmlParser xmlParser; if (xmlParser.parse(opcPackage.RootStream())) { - D3MF::XmlSerializer xmlSerializer(&xmlParser); + XmlSerializer xmlSerializer(&xmlParser); xmlSerializer.ImportXml(pScene); } } diff --git a/code/AssetLib/3MF/D3MFImporter.h b/code/AssetLib/3MF/D3MFImporter.h index a65c4102f..811c463b6 100644 --- a/code/AssetLib/3MF/D3MFImporter.h +++ b/code/AssetLib/3MF/D3MFImporter.h @@ -47,9 +47,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { +/// @brief The 3MF-importer class. class D3MFImporter : public BaseImporter { public: - // BaseImporter interface D3MFImporter(); ~D3MFImporter(); bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const; diff --git a/code/AssetLib/3MF/D3MFOpcPackage.cpp b/code/AssetLib/3MF/D3MFOpcPackage.cpp index 16e659ea3..dbf4f2e10 100644 --- a/code/AssetLib/3MF/D3MFOpcPackage.cpp +++ b/code/AssetLib/3MF/D3MFOpcPackage.cpp @@ -103,9 +103,9 @@ public: std::string name = currentNode.name(); if (name == "Relationship") { OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship()); - relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID.c_str()).as_string(); - relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE.c_str()).as_string(); - relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET.c_str()).as_string(); + relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID).as_string(); + relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string(); + relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string(); if (validateRels(relPtr)) { m_relationShips.push_back(relPtr); } @@ -160,9 +160,9 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) : } } else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) { - ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file); + ASSIMP_LOG_WARN("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file); } else { - ASSIMP_LOG_WARN_F("Ignored file of unknown type: ", file); + ASSIMP_LOG_WARN("Ignored file of unknown type: ", file); } } } @@ -188,7 +188,7 @@ bool D3MFOpcPackage::validate() { std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) { XmlParser xmlParser; if (!xmlParser.parse(stream)) { - return ""; + return std::string(); } OpcPackageRelationshipReader reader(xmlParser); diff --git a/code/AssetLib/AC/ACLoader.cpp b/code/AssetLib/AC/ACLoader.cpp index cba84e8b0..078c96e32 100644 --- a/code/AssetLib/AC/ACLoader.cpp +++ b/code/AssetLib/AC/ACLoader.cpp @@ -116,7 +116,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name buffer = AcSkipToNextToken(buffer); if (0 != name_length) { if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) { - ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " + std::string(name) + " was expected."); + ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected."); return buffer; } buffer += name_length + 1; @@ -492,7 +492,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object, default: // Coerce unknowns to a polygon and warn - ASSIMP_LOG_WARN_F("AC3D: The type flag of a surface is unknown: ", (*it).flags); + ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown: ", (*it).flags); (*it).flags &= ~(Surface::Mask); // fallthrough @@ -690,7 +690,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object, if (object.subDiv) { if (configEvalSubdivision) { std::unique_ptr div(Subdivider::Create(Subdivider::CATMULL_CLARKE)); - ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: " + object.name); + ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: ", object.name); std::vector cpy(meshes.size() - oldm, nullptr); div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true); @@ -698,7 +698,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object, // previous meshes are deleted vy Subdivide(). } else { - ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: " + object.name); + ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: ", object.name); } } } @@ -782,7 +782,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile, unsigned int version = HexDigitToDecimal(buffer[4]); char msg[3]; ASSIMP_itoa10(msg, 3, version); - ASSIMP_LOG_INFO_F("AC3D file format version: ", msg); + ASSIMP_LOG_INFO("AC3D file format version: ", msg); std::vector materials; materials.reserve(5); diff --git a/code/AssetLib/AC/ACLoader.h b/code/AssetLib/AC/ACLoader.h index 77de16b8b..5ae2e80bb 100644 --- a/code/AssetLib/AC/ACLoader.h +++ b/code/AssetLib/AC/ACLoader.h @@ -123,9 +123,9 @@ public: struct Object { Object() : type(World), - name(""), + name(), children(), - texture(""), + texture(), texRepeat(1.f, 1.f), texOffset(0.0f, 0.0f), rotation(), diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index 37756aea0..615882b6a 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -205,7 +205,7 @@ void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::s } static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) { - return (isalnum(pChar) || (pChar == '+') || (pChar == '/')); + return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/')); } void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector &pOutputData) const { @@ -268,7 +268,8 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { mXmlParser = new XmlParser(); if (!mXmlParser->parse(file.get())) { delete mXmlParser; - throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); + mXmlParser = nullptr; + throw DeadlyImportError("Failed to create XML reader for file ", pFile, "."); } // Start reading, search for root tag @@ -517,10 +518,6 @@ bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool p return false; } -void AMFImporter::GetExtensionList(std::set &pExtensionList) { - pExtensionList.insert("amf"); -} - const aiImporterDesc *AMFImporter::GetInfo() const { return &Description; } diff --git a/code/AssetLib/AMF/AMFImporter.hpp b/code/AssetLib/AMF/AMFImporter.hpp index ef61be463..18ef83c24 100644 --- a/code/AssetLib/AMF/AMFImporter.hpp +++ b/code/AssetLib/AMF/AMFImporter.hpp @@ -277,7 +277,6 @@ public: void ParseHelper_Node_Enter(AMFNodeElementBase *child); void ParseHelper_Node_Exit(); bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const; - void GetExtensionList(std::set &pExtensionList); void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); const aiImporterDesc *GetInfo() const; bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const; diff --git a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp index 036b647e8..43d0de52f 100644 --- a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp +++ b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp @@ -428,10 +428,10 @@ void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const st if (pBiggerThan != nullptr) { bool found = false; - + const size_t biggerThan = *pBiggerThan; for (const SComplexFace &face : pFaceList) { for (size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++) { - if (face.Face.mIndices[idx_vert] > *pBiggerThan) { + if (face.Face.mIndices[idx_vert] > biggerThan) { rv = face.Face.mIndices[idx_vert]; found = true; break; diff --git a/code/AssetLib/ASE/ASELoader.cpp b/code/AssetLib/ASE/ASELoader.cpp index e1b9c5b83..1a42c2f52 100644 --- a/code/AssetLib/ASE/ASELoader.cpp +++ b/code/AssetLib/ASE/ASELoader.cpp @@ -614,7 +614,7 @@ void ASEImporter::AddNodes(const std::vector &nodes, node->mNumChildren++; // What we did is so great, it is at least worth a debug message - ASSIMP_LOG_VERBOSE_DEBUG("ASE: Generating separate target node (" + snode->mName + ")"); + ASSIMP_LOG_VERBOSE_DEBUG("ASE: Generating separate target node (", snode->mName, ")"); } } diff --git a/code/AssetLib/ASE/ASEParser.cpp b/code/AssetLib/ASE/ASEParser.cpp index 21ec26593..1f7018b11 100644 --- a/code/AssetLib/ASE/ASEParser.cpp +++ b/code/AssetLib/ASE/ASEParser.cpp @@ -498,6 +498,12 @@ void Parser::ParseLV1MaterialListBlock() { ParseLV2MaterialBlock(sMat); continue; } + if( iDepth == 1 ){ + // CRUDE HACK: support missing brace after "Ascii Scene Exporter v2.51" + LogWarning("Missing closing brace in material list"); + --filePtr; + return; + } } AI_ASE_HANDLE_TOP_LEVEL_SECTION(); } @@ -671,7 +677,7 @@ void Parser::ParseLV3MapBlock(Texture &map) { if (!ParseString(temp, "*MAP_CLASS")) SkipToNextToken(); if (temp != "Bitmap" && temp != "Normal Bump") { - ASSIMP_LOG_WARN_F("ASE: Skipping unknown map type: ", temp); + ASSIMP_LOG_WARN("ASE: Skipping unknown map type: ", temp); parsePath = false; } continue; @@ -685,7 +691,7 @@ void Parser::ParseLV3MapBlock(Texture &map) { // Files with 'None' as map name are produced by // an Maja to ASE exporter which name I forgot .. ASSIMP_LOG_WARN("ASE: Skipping invalid map entry"); - map.mMapName = ""; + map.mMapName = std::string(); } continue; @@ -1119,7 +1125,7 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) { "this is no spot light or target camera"); } } else { - ASSIMP_LOG_ERROR("ASE: Unknown node transformation: " + temp); + ASSIMP_LOG_ERROR("ASE: Unknown node transformation: ", temp); // mode = 0 } continue; diff --git a/code/AssetLib/Assbin/AssbinLoader.cpp b/code/AssetLib/Assbin/AssbinLoader.cpp index d94a9ed7d..d94407e03 100644 --- a/code/AssetLib/Assbin/AssbinLoader.cpp +++ b/code/AssetLib/Assbin/AssbinLoader.cpp @@ -671,7 +671,7 @@ void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) { void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { IOStream *stream = pIOHandler->Open(pFile, "rb"); if (nullptr == stream) { - return; + throw DeadlyImportError("ASSBIN: Could not open ", pFile); } // signature diff --git a/code/AssetLib/B3D/B3DImporter.cpp b/code/AssetLib/B3D/B3DImporter.cpp index bcdb286be..3d9a5075a 100644 --- a/code/AssetLib/B3D/B3DImporter.cpp +++ b/code/AssetLib/B3D/B3DImporter.cpp @@ -145,7 +145,7 @@ AI_WONT_RETURN void B3DImporter::Oops() { // ------------------------------------------------------------------------------------------------ AI_WONT_RETURN void B3DImporter::Fail(string str) { #ifdef DEBUG_B3D - ASSIMP_LOG_ERROR_F("Error in B3D file data: ", str); + ASSIMP_LOG_ERROR("Error in B3D file data: ", str); #endif throw DeadlyImportError("B3D Importer - error in B3D file data: ", str); } @@ -233,7 +233,7 @@ string B3DImporter::ReadChunk() { tag += char(ReadByte()); } #ifdef DEBUG_B3D - ASSIMP_LOG_DEBUG_F("ReadChunk: ", tag); + ASSIMP_LOG_DEBUG("ReadChunk: ", tag); #endif unsigned sz = (unsigned)ReadInt(); _stack.push_back(_pos + sz); @@ -397,7 +397,7 @@ void B3DImporter::ReadTRIS(int v0) { matid = 0; } else if (matid < 0 || matid >= (int)_materials.size()) { #ifdef DEBUG_B3D - ASSIMP_LOG_ERROR_F("material id=", matid); + ASSIMP_LOG_ERROR("material id=", matid); #endif Fail("Bad material id"); } @@ -417,7 +417,7 @@ void B3DImporter::ReadTRIS(int v0) { int i2 = ReadInt() + v0; if (i0 < 0 || i0 >= (int)_vertices.size() || i1 < 0 || i1 >= (int)_vertices.size() || i2 < 0 || i2 >= (int)_vertices.size()) { #ifdef DEBUG_B3D - ASSIMP_LOG_ERROR_F("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2); + ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2); #endif Fail("Bad triangle index"); continue; diff --git a/code/AssetLib/BVH/BVHLoader.cpp b/code/AssetLib/BVH/BVHLoader.cpp index 8ae99033c..cf78fb6c6 100644 --- a/code/AssetLib/BVH/BVHLoader.cpp +++ b/code/AssetLib/BVH/BVHLoader.cpp @@ -359,7 +359,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) { std::string BVHLoader::GetNextToken() { // skip any preceding whitespace while (mReader != mBuffer.end()) { - if (!isspace(*mReader)) + if (!isspace((unsigned char)*mReader)) break; // count lines @@ -372,7 +372,7 @@ std::string BVHLoader::GetNextToken() { // collect all chars till the next whitespace. BVH is easy in respect to that. std::string token; while (mReader != mBuffer.end()) { - if (isspace(*mReader)) + if (isspace((unsigned char)*mReader)) break; token.push_back(*mReader); diff --git a/code/AssetLib/Blender/BlenderDNA.cpp b/code/AssetLib/Blender/BlenderDNA.cpp index 4dcb3d654..3da0dce31 100644 --- a/code/AssetLib/Blender/BlenderDNA.cpp +++ b/code/AssetLib/Blender/BlenderDNA.cpp @@ -198,9 +198,9 @@ void DNAParser::Parse() { s.size = offset; } - ASSIMP_LOG_DEBUG_F("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields"); + ASSIMP_LOG_DEBUG("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields"); -#ifdef ASSIMP_BUILD_BLENDER_DEBUG +#if ASSIMP_BUILD_BLENDER_DEBUG_DNA dna.DumpToFile(); #endif @@ -208,7 +208,7 @@ void DNAParser::Parse() { dna.RegisterConverters(); } -#ifdef ASSIMP_BUILD_BLENDER_DEBUG +#if ASSIMP_BUILD_BLENDER_DEBUG_DNA #include // ------------------------------------------------------------------------------------------------ @@ -237,7 +237,7 @@ void DNA ::DumpToFile() { ASSIMP_LOG_INFO("BlenderDNA: Dumped dna to dna.txt"); } -#endif +#endif // ASSIMP_BUILD_BLENDER_DEBUG_DNA // ------------------------------------------------------------------------------------------------ /*static*/ void DNA ::ExtractArraySize( diff --git a/code/AssetLib/Blender/BlenderDNA.h b/code/AssetLib/Blender/BlenderDNA.h index 090d1be04..f566554b8 100644 --- a/code/AssetLib/Blender/BlenderDNA.h +++ b/code/AssetLib/Blender/BlenderDNA.h @@ -59,6 +59,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define ASSIMP_BUILD_BLENDER_DEBUG #endif +// set this to non-zero to dump BlenderDNA stuff to dna.txt. +// you could set it on the assimp build command line too without touching it here. +// !!! please make sure this is set to 0 in the repo !!! +#ifndef ASSIMP_BUILD_BLENDER_DEBUG_DNA +#define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0 +#endif + // #define ASSIMP_BUILD_BLENDER_NO_STATS namespace Assimp { @@ -495,7 +502,7 @@ public: const Structure &structure, const FileDatabase &db) const; -#ifdef ASSIMP_BUILD_BLENDER_DEBUG +#if ASSIMP_BUILD_BLENDER_DEBUG_DNA // -------------------------------------------------------- /** Dump the DNA to a text file. This is for debugging purposes. * The output file is `dna.txt` in the current working folder*/ diff --git a/code/AssetLib/Blender/BlenderDNA.inl b/code/AssetLib/Blender/BlenderDNA.inl index aebcefa84..a46532057 100644 --- a/code/AssetLib/Blender/BlenderDNA.inl +++ b/code/AssetLib/Blender/BlenderDNA.inl @@ -565,7 +565,7 @@ template <> bool Structure :: ResolvePointer(std::shar // this might happen if DNA::RegisterConverters hasn't been called so far // or if the target type is not contained in `our` DNA. out.reset(); - ASSIMP_LOG_WARN_F( "Failed to find a converter for the `",s.name,"` structure" ); + ASSIMP_LOG_WARN( "Failed to find a converter for the `",s.name,"` structure" ); return false; } diff --git a/code/AssetLib/Blender/BlenderLoader.cpp b/code/AssetLib/Blender/BlenderLoader.cpp index 71ab67721..7cf4e070e 100644 --- a/code/AssetLib/Blender/BlenderLoader.cpp +++ b/code/AssetLib/Blender/BlenderLoader.cpp @@ -132,12 +132,6 @@ bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bo return false; } -// ------------------------------------------------------------------------------------------------ -// List all extensions handled by this loader -void BlenderImporter::GetExtensionList(std::set &app) { - app.insert("blend"); -} - // ------------------------------------------------------------------------------------------------ // Loader registry entry const aiImporterDesc *BlenderImporter::GetInfo() const { @@ -241,9 +235,9 @@ void BlenderImporter::InternReadFile(const std::string &pFile, stream->Read(magic, 3, 1); magic[3] = '\0'; - LogInfo((format(), "Blender version is ", magic[0], ".", magic + 1, + LogInfo("Blender version is ", magic[0], ".", magic + 1, " (64bit: ", file.i64bit ? "true" : "false", - ", little endian: ", file.little ? "true" : "false", ")")); + ", little endian: ", file.little ? "true" : "false", ")"); ParseBlendFile(file, stream); @@ -316,7 +310,7 @@ void BlenderImporter::ExtractScene(Scene &out, const FileDatabase &file) { ss.Convert(out, file); #ifndef ASSIMP_BUILD_BLENDER_NO_STATS - ASSIMP_LOG_INFO_F( + ASSIMP_LOG_INFO( "(Stats) Fields read: ", file.stats().fields_read, ", pointers resolved: ", file.stats().pointers_resolved, ", cache hits: ", file.stats().cache_hits, @@ -426,9 +420,9 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M --s; } - curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]); - curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]); - curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]); + curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower((unsigned char)s[1]); + curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower((unsigned char)s[2]); + curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower((unsigned char)s[3]); curTex->achFormatHint[3] = '\0'; // tex->mHeight = 0; @@ -440,7 +434,7 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M curTex->pcData = reinterpret_cast(ch); - LogInfo("Reading embedded texture, original file was " + std::string(img->name)); + LogInfo("Reading embedded texture, original file was ", img->name); } else { name = aiString(img->name); } @@ -522,7 +516,7 @@ void BlenderImporter::ResolveTexture(aiMaterial *out, const Material *mat, const case Tex::Type_POINTDENSITY: case Tex::Type_VOXELDATA: - LogWarn(std::string("Encountered a texture with an unsupported type: ") + dispnam); + LogWarn("Encountered a texture with an unsupported type: ", dispnam); AddSentinelTexture(out, mat, tex, conv_data); break; @@ -758,7 +752,7 @@ void BlenderImporter::CheckActualType(const ElemBase *dt, const char *check) { // ------------------------------------------------------------------------------------------------ void BlenderImporter::NotSupportedObjectType(const Object *obj, const char *type) { - LogWarn((format(), "Object `", obj->id.name, "` - type is unsupported: `", type, "`, skipping")); + LogWarn("Object `", obj->id.name, "` - type is unsupported: `", type, "`, skipping"); } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/Blender/BlenderLoader.h b/code/AssetLib/Blender/BlenderLoader.h index fdbb586c9..42da76514 100644 --- a/code/AssetLib/Blender/BlenderLoader.h +++ b/code/AssetLib/Blender/BlenderLoader.h @@ -110,7 +110,6 @@ public: protected: const aiImporterDesc* GetInfo () const; - void GetExtensionList(std::set& app); void SetupProperties(const Importer* pImp); void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void ParseBlendFile(Blender::FileDatabase& out, std::shared_ptr stream); diff --git a/code/AssetLib/Blender/BlenderModifier.cpp b/code/AssetLib/Blender/BlenderModifier.cpp index 995e20b1c..bc5c8c2d9 100644 --- a/code/AssetLib/Blender/BlenderModifier.cpp +++ b/code/AssetLib/Blender/BlenderModifier.cpp @@ -90,7 +90,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d const Structure *s = conv_data.db.dna.Get(cur->dna_type); if (!s) { - ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ", cur->dna_type); + ASSIMP_LOG_WARN("BlendModifier: could not resolve DNA name: ", cur->dna_type); continue; } @@ -132,7 +132,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d } } if (curgod) { - ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ", dat.name); + ASSIMP_LOG_WARN("Couldn't find a handler for modifier: ", dat.name); } } @@ -140,7 +140,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d // object, we still can't say whether our modifier implementations were // able to fully do their job. if (ful) { - ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ", cnt, " of ", ful, " modifiers on `", orig_object.id.name, + ASSIMP_LOG_DEBUG("BlendModifier: found handlers for ", cnt, " of ", ful, " modifiers on `", orig_object.id.name, "`, check log messages above for errors"); } } @@ -248,7 +248,7 @@ void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const out.mMeshes = nind; out.mNumMeshes *= 2; - ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `", + ASSIMP_LOG_INFO("BlendModifier: Applied the `Mirror` modifier to `", orig_object.id.name, "`"); } @@ -277,7 +277,7 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data, break; default: - ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ", mir.subdivType); + ASSIMP_LOG_WARN("BlendModifier: Unrecognized subdivision algorithm: ", mir.subdivType); return; }; @@ -292,7 +292,7 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data, subd->Subdivide(meshes, out.mNumMeshes, tempmeshes.get(), std::max(mir.renderLevels, mir.levels), true); std::copy(tempmeshes.get(), tempmeshes.get() + out.mNumMeshes, meshes); - ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `", + ASSIMP_LOG_INFO("BlendModifier: Applied the `Subdivision` modifier to `", orig_object.id.name, "`"); } diff --git a/code/AssetLib/Blender/BlenderModifier.h b/code/AssetLib/Blender/BlenderModifier.h index 7d4096cde..daf120087 100644 --- a/code/AssetLib/Blender/BlenderModifier.h +++ b/code/AssetLib/Blender/BlenderModifier.h @@ -86,7 +86,7 @@ public: const Scene& /*in*/, const Object& /*orig_object*/ ) { - ASSIMP_LOG_INFO_F("This modifier is not supported, skipping: ",orig_modifier.dna_type ); + ASSIMP_LOG_INFO("This modifier is not supported, skipping: ",orig_modifier.dna_type ); return; } }; diff --git a/code/AssetLib/C4D/C4DImporter.cpp b/code/AssetLib/C4D/C4DImporter.cpp index 24fd6f622..434d1429e 100644 --- a/code/AssetLib/C4D/C4DImporter.cpp +++ b/code/AssetLib/C4D/C4DImporter.cpp @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2020, assimp team +Copyright (c) 2006-2021, assimp team All rights reserved. Redistribution and use of this software in source and binary forms, @@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif #include "C4DImporter.h" -#include #include #include #include @@ -65,7 +64,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "c4d_file.h" #include "default_alien_overloads.h" -using namespace melange; +namespace { + +aiString aiStringFrom(cineware::String const & cinestring) { + aiString result; + cinestring.GetCString(result.data, MAXLEN-1); + result.length = static_cast(cinestring.GetLength()); + return result; +} + +} + +using namespace Assimp; +using namespace cineware; // overload this function and fill in your own unique data void GetWriterInfo(int &id, String &appname) { @@ -73,9 +84,6 @@ void GetWriterInfo(int &id, String &appname) { appname = "Open Asset Import Library"; } -using namespace Assimp; -using namespace Assimp::Formatter; - namespace Assimp { template<> const char* LogFunctions::Prefix() { static auto prefix = "C4D: "; @@ -97,17 +105,6 @@ static const aiImporterDesc desc = { }; -// ------------------------------------------------------------------------------------------------ -C4DImporter::C4DImporter() -: BaseImporter() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -C4DImporter::~C4DImporter() { - // empty -} - // ------------------------------------------------------------------------------------------------ bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { const std::string& extension = GetExtension(pFile); @@ -125,11 +122,6 @@ const aiImporterDesc* C4DImporter::GetInfo () const { return &desc; } -// ------------------------------------------------------------------------------------------------ -void C4DImporter::SetupProperties(const Importer* /*pImp*/) { - // nothing to be done for the moment -} - // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. @@ -199,8 +191,8 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS // ------------------------------------------------------------------------------------------------ -bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) { - // based on Melange sample code (C4DImportExport.cpp) +bool C4DImporter::ReadShader(aiMaterial* out, BaseShader* shader) { + // based on Cineware sample code (C4DImportExport.cpp) while(shader) { if(shader->GetType() == Xlayer) { BaseContainer* container = shader->GetDataInstance(); @@ -242,13 +234,11 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) { lsl = lsl->GetNext(); } } else if ( shader->GetType() == Xbitmap ) { - aiString path; - shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1); - path.length = ::strlen(path.data); + auto const path = aiStringFrom(shader->GetFileName().GetString()); out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0)); return true; } else { - LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType()))); + LogWarn("ignoring shader type: ", GetObjectTypeName(shader->GetType())); } shader = shader->GetNext(); } @@ -257,18 +247,15 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) { } // ------------------------------------------------------------------------------------------------ -void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) { - // based on Melange sample code +void C4DImporter::ReadMaterials(BaseMaterial* mat) { + // based on Cineware sample code while (mat) { - const String& name = mat->GetName(); if (mat->GetType() == Mmaterial) { aiMaterial* out = new aiMaterial(); material_mapping[mat] = static_cast(materials.size()); materials.push_back(out); - aiString ai_name; - name.GetCString(ai_name.data, MAXLEN-1); - ai_name.length = ::strlen(ai_name.data); + auto const ai_name = aiStringFrom(mat->GetName()); out->AddProperty(&ai_name, AI_MATKEY_NAME); Material& m = dynamic_cast(*mat); @@ -294,7 +281,7 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) { ReadShader(out, shader); } } else { - LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType()))); + LogWarn("ignoring plugin material: ", GetObjectTypeName(mat->GetType())); } mat = mat->GetNext(); } @@ -305,19 +292,15 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) { ai_assert(parent != nullptr ); std::vector nodes; - // based on Melange sample code + // based on Cineware sample code while (object) { - const String& name = object->GetName(); const LONG type = object->GetType(); const Matrix& ml = object->GetMl(); - aiString string; - name.GetCString(string.data, MAXLEN-1); - string.length = ::strlen(string.data); aiNode* const nd = new aiNode(); nd->mParent = parent; - nd->mName = string; + nd->mName = aiStringFrom(object->GetName()); nd->mTransformation.a1 = ml.v1.x; nd->mTransformation.b1 = ml.v1.y; @@ -352,7 +335,7 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) { meshes.push_back(mesh); } } else { - LogWarn("ignoring object: " + std::string(GetObjectTypeName(type))); + LogWarn("ignoring object: ", GetObjectTypeName(type)); } RecurseHierarchy(object->GetDown(), nd); @@ -370,7 +353,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) { ai_assert(object != nullptr); ai_assert( object->GetType() == Opolygon ); - // based on Melange sample code + // based on Cineware sample code PolygonObject* const polyObject = dynamic_cast(object); ai_assert(polyObject != nullptr); @@ -618,4 +601,3 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) { } #endif // ASSIMP_BUILD_NO_C4D_IMPORTER - diff --git a/code/AssetLib/C4D/C4DImporter.h b/code/AssetLib/C4D/C4DImporter.h index f9406c3e0..c44cf5e37 100644 --- a/code/AssetLib/C4D/C4DImporter.h +++ b/code/AssetLib/C4D/C4DImporter.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2020, assimp team +Copyright (c) 2006-2021, assimp team All rights reserved. Redistribution and use of this software in source and binary forms, @@ -56,8 +56,8 @@ struct aiMaterial; struct aiImporterDesc; -namespace melange { - class BaseObject; // c4d_file.h +namespace cineware { + class BaseObject; class PolygonObject; class BaseMaterial; class BaseShader; @@ -71,43 +71,34 @@ namespace Assimp { } // ------------------------------------------------------------------------------------------- -/** Importer class to load Cinema4D files using the Melange library to be obtained from - * www.plugincafe.com +/** Importer class to load Cinema4D files using the Cineware library to be obtained from + * https://developers.maxon.net * - * Note that Melange is not free software. */ + * Note that Cineware is not free software. */ // ------------------------------------------------------------------------------------------- class C4DImporter : public BaseImporter, public LogFunctions { public: - C4DImporter(); - ~C4DImporter(); - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, - bool checkSig) const; + bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override; protected: - // -------------------- - const aiImporterDesc* GetInfo () const; + const aiImporterDesc* GetInfo () const override; - // -------------------- - void SetupProperties(const Importer* pImp); - - // -------------------- - void InternReadFile( const std::string& pFile, aiScene* pScene, - IOSystem* pIOHandler); + void InternReadFile( const std::string& pFile, aiScene*, IOSystem* ) override; private: - void ReadMaterials(melange::BaseMaterial* mat); - void RecurseHierarchy(melange::BaseObject* object, aiNode* parent); - aiMesh* ReadMesh(melange::BaseObject* object); - unsigned int ResolveMaterial(melange::PolygonObject* obj); + void ReadMaterials(cineware::BaseMaterial* mat); + void RecurseHierarchy(cineware::BaseObject* object, aiNode* parent); + aiMesh* ReadMesh(cineware::BaseObject* object); + unsigned int ResolveMaterial(cineware::PolygonObject* obj); - bool ReadShader(aiMaterial* out, melange::BaseShader* shader); + bool ReadShader(aiMaterial* out, cineware::BaseShader* shader); std::vector meshes; std::vector materials; - typedef std::map MaterialMap; + typedef std::map MaterialMap; MaterialMap material_mapping; }; // !class C4DImporter diff --git a/code/AssetLib/COB/COBLoader.cpp b/code/AssetLib/COB/COBLoader.cpp index efe7fc446..94327c683 100644 --- a/code/AssetLib/COB/COBLoader.cpp +++ b/code/AssetLib/COB/COBLoader.cpp @@ -137,7 +137,13 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) { // Imports the given file into the given scene structure. void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { COB::Scene scene; - std::unique_ptr stream(new StreamReaderLE(pIOHandler->Open(pFile, "rb"))); + + auto file = pIOHandler->Open(pFile, "rb"); + if (!file) { + ThrowException("Could not open " + pFile); + } + + std::unique_ptr stream(new StreamReaderLE(file)); // check header char head[32]; @@ -146,7 +152,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy ThrowException("Could not found magic id: `Caligari`"); } - ASSIMP_LOG_INFO_F("File format tag: ", std::string(head + 9, 6)); + ASSIMP_LOG_INFO("File format tag: ", std::string(head + 9, 6)); if (head[16] != 'L') { ThrowException("File is big-endian, which is not supported"); } @@ -295,8 +301,7 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi } std::unique_ptr defmat; if (!min) { - ASSIMP_LOG_VERBOSE_DEBUG(format() << "Could not resolve material index " - << reflist.first << " - creating default material for this slot"); + ASSIMP_LOG_VERBOSE_DEBUG("Could not resolve material index ", reflist.first, " - creating default material for this slot"); defmat.reset(min = new Material()); } @@ -521,7 +526,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk ++splitter; if (!splitter.match_start("mat# ")) { - ASSIMP_LOG_WARN_F("Expected `mat#` line in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `mat#` line in `Mat1` chunk ", nfo.id); return; } @@ -533,7 +538,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk ++splitter; if (!splitter.match_start("shader: ")) { - ASSIMP_LOG_WARN_F("Expected `mat#` line in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `mat#` line in `Mat1` chunk ", nfo.id); return; } std::string shader = std::string(splitter[1]); @@ -544,12 +549,12 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk } else if (shader == "phong") { mat.shader = Material::PHONG; } else if (shader != "flat") { - ASSIMP_LOG_WARN_F("Unknown value for `shader` in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Unknown value for `shader` in `Mat1` chunk ", nfo.id); } ++splitter; if (!splitter.match_start("rgb ")) { - ASSIMP_LOG_WARN_F("Expected `rgb` line in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `rgb` line in `Mat1` chunk ", nfo.id); } const char *rgb = splitter[1]; @@ -557,7 +562,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk ++splitter; if (!splitter.match_start("alpha ")) { - ASSIMP_LOG_WARN_F("Expected `alpha` line in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `alpha` line in `Mat1` chunk ", nfo.id); } const char *tokens[10]; @@ -577,7 +582,7 @@ void COBImporter::ReadUnit_Ascii(Scene &out, LineSplitter &splitter, const Chunk } ++splitter; if (!splitter.match_start("Units ")) { - ASSIMP_LOG_WARN_F("Expected `Units` line in `Unit` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `Units` line in `Unit` chunk ", nfo.id); return; } @@ -588,12 +593,12 @@ void COBImporter::ReadUnit_Ascii(Scene &out, LineSplitter &splitter, const Chunk const unsigned int t = strtoul10(splitter[1]); nd->unit_scale = t >= sizeof(units) / sizeof(units[0]) ? ( - ASSIMP_LOG_WARN_F(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) : + ASSIMP_LOG_WARN(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) : units[t]; return; } } - ASSIMP_LOG_WARN_F("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); + ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); } // ------------------------------------------------------------------------------------------------ @@ -622,13 +627,13 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk } else if (splitter.match_start("Spot ")) { msh.ltype = Light::SPOT; } else { - ASSIMP_LOG_WARN_F("Unknown kind of light source in `Lght` chunk ", nfo.id, " : ", *splitter); + ASSIMP_LOG_WARN("Unknown kind of light source in `Lght` chunk ", nfo.id, " : ", *splitter); msh.ltype = Light::SPOT; } ++splitter; if (!splitter.match_start("color ")) { - ASSIMP_LOG_WARN_F("Expected `color` line in `Lght` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `color` line in `Lght` chunk ", nfo.id); } const char *rgb = splitter[1]; @@ -636,14 +641,14 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk SkipSpaces(&rgb); if (strncmp(rgb, "cone angle", 10) != 0) { - ASSIMP_LOG_WARN_F("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id); } SkipSpaces(rgb + 10, &rgb); msh.angle = fast_atof(&rgb); SkipSpaces(&rgb); if (strncmp(rgb, "inner angle", 11) != 0) { - ASSIMP_LOG_WARN_F("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id); } SkipSpaces(rgb + 11, &rgb); msh.inner_angle = fast_atof(&rgb); @@ -1027,7 +1032,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const mat.type = Material::METAL; break; default: - ASSIMP_LOG_ERROR_F("Unrecognized shader type in `Mat1` chunk with id ", nfo.id); + ASSIMP_LOG_ERROR("Unrecognized shader type in `Mat1` chunk with id ", nfo.id); mat.type = Material::FLAT; } @@ -1042,7 +1047,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const mat.autofacet = Material::SMOOTH; break; default: - ASSIMP_LOG_ERROR_F("Unrecognized faceting mode in `Mat1` chunk with id ", nfo.id); + ASSIMP_LOG_ERROR("Unrecognized faceting mode in `Mat1` chunk with id ", nfo.id); mat.autofacet = Material::FACETED; } mat.autofacet_angle = static_cast(reader.GetI1()); @@ -1170,13 +1175,13 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const if (nd->id == nfo.parent_id) { const unsigned int t = reader.GetI2(); nd->unit_scale = t >= sizeof(units) / sizeof(units[0]) ? ( - ASSIMP_LOG_WARN_F(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) : + ASSIMP_LOG_WARN(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) : units[t]; return; } } - ASSIMP_LOG_WARN_F("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); + ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); } #endif // ASSIMP_BUILD_NO_COB_IMPORTER diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp index 902eebc4b..492e6971f 100644 --- a/code/AssetLib/Collada/ColladaLoader.cpp +++ b/code/AssetLib/Collada/ColladaLoader.cpp @@ -75,7 +75,7 @@ static const aiImporterDesc desc = { 3, 1, 5, - "dae zae" + "dae xml zae" }; static const float kMillisecondsFromSeconds = 1000.f; @@ -317,7 +317,7 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Nod nd = FindNode(pParser.mRootNode, nodeInst.mNode); } if (nullptr == nd) { - ASSIMP_LOG_ERROR_F("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode); + ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode); } else { // attach this node to the list of children resolved.push_back(nd); @@ -347,7 +347,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node // find the referred light ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find(lid.mLight); if (srcLightIt == pParser.mLightLibrary.end()) { - ASSIMP_LOG_WARN_F("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping."); + ASSIMP_LOG_WARN("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping."); continue; } const Collada::Light *srcLight = &srcLightIt->second; @@ -412,7 +412,7 @@ void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node // find the referred light ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera); if (srcCameraIt == pParser.mCameraLibrary.end()) { - ASSIMP_LOG_WARN_F("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping."); + ASSIMP_LOG_WARN("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping."); continue; } const Collada::Camera *srcCamera = &srcCameraIt->second; @@ -486,7 +486,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node } if (nullptr == srcMesh) { - ASSIMP_LOG_WARN_F("Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping."); + ASSIMP_LOG_WARN("Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping."); continue; } } else { @@ -511,7 +511,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node table = &meshMatIt->second; meshMaterial = table->mMatName; } else { - ASSIMP_LOG_WARN_F("Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <", + ASSIMP_LOG_WARN("Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <", mid.mMeshOrController, ">."); if (!mid.mMaterials.empty()) { meshMaterial = mid.mMaterials.begin()->second.mMatName; @@ -883,7 +883,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc if (nullptr != bnode) { bone->mName.Set(FindNameForNode(bnode)); } else { - ASSIMP_LOG_WARN_F("ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\"."); + ASSIMP_LOG_WARN("ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\"."); } // and insert bone @@ -1184,7 +1184,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse else if (subElement == "Z") entry.mSubElement = 2; else - ASSIMP_LOG_WARN_F("Unknown anim subelement <", subElement, ">. Ignoring"); + ASSIMP_LOG_WARN("Unknown anim subelement <", subElement, ">. Ignoring"); } else { // no sub-element following, transformId is remaining string entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1); @@ -1241,7 +1241,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse continue; } entry.mTargetId = entry.mTransformId; - entry.mTransformId = ""; + entry.mTransformId = std::string(); } entry.mChannel = &(*cit); @@ -1711,7 +1711,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse // find the image referred by this name in the image library of the scene ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find(name); if (imIt == pParser.mImageLibrary.end()) { - ASSIMP_LOG_WARN_F("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\"."); + ASSIMP_LOG_WARN("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\"."); //set default texture file name result.Set(name + ".jpg"); diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index 42166fdd4..5dbf0a567 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -71,7 +71,7 @@ static void ReportWarning(const char *msg, ...) { ai_assert(iLen > 0); va_end(args); - ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen)); + ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen)); } static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) { @@ -234,7 +234,7 @@ void ColladaParser::UriDecodePath(aiString &ss) { #if defined(_MSC_VER) if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') { #else - if (ss.data[0] == '/' && isalpha(ss.data[1]) && ss.data[2] == ':') { + if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') { #endif --ss.length; ::memmove(ss.data, ss.data + 1, ss.length); @@ -623,8 +623,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle controller.mType = Skin; controller.mMethod = Normalized; - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { @@ -929,8 +928,7 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) { // ------------------------------------------------------------------------------------------------ // Reads a light entry into the given light void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) { - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -991,10 +989,8 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) { // ------------------------------------------------------------------------------------------------ // Reads a camera entry into the given light void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) { - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; - while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); if (currentName == "orthographic") { @@ -1050,11 +1046,10 @@ void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) { // ------------------------------------------------------------------------------------------------ // Reads an COMMON effect profile void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) { - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { - const std::string ¤tName = currentNode.name(); + const std::string currentName = currentNode.name(); if (currentName == "newparam") { // save ID std::string sid = currentNode.attribute("sid").as_string(); @@ -1145,10 +1140,9 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) { if (node.empty()) { return; } - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); - XmlNode currentNode; + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); + XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); // MAYA extensions @@ -1208,10 +1202,9 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p if (node.empty()) { return; } - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); - XmlNode currentNode; + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); + XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); if (currentName == "color") { @@ -1273,8 +1266,7 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam) return; } - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -1360,8 +1352,7 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) { return; } - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -1386,8 +1377,7 @@ void ColladaParser::ReadSource(XmlNode &node) { std::string sourceID; XmlParser::getStdStrAttribute(node, "id", sourceID); - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -1490,8 +1480,7 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) { acc.mSource = source.c_str() + 1; // ignore the leading '#' acc.mSize = 0; // gets incremented with every param - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -1608,8 +1597,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) { ai_assert(primType != Prim_Invalid); // also a number of elements, but in addition a

primitive collection and probably index counts for all primitives - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -2400,7 +2388,7 @@ Collada::InputType ColladaParser::GetTypeForSemantic(const std::string &semantic else if (semantic == "TANGENT" || semantic == "TEXTANGENT") return IT_Tangent; - ASSIMP_LOG_WARN_F("Unknown vertex input type \"", semantic, "\". Ignoring."); + ASSIMP_LOG_WARN("Unknown vertex input type \"", semantic, "\". Ignoring."); return IT_Invalid; } diff --git a/code/AssetLib/DXF/DXFHelper.h b/code/AssetLib/DXF/DXFHelper.h index f7fc470e8..c7e75c3b1 100644 --- a/code/AssetLib/DXF/DXFHelper.h +++ b/code/AssetLib/DXF/DXFHelper.h @@ -135,7 +135,7 @@ public: for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++); splitter++; - ASSIMP_LOG_VERBOSE_DEBUG((Formatter::format("DXF: skipped over control group ("),cnt," lines)")); + ASSIMP_LOG_VERBOSE_DEBUG("DXF: skipped over control group (",cnt," lines)"); } } catch(std::logic_error&) { ai_assert(!splitter); diff --git a/code/AssetLib/DXF/DXFLoader.cpp b/code/AssetLib/DXF/DXFLoader.cpp index d4a6be4ad..09c229265 100644 --- a/code/AssetLib/DXF/DXFLoader.cpp +++ b/code/AssetLib/DXF/DXFLoader.cpp @@ -202,7 +202,7 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene, // comments else if (reader.Is(999)) { - ASSIMP_LOG_INFO_F("DXF Comment: ", reader.Value()); + ASSIMP_LOG_INFO("DXF Comment: ", reader.Value()); } // don't read past the official EOF sign @@ -241,7 +241,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) { } } - ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount); + ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount); } if (! output.blocks.size() ) { @@ -372,7 +372,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc // first check if the referenced blocks exists ... const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name); if (it == blocks_by_name.end()) { - ASSIMP_LOG_ERROR_F("DXF: Failed to resolve block reference: ", insert.name,"; skipping" ); + ASSIMP_LOG_ERROR("DXF: Failed to resolve block reference: ", insert.name,"; skipping" ); continue; } @@ -473,7 +473,7 @@ void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) { ++reader; } - ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: got ", output.blocks.size()," entries in BLOCKS" ); + ASSIMP_LOG_VERBOSE_DEBUG("DXF: got ", output.blocks.size()," entries in BLOCKS" ); } // ------------------------------------------------------------------------------------------------ @@ -549,7 +549,7 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) ++reader; } - ASSIMP_LOG_VERBOSE_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), + ASSIMP_LOG_VERBOSE_DEBUG( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), " inserted blocks in ENTITIES" ); } @@ -654,7 +654,7 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) //} if (vguess && line.positions.size() != vguess) { - ASSIMP_LOG_WARN_F("DXF: unexpected vertex count in polymesh: ", + ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ", line.positions.size(),", expected ", vguess ); } @@ -670,7 +670,7 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) // to set the 71 and 72 fields, respectively, to valid values. // So just fire a warning. if (iguess && line.counts.size() != iguess) { - ASSIMP_LOG_WARN_F( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess ); + ASSIMP_LOG_WARN( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess ); } } else if (!line.indices.size() && !line.counts.size()) { diff --git a/code/AssetLib/FBX/FBXBinaryTokenizer.cpp b/code/AssetLib/FBX/FBXBinaryTokenizer.cpp index 800d0014d..348812054 100644 --- a/code/AssetLib/FBX/FBXBinaryTokenizer.cpp +++ b/code/AssetLib/FBX/FBXBinaryTokenizer.cpp @@ -459,7 +459,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length) /*Result ignored*/ ReadByte(input, cursor, input + length); /*Result ignored*/ ReadByte(input, cursor, input + length); const uint32_t version = ReadWord(input, cursor, input + length); - ASSIMP_LOG_DEBUG_F("FBX version: ", version); + ASSIMP_LOG_DEBUG("FBX version: ", version); const bool is64bits = version >= 7500; const char *end = input + length; try diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index cb033a651..8d37d3790 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -811,7 +811,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std // we need to generate a full node chain to accommodate for assimp's // lack to express pivots and offsets. if ((chainBits & chainMaskComplex) && doc.Settings().preservePivots) { - FBXImporter::LogInfo("generating full transformation chain for node: " + name); + FBXImporter::LogInfo("generating full transformation chain for node: ", name); // query the anim_chain_bits dictionary to find out which chain elements // have associated node animation channels. These can not be dropped @@ -918,7 +918,7 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root const std::vector &indices = ConvertLine(*line, root_node); std::copy(indices.begin(), indices.end(), std::back_inserter(meshes)); } else { - FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name()); + FBXImporter::LogWarn("ignoring unrecognized geometry: ", geo->Name()); } } @@ -944,7 +944,7 @@ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode * const std::vector &vertices = mesh.GetVertices(); const std::vector &faces = mesh.GetFaceIndexCounts(); if (vertices.empty() || faces.empty()) { - FBXImporter::LogWarn("ignoring empty geometry: " + mesh.Name()); + FBXImporter::LogWarn("ignoring empty geometry: ", mesh.Name()); return temp; } @@ -971,7 +971,7 @@ std::vector FBXConverter::ConvertLine(const LineGeometry &line, ai const std::vector &vertices = line.GetVertices(); const std::vector &indices = line.GetIndices(); if (vertices.empty() || indices.empty()) { - FBXImporter::LogWarn("ignoring empty line: " + line.Name()); + FBXImporter::LogWarn("ignoring empty line: ", line.Name()); return temp; } @@ -1542,10 +1542,10 @@ void FBXConverter::ConvertCluster(std::vector &local_mesh_bones, const aiBone *bone = nullptr; if (bone_map.count(deformer_name)) { - ASSIMP_LOG_VERBOSE_DEBUG_F("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name); + ASSIMP_LOG_VERBOSE_DEBUG("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name); bone = bone_map[deformer_name]; } else { - ASSIMP_LOG_VERBOSE_DEBUG_F("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name); + ASSIMP_LOG_VERBOSE_DEBUG("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name); bone = new aiBone(); bone->mName = bone_name; @@ -1591,7 +1591,7 @@ void FBXConverter::ConvertCluster(std::vector &local_mesh_bones, const bone_map.insert(std::pair(deformer_name, bone)); } - ASSIMP_LOG_DEBUG_F("bone research: Indicies size: ", out_indices.size()); + ASSIMP_LOG_DEBUG("bone research: Indicies size: ", out_indices.size()); // lookup must be populated in case something goes wrong // this also allocates bones to mesh instance outside @@ -1815,14 +1815,14 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); continue; } if (uvIndex == -1) { uvIndex = index; } else { - FBXImporter::LogWarn("the UV channel named " + uvSet + + FBXImporter::LogWarn("the UV channel named ", uvSet, " appears at different positions in meshes, results will be wrong"); } } @@ -1839,7 +1839,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); } if (uvIndex == -1) { @@ -1848,7 +1848,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap } if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); + FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel"); uvIndex = 0; } } @@ -1934,14 +1934,14 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); continue; } if (uvIndex == -1) { uvIndex = index; } else { - FBXImporter::LogWarn("the UV channel named " + uvSet + + FBXImporter::LogWarn("the UV channel named ", uvSet, " appears at different positions in meshes, results will be wrong"); } } @@ -1958,7 +1958,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); } if (uvIndex == -1) { @@ -1967,7 +1967,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex } if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); + FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel"); uvIndex = 0; } } @@ -2319,14 +2319,14 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); continue; } if (uvIndex == -1) { uvIndex = index; } else { - FBXImporter::LogWarn("the UV channel named " + uvSet + " appears at different positions in meshes, results will be wrong"); + FBXImporter::LogWarn("the UV channel named ", uvSet, " appears at different positions in meshes, results will be wrong"); } } } else { @@ -2342,7 +2342,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); } if (uvIndex == -1) { @@ -2351,7 +2351,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa } if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); + FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel"); uvIndex = 0; } } @@ -2574,7 +2574,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) { // empty animations would fail validation, so drop them delete anim; animations.pop_back(); - FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): " + name); + FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): ", name); return; } @@ -2707,13 +2707,13 @@ void FBXConverter::GenerateNodeAnimations(std::vector &node_anims, ai_assert(node); if (node->TargetProperty().empty()) { - FBXImporter::LogWarn("target property for animation curve not set: " + node->Name()); + FBXImporter::LogWarn("target property for animation curve not set: ", node->Name()); continue; } curve_node = node; if (node->Curves().empty()) { - FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: " + node->Name()); + FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: ", node->Name()); continue; } @@ -2748,7 +2748,7 @@ void FBXConverter::GenerateNodeAnimations(std::vector &node_anims, if (doc.Settings().optimizeEmptyAnimationCurves && IsRedundantAnimationData(target, comp, (chain[i]->second))) { - FBXImporter::LogVerboseDebug("dropping redundant animation channel for node " + target.Name()); + FBXImporter::LogVerboseDebug("dropping redundant animation channel for node ", target.Name()); continue; } diff --git a/code/AssetLib/FBX/FBXDocument.cpp b/code/AssetLib/FBX/FBXDocument.cpp index a9eb3ad15..7adaadf6c 100644 --- a/code/AssetLib/FBX/FBXDocument.cpp +++ b/code/AssetLib/FBX/FBXDocument.cpp @@ -312,7 +312,7 @@ void Document::ReadHeader() { const Scope& shead = *ehead->Compound(); fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0)); - ASSIMP_LOG_DEBUG_F("FBX Version: ", fbxVersion); + ASSIMP_LOG_DEBUG("FBX Version: ", fbxVersion); // While we may have some success with newer files, we don't support // the older 6.n fbx format diff --git a/code/AssetLib/FBX/FBXDocumentUtil.cpp b/code/AssetLib/FBX/FBXDocumentUtil.cpp index 6ba01aa47..ab15298a8 100644 --- a/code/AssetLib/FBX/FBXDocumentUtil.cpp +++ b/code/AssetLib/FBX/FBXDocumentUtil.cpp @@ -79,7 +79,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/) void DOMWarning(const std::string& message, const Token& token) { if(DefaultLogger::get()) { - ASSIMP_LOG_WARN_F("FBX-DOM", Util::GetTokenText(&token), message); + ASSIMP_LOG_WARN("FBX-DOM", Util::GetTokenText(&token), message); } } @@ -91,7 +91,7 @@ void DOMWarning(const std::string& message, const Element* element /*= nullptr*/ return; } if(DefaultLogger::get()) { - ASSIMP_LOG_WARN("FBX-DOM: " + message); + ASSIMP_LOG_WARN("FBX-DOM: ", message); } } diff --git a/code/AssetLib/FBX/FBXExporter.cpp b/code/AssetLib/FBX/FBXExporter.cpp index 322161411..e519f7e77 100644 --- a/code/AssetLib/FBX/FBXExporter.cpp +++ b/code/AssetLib/FBX/FBXExporter.cpp @@ -1789,13 +1789,13 @@ void FBXExporter::WriteObjects () blendchannel_uid, blendshape_name + FBX::SEPARATOR + "SubDeformer", "BlendShapeChannel" ); sdnode.AddChild("Version", int32_t(100)); - sdnode.AddChild("DeformPercent", int32_t(100)); + sdnode.AddChild("DeformPercent", float_t(0.0)); FBX::Node p("Properties70"); - p.AddP70numberA("DeformPercent", 100.); + p.AddP70numberA("DeformPercent", 0.0); sdnode.AddChild(p); // TODO: Normally just one weight per channel, adding stub for later development std::vectorfFullWeights; - fFullWeights.push_back(0.); + fFullWeights.push_back(100.); sdnode.AddChild("FullWeights", fFullWeights); sdnode.Dump(outstream, binary, indent); diff --git a/code/AssetLib/FBX/FBXMaterial.cpp b/code/AssetLib/FBX/FBXMaterial.cpp index 3af014bc3..6ada9630b 100644 --- a/code/AssetLib/FBX/FBXMaterial.cpp +++ b/code/AssetLib/FBX/FBXMaterial.cpp @@ -82,7 +82,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con // lower-case shading because Blender (for example) writes "Phong" for (size_t i = 0; i < shading.length(); ++i) { - shading[i] = static_cast(tolower(shading[i])); + shading[i] = static_cast(tolower(static_cast(shading[i]))); } std::string templateName; if(shading == "phong") { @@ -352,7 +352,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std } } catch (const runtime_error& runtimeError) { //we don't need the content data for contents that has already been loaded - ASSIMP_LOG_VERBOSE_DEBUG_F("Caught exception in FBXMaterial (likely because content was already loaded): ", + ASSIMP_LOG_VERBOSE_DEBUG("Caught exception in FBXMaterial (likely because content was already loaded): ", runtimeError.what()); } } diff --git a/code/AssetLib/FBX/FBXMeshGeometry.cpp b/code/AssetLib/FBX/FBXMeshGeometry.cpp index fd8a0ff98..9bafcbd2a 100644 --- a/code/AssetLib/FBX/FBXMeshGeometry.cpp +++ b/code/AssetLib/FBX/FBXMeshGeometry.cpp @@ -307,8 +307,8 @@ void MeshGeometry::ReadLayerElement(const Scope& layerElement) } } - FBXImporter::LogError(Formatter::format("failed to resolve vertex layer element: ") - << type << ", index: " << typedIndex); + FBXImporter::LogError("failed to resolve vertex layer element: ", + type, ", index: ", typedIndex); } // ------------------------------------------------------------------------------------------------ @@ -324,13 +324,13 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop if (type == "LayerElementUV") { if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { - FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum number of UV channels exceeded: ") - << index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" ); + FBXImporter::LogError("ignoring UV layer, maximum number of UV channels exceeded: ", + index, " (limit is ", AI_MAX_NUMBER_OF_TEXTURECOORDS, ")" ); return; } const Element* Name = source["Name"]; - m_uvNames[index] = ""; + m_uvNames[index] = std::string(); if(Name) { m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0)); } @@ -402,8 +402,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop } else if (type == "LayerElementColor") { if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) { - FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ") - << index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")" ); + FBXImporter::LogError("ignoring vertex color layer, maximum number of color sets exceeded: ", + index, " (limit is ", AI_MAX_NUMBER_OF_COLOR_SETS, ")" ); return; } @@ -449,8 +449,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); if (tempData.size() != mapping_offsets.size()) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ") - << tempData.size() << ", expected " << mapping_offsets.size()); + FBXImporter::LogError("length of input data unexpected for ByVertice mapping: ", + tempData.size(), ", expected ", mapping_offsets.size()); return; } @@ -470,8 +470,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); if (uvIndices.size() != vertex_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ") - << uvIndices.size() << ", expected " << vertex_count); + FBXImporter::LogError("length of input data unexpected for ByVertice mapping: ", + uvIndices.size(), ", expected ", vertex_count); return; } @@ -493,8 +493,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); if (tempData.size() != vertex_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") - << tempData.size() << ", expected " << vertex_count + FBXImporter::LogError("length of input data unexpected for ByPolygon mapping: ", + tempData.size(), ", expected ", vertex_count ); return; } @@ -509,14 +509,14 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); if (uvIndices.size() > vertex_count) { - FBXImporter::LogWarn(Formatter::format("trimming length of input array for ByPolygonVertex mapping: ") - << uvIndices.size() << ", expected " << vertex_count); + FBXImporter::LogWarn("trimming length of input array for ByPolygonVertex mapping: ", + uvIndices.size(), ", expected ", vertex_count); uvIndices.resize(vertex_count); } if (uvIndices.size() != vertex_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygonVertex mapping: ") - << uvIndices.size() << ", expected " << vertex_count); + FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping: ", + uvIndices.size(), ", expected ", vertex_count); return; } @@ -537,8 +537,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, } } else { - FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ") - << MappingInformationType << "," << ReferenceInformationType); + FBXImporter::LogError("ignoring vertex data channel, access type not implemented: ", + MappingInformationType, ",", ReferenceInformationType); } } @@ -642,10 +642,10 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons if (MappingInformationType == "AllSame") { // easy - same material for all faces if (materials_out.empty()) { - FBXImporter::LogError(Formatter::format("expected material index, ignoring")); + FBXImporter::LogError("expected material index, ignoring"); return; } else if (materials_out.size() > 1) { - FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one")); + FBXImporter::LogWarn("expected only a single material index, ignoring all except the first one"); materials_out.clear(); } @@ -655,14 +655,14 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons materials_out.resize(face_count); if(materials_out.size() != face_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") - << materials_out.size() << ", expected " << face_count + FBXImporter::LogError("length of input data unexpected for ByPolygon mapping: ", + materials_out.size(), ", expected ", face_count ); return; } } else { - FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ") - << MappingInformationType << "," << ReferenceInformationType); + FBXImporter::LogError("ignoring material assignments, access type not implemented: ", + MappingInformationType, ",", ReferenceInformationType); } } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/FBX/FBXParser.cpp b/code/AssetLib/FBX/FBXParser.cpp index 046d26c95..37cf83cf9 100644 --- a/code/AssetLib/FBX/FBXParser.cpp +++ b/code/AssetLib/FBX/FBXParser.cpp @@ -462,7 +462,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out) if (t.Type() != TokenType_DATA) { err_out = "expected TOK_DATA token"; - return ""; + return std::string(); } if(t.IsBinary()) @@ -470,7 +470,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out) const char* data = t.begin(); if (data[0] != 'S') { err_out = "failed to parse S(tring), unexpected data type (binary)"; - return ""; + return std::string(); } // read string length @@ -484,13 +484,13 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out) const size_t length = static_cast(t.end() - t.begin()); if(length < 2) { err_out = "token is too short to hold a string"; - return ""; + return std::string(); } const char* s = t.begin(), *e = t.end() - 1; if (*s != '\"' || *e != '\"') { err_out = "expected double quoted string"; - return ""; + return std::string(); } return std::string(s+1,length-2); diff --git a/code/AssetLib/FBX/FBXProperties.cpp b/code/AssetLib/FBX/FBXProperties.cpp index 2f39fc7dc..1e4cd0ead 100644 --- a/code/AssetLib/FBX/FBXProperties.cpp +++ b/code/AssetLib/FBX/FBXProperties.cpp @@ -155,7 +155,7 @@ std::string PeekPropertyName(const Element& element) ai_assert(element.KeyToken().StringContents() == "P"); const TokenList& tok = element.Tokens(); if(tok.size() < 4) { - return ""; + return std::string(); } return ParseTokenAsString(*tok[0]); diff --git a/code/AssetLib/HMP/HMPLoader.cpp b/code/AssetLib/HMP/HMPLoader.cpp index 56401f5c9..cd14cb9c3 100644 --- a/code/AssetLib/HMP/HMPLoader.cpp +++ b/code/AssetLib/HMP/HMPLoader.cpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssetLib/HMP/HMPLoader.h" #include "AssetLib/MD2/MD2FileData.h" +#include #include #include #include @@ -151,12 +152,7 @@ void HMPImporter::InternReadFile(const std::string &pFile, InternReadFile_HMP7(); } else { // Print the magic word to the logger - char szBuffer[5]; - szBuffer[0] = ((char *)&iMagic)[0]; - szBuffer[1] = ((char *)&iMagic)[1]; - szBuffer[2] = ((char *)&iMagic)[2]; - szBuffer[3] = ((char *)&iMagic)[3]; - szBuffer[4] = '\0'; + std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic)); delete[] mBuffer; mBuffer = nullptr; diff --git a/code/AssetLib/IFC/IFCBoolean.cpp b/code/AssetLib/IFC/IFCBoolean.cpp index 6015920c1..86cac7f46 100644 --- a/code/AssetLib/IFC/IFCBoolean.cpp +++ b/code/AssetLib/IFC/IFCBoolean.cpp @@ -715,7 +715,7 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul // DIFFERENCE if (const Schema_2x3::IfcBooleanResult *const clip = boolean.ToPtr()) { if (clip->Operator != "DIFFERENCE") { - IFCImporter::LogWarn("encountered unsupported boolean operator: " + (std::string)clip->Operator); + IFCImporter::LogWarn("encountered unsupported boolean operator: ", (std::string)clip->Operator); return; } @@ -756,7 +756,7 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul ProcessBooleanExtrudedAreaSolidDifference(as, result, first_operand, conv); } } else { - IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is " + boolean.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is ", boolean.GetClassName()); } } diff --git a/code/AssetLib/IFC/IFCGeometry.cpp b/code/AssetLib/IFC/IFCGeometry.cpp index 664444443..6e645f1ae 100644 --- a/code/AssetLib/IFC/IFCGeometry.cpp +++ b/code/AssetLib/IFC/IFCGeometry.cpp @@ -216,7 +216,7 @@ void ProcessConnectedFaceSet(const Schema_2x3::IfcConnectedFaceSet& fset, TempMe } } else { - IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is " + bound.Bound->GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is ", bound.Bound->GetClassName()); continue; } @@ -729,7 +729,7 @@ void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh& ProcessRevolvedAreaSolid(*rev,meshout,conv); } else { - IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is " + swept.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is ", swept.GetClassName()); } } @@ -781,7 +781,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned return false; } else { - IFCImporter::LogWarn("skipping unknown IfcGeometricRepresentationItem entity, type is " + geo.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcGeometricRepresentationItem entity, type is ", geo.GetClassName()); return false; } diff --git a/code/AssetLib/IFC/IFCLoader.cpp b/code/AssetLib/IFC/IFCLoader.cpp index be100df57..daf2cc946 100644 --- a/code/AssetLib/IFC/IFCLoader.cpp +++ b/code/AssetLib/IFC/IFCLoader.cpp @@ -115,7 +115,7 @@ static const aiImporterDesc desc = { 0, 0, 0, - "ifc ifczip stp" + "ifc ifczip step stp" }; // ------------------------------------------------------------------------------------------------ @@ -243,12 +243,12 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy } if (!DefaultLogger::isNullLogger()) { - LogDebug("File schema is \'" + head.fileSchema + '\''); + LogDebug("File schema is \'", head.fileSchema, '\''); if (head.timestamp.length()) { - LogDebug("Timestamp \'" + head.timestamp + '\''); + LogDebug("Timestamp \'", head.timestamp, '\''); } if (head.app.length()) { - LogDebug("Application/Exporter identline is \'" + head.app + '\''); + LogDebug("Application/Exporter identline is \'", head.app, '\''); } } @@ -315,7 +315,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // this must be last because objects are evaluated lazily as we process them if (!DefaultLogger::isNullLogger()) { - LogDebug((Formatter::format(), "STEP: evaluated ", db->GetEvaluatedObjectCount(), " object records")); + LogDebug("STEP: evaluated ", db->GetEvaluatedObjectCount(), " object records"); } } @@ -403,7 +403,7 @@ void ResolveObjectPlacement(aiMatrix4x4 &m, const Schema_2x3::IfcObjectPlacement m = tmpM * m; } } else { - IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is ", place.GetClassName()); } } @@ -438,7 +438,7 @@ bool ProcessMappedItem(const Schema_2x3::IfcMappedItem &mapped, aiNode *nd_src, bool got = false; for (const Schema_2x3::IfcRepresentationItem &item : repr.Items) { if (!ProcessRepresentationItem(item, localmatid, meshes, conv)) { - IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated"); + IFCImporter::LogWarn("skipping mapped entity of type ", item.GetClassName(), ", no representations could be generated"); } else got = true; } @@ -567,7 +567,7 @@ typedef std::map Metadata; // ------------------------------------------------------------------------------------------------ void ProcessMetadata(const Schema_2x3::ListOf, 1, 0> &set, ConversionData &conv, Metadata &properties, - const std::string &prefix = "", + const std::string &prefix = std::string(), unsigned int nest = 0) { for (const Schema_2x3::IfcProperty &property : set) { const std::string &key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name; @@ -618,7 +618,7 @@ void ProcessMetadata(const Schema_2x3::ListOfHasProperties, conv, properties, key, nest + 1); } } else { - properties[key] = ""; + properties[key] = std::string(); } } } @@ -856,7 +856,7 @@ void ProcessSpatialStructures(ConversionData &conv) { if (!prod) { continue; } - IFCImporter::LogVerboseDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType ? " which is of type " + prod->ObjectType.Get() : "")); + IFCImporter::LogVerboseDebug("looking at spatial structure `", (prod->Name ? prod->Name.Get() : "unnamed"), "`", (prod->ObjectType ? " which is of type " + prod->ObjectType.Get() : "")); // the primary sites are referenced by an IFCRELAGGREGATES element which assigns them to the IFCPRODUCT const STEP::DB::RefMap &refs = conv.db.GetRefs(); diff --git a/code/AssetLib/IFC/IFCMaterial.cpp b/code/AssetLib/IFC/IFCMaterial.cpp index e0146b887..2a79f0754 100644 --- a/code/AssetLib/IFC/IFCMaterial.cpp +++ b/code/AssetLib/IFC/IFCMaterial.cpp @@ -64,7 +64,7 @@ static int ConvertShadingMode(const std::string& name) { else if (name == "PHONG") { return aiShadingMode_Phong; } - IFCImporter::LogWarn("shading mode "+name+" not recognized by Assimp, using Phong instead"); + IFCImporter::LogWarn("shading mode ", name, " not recognized by Assimp, using Phong instead"); return aiShadingMode_Phong; } @@ -145,7 +145,7 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat // not found, create new material const std::string side = static_cast(surf->Side); if( side != "BOTH" ) { - IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side); + IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: ", side); } std::unique_ptr mat(new aiMaterial()); diff --git a/code/AssetLib/IFC/IFCProfile.cpp b/code/AssetLib/IFC/IFCProfile.cpp index f33f8cdbe..4235be181 100644 --- a/code/AssetLib/IFC/IFCProfile.cpp +++ b/code/AssetLib/IFC/IFCProfile.cpp @@ -68,7 +68,7 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, Convers { std::unique_ptr cv(Curve::Convert(curve,conv)); if (!cv) { - IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is ", curve.GetClassName()); return false; } @@ -78,7 +78,7 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, Convers bc->SampleDiscrete(meshout); } catch(const CurveError& cv) { - IFCImporter::LogError(cv.mStr + " (error occurred while processing curve)"); + IFCImporter::LogError(cv.mStr, " (error occurred while processing curve)"); return false; } meshout.mVertcnt.push_back(static_cast(meshout.mVerts.size())); @@ -152,7 +152,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de meshout.mVertcnt.push_back(12); } else { - IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is ", def.GetClassName()); return; } @@ -174,7 +174,7 @@ bool ProcessProfile(const Schema_2x3::IfcProfileDef& prof, TempMesh& meshout, Co ProcessParametrizedProfile(*cparam,meshout,conv); } else { - IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is ", prof.GetClassName()); return false; } meshout.RemoveAdjacentDuplicates(); diff --git a/code/AssetLib/IFC/IFCUtil.cpp b/code/AssetLib/IFC/IFCUtil.cpp index b451262e9..8c37cebed 100644 --- a/code/AssetLib/IFC/IFCUtil.cpp +++ b/code/AssetLib/IFC/IFCUtil.cpp @@ -506,7 +506,7 @@ IfcFloat ConvertSIPrefix(const std::string& prefix) return 1e-18f; } else { - IFCImporter::LogError("Unrecognized SI prefix: " + prefix); + IFCImporter::LogError("Unrecognized SI prefix: ", prefix); return 1; } } diff --git a/code/AssetLib/Irr/IRRLoader.cpp b/code/AssetLib/Irr/IRRLoader.cpp index 9c1136499..cb383e936 100644 --- a/code/AssetLib/Irr/IRRLoader.cpp +++ b/code/AssetLib/Irr/IRRLoader.cpp @@ -639,7 +639,7 @@ void IRRImporter::GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene, // graph we're currently building aiScene *localScene = batch.GetImport(root->id); if (!localScene) { - ASSIMP_LOG_ERROR("IRR: Unable to load external file: " + root->meshPath); + ASSIMP_LOG_ERROR("IRR: Unable to load external file: ", root->meshPath); break; } attach.push_back(AttachmentInfo(localScene, rootOut)); @@ -859,13 +859,13 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // Check whether we can read from the file if (file.get() == nullptr) { - throw DeadlyImportError("Failed to open IRR file " + pFile + ""); + throw DeadlyImportError("Failed to open IRR file ", pFile); } // Construct the irrXML parser XmlParser st; if (!st.parse( file.get() )) { - return; + throw DeadlyImportError("XML parse error while loading IRR file ", pFile); } pugi::xml_node rootElement = st.getRootNode(); @@ -963,7 +963,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy ASSIMP_LOG_ERROR("IRR: Billboards are not supported by Assimp"); nd = new Node(Node::DUMMY); } else { - ASSIMP_LOG_WARN("IRR: Found unknown node: " + std::string(attrib.name())); + ASSIMP_LOG_WARN("IRR: Found unknown node: ", attrib.name()); /* We skip the contents of nodes we don't know. * We parse the transformation and all animators @@ -1181,7 +1181,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy lights.pop_back(); curNode->type = Node::DUMMY; - ASSIMP_LOG_ERROR("Ignoring light of unknown type: " + prop.value); + ASSIMP_LOG_ERROR("Ignoring light of unknown type: ", prop.value); } } else if ((prop.name == "Mesh" && Node::MESH == curNode->type) || Node::ANIMMESH == curNode->type) { @@ -1225,7 +1225,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy } else if (prop.value == "followSpline") { curAnim->type = Animator::FOLLOW_SPLINE; } else { - ASSIMP_LOG_WARN("IRR: Ignoring unknown animator: " + prop.value); + ASSIMP_LOG_WARN("IRR: Ignoring unknown animator: ", prop.value); curAnim->type = Animator::UNKNOWN; } diff --git a/code/AssetLib/Irr/IRRMeshLoader.cpp b/code/AssetLib/Irr/IRRMeshLoader.cpp index 97d74026f..9350e07b8 100644 --- a/code/AssetLib/Irr/IRRMeshLoader.cpp +++ b/code/AssetLib/Irr/IRRMeshLoader.cpp @@ -135,12 +135,12 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile, // Check whether we can read from the file if (file.get() == NULL) - throw DeadlyImportError("Failed to open IRRMESH file " + pFile + ""); + throw DeadlyImportError("Failed to open IRRMESH file ", pFile); // Construct the irrXML parser XmlParser parser; if (!parser.parse( file.get() )) { - return; + throw DeadlyImportError("XML parse error while loading IRRMESH file ", pFile); } XmlNode root = parser.getRootNode(); diff --git a/code/AssetLib/Irr/IRRShared.cpp b/code/AssetLib/Irr/IRRShared.cpp index b119b063a..b42f34b65 100644 --- a/code/AssetLib/Irr/IRRShared.cpp +++ b/code/AssetLib/Irr/IRRShared.cpp @@ -260,7 +260,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { prop.value == "parallaxmap_trans_add") { matFlags = AI_IRRMESH_MAT_normalmap_ta; } else { - ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: " + prop.value); + ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: ", prop.value); } } diff --git a/code/AssetLib/LWO/LWOBLoader.cpp b/code/AssetLib/LWO/LWOBLoader.cpp index 2654eccf4..8ef40fc21 100644 --- a/code/AssetLib/LWO/LWOBLoader.cpp +++ b/code/AssetLib/LWO/LWOBLoader.cpp @@ -242,7 +242,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i else { // procedural or gradient, not supported - ASSIMP_LOG_ERROR_F("LWOB: Unsupported legacy texture: ", type); + ASSIMP_LOG_ERROR("LWOB: Unsupported legacy texture: ", type); } return tex; diff --git a/code/AssetLib/LWO/LWOFileData.h b/code/AssetLib/LWO/LWOFileData.h index 70642c537..93ac1a236 100644 --- a/code/AssetLib/LWO/LWOFileData.h +++ b/code/AssetLib/LWO/LWOFileData.h @@ -502,7 +502,7 @@ struct Surface { Surface() : mColor(0.78431f, 0.78431f, 0.78431f), bDoubleSided(false), mDiffuseValue(1.f), mSpecularValue(0.f), mTransparency(0.f), mGlossiness(0.4f), mLuminosity(0.f), mColorHighlights(0.f), mMaximumSmoothAngle(0.f) // 0 == not specified, no smoothing , - mVCMap(""), + mVCMap(), mVCMapType(AI_LWO_RGBA), mIOR(1.f) // vakuum , diff --git a/code/AssetLib/LWO/LWOLoader.cpp b/code/AssetLib/LWO/LWOLoader.cpp index a9fa08f11..bc62152c5 100644 --- a/code/AssetLib/LWO/LWOLoader.cpp +++ b/code/AssetLib/LWO/LWOLoader.cpp @@ -961,7 +961,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { switch (type) { case AI_LWO_TXUV: if (dims != 2) { - ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'" + name + "\' with !2 components"); + ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'", name, "\' with !2 components"); return; } base = FindEntry(mCurLayer->mUVChannels, name, perPoly); @@ -969,7 +969,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { case AI_LWO_WGHT: case AI_LWO_MNVW: if (dims != 1) { - ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'" + name + "\' with !1 components"); + ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'", name, "\' with !1 components"); return; } base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels : mCurLayer->mSWeightChannels), name, perPoly); @@ -977,7 +977,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { case AI_LWO_RGB: case AI_LWO_RGBA: if (dims != 3 && dims != 4) { - ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'" + name + "\' with a dimension > 4 or < 3"); + ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'", name, "\' with a dimension > 4 or < 3"); return; } base = FindEntry(mCurLayer->mVColorChannels, name, perPoly); @@ -1006,7 +1006,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { if (name == "APS.Level") { // XXX handle this (seems to be subdivision-related). } - ASSIMP_LOG_WARN_F("LWO2: Skipping unknown VMAP/VMAD channel \'", name, "\'"); + ASSIMP_LOG_WARN("LWO2: Skipping unknown VMAP/VMAD channel \'", name, "\'"); return; }; base->Allocate((unsigned int)mCurLayer->mTempPoints.size()); @@ -1026,7 +1026,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs; if (idx >= numPoints) { - ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAP/VMAD entry \'", name, "\', vertex index is out of range"); + ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAP/VMAD entry \'", name, "\', vertex index is out of range"); mFileBuffer += base->dims << 2u; continue; } @@ -1036,7 +1036,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { // we have already a VMAP entry for this vertex - thus // we need to duplicate the corresponding polygon. if (polyIdx >= numFaces) { - ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAD entry \'", name, "\', polygon index is out of range"); + ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAD entry \'", name, "\', polygon index is out of range"); mFileBuffer += base->dims << 2u; continue; } @@ -1076,7 +1076,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { CreateNewEntry(mCurLayer->mNormals, srcIdx); } if (!had) { - ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAD entry \'", name, "\', vertex index wasn't found in that polygon"); + ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAD entry \'", name, "\', vertex index wasn't found in that polygon"); ai_assert(had); } } diff --git a/code/AssetLib/LWO/LWOMaterial.cpp b/code/AssetLib/LWO/LWOMaterial.cpp index 9d51438d7..178f24265 100644 --- a/code/AssetLib/LWO/LWOMaterial.cpp +++ b/code/AssetLib/LWO/LWOMaterial.cpp @@ -335,7 +335,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) { m = aiShadingMode_Fresnel; break; } else { - ASSIMP_LOG_WARN_F("LWO2: Unknown surface shader: ", shader.functionName); + ASSIMP_LOG_WARN("LWO2: Unknown surface shader: ", shader.functionName); } } if (surf.mMaximumSmoothAngle <= 0.0) @@ -711,7 +711,7 @@ void LWOImporter::LoadLWO2Surface(unsigned int size) { } } if (derived.size()) { - ASSIMP_LOG_WARN("LWO2: Unable to find source surface: " + derived); + ASSIMP_LOG_WARN("LWO2: Unable to find source surface: ", derived); } } diff --git a/code/AssetLib/LWS/LWSLoader.cpp b/code/AssetLib/LWS/LWSLoader.cpp index a75b90ef9..d469a1064 100644 --- a/code/AssetLib/LWS/LWSLoader.cpp +++ b/code/AssetLib/LWS/LWSLoader.cpp @@ -346,7 +346,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vectormRootNode->mNumChildren == 1) { @@ -538,7 +538,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // get file format version and print to log ++it; unsigned int version = strtoul10((*it).tokens[0].c_str()); - ASSIMP_LOG_INFO("LWS file format version is " + (*it).tokens[0]); + ASSIMP_LOG_INFO("LWS file format version is ", (*it).tokens[0]); first = 0.; last = 60.; fps = 25.; // seems to be a good default frame rate diff --git a/code/AssetLib/LWS/LWSLoader.h b/code/AssetLib/LWS/LWSLoader.h index 93251cd5d..cd7a0543e 100644 --- a/code/AssetLib/LWS/LWSLoader.h +++ b/code/AssetLib/LWS/LWSLoader.h @@ -88,7 +88,7 @@ struct NodeDesc { id(), number(0), parent(0), - name(""), + name(), isPivotSet(false), lightColor(1.f, 1.f, 1.f), lightIntensity(1.f), diff --git a/code/AssetLib/M3D/M3DExporter.cpp b/code/AssetLib/M3D/M3DExporter.cpp index 856932947..bcac1d98a 100644 --- a/code/AssetLib/M3D/M3DExporter.cpp +++ b/code/AssetLib/M3D/M3DExporter.cpp @@ -294,21 +294,17 @@ void ExportSceneM3D( // Worker function for exporting a scene to ASCII A3D. // Prototyped and registered in Exporter.cpp void ExportSceneM3DA( - const char *, - IOSystem *, - const aiScene *, - const ExportProperties * + const char *pFile, + IOSystem *pIOSystem, + const aiScene *pScene, + const ExportProperties *pProperties ) { -#ifdef M3D_ASCII // initialize the exporter M3DExporter exporter(pScene, pProperties); // perform ascii export exporter.doExport(pFile, pIOSystem, true); -#else - throw DeadlyExportError("Assimp configured without M3D_ASCII support"); -#endif } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/M3D/M3DImporter.cpp b/code/AssetLib/M3D/M3DImporter.cpp index 8cbda23cb..38bbd1d4a 100644 --- a/code/AssetLib/M3D/M3DImporter.cpp +++ b/code/AssetLib/M3D/M3DImporter.cpp @@ -95,11 +95,7 @@ static const aiImporterDesc desc = { 0, 0, 0, -#ifdef M3D_ASCII "m3d a3d" -#else - "m3d" -#endif }; namespace Assimp { @@ -119,9 +115,7 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c const std::string extension = GetExtension(pFile); if (extension == "m3d" -#ifdef M3D_ASCII || extension == "a3d" -#endif ) return true; else if (!extension.length() || checkSig) { @@ -137,13 +131,11 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c */ std::unique_ptr pStream(pIOHandler->Open(pFile, "rb")); unsigned char data[4]; - if (4 != pStream->Read(data, 1, 4)) { + if (!pStream || 4 != pStream->Read(data, 1, 4)) { return false; } return !memcmp(data, "3DMO", 4) /* bin */ -#ifdef M3D_ASCII || !memcmp(data, "3dmo", 4) /* ASCII */ -#endif ; } return false; @@ -176,12 +168,10 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys if (!memcmp(buffer.data(), "3DMO", 4) && memcmp(buffer.data() + 4, &fileSize, 4)) { throw DeadlyImportError("Bad binary header in file ", file, "."); } -#ifdef M3D_ASCII // make sure there's a terminator zero character, as input must be ASCIIZ if (!memcmp(buffer.data(), "3dmo", 4)) { buffer.push_back(0); } -#endif // Get the path for external assets std::string folderName("./"); @@ -194,7 +184,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys } //DefaultLogger::create("/dev/stderr", Logger::VERBOSE); - ASSIMP_LOG_DEBUG_F("M3D: loading ", file); + ASSIMP_LOG_DEBUG("M3D: loading ", file); // let the C SDK do the hard work for us M3DWrapper m3d(pIOHandler, buffer); @@ -210,7 +200,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys pScene->mRootNode->mNumChildren = 0; mScene = pScene; - ASSIMP_LOG_DEBUG("M3D: root node " + m3d.Name()); + ASSIMP_LOG_DEBUG("M3D: root node ", m3d.Name()); // now we just have to fill up the Assimp structures in pScene importMaterials(m3d); @@ -240,7 +230,7 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) { mScene->mNumMaterials = m3d->nummaterial + 1; mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials]; - ASSIMP_LOG_DEBUG_F("M3D: importMaterials ", mScene->mNumMaterials); + ASSIMP_LOG_DEBUG("M3D: importMaterials ", mScene->mNumMaterials); // add a default material as first aiMaterial *mat = new aiMaterial; @@ -335,7 +325,7 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) { ai_assert(m3d); mScene->mNumTextures = m3d->numtexture; - ASSIMP_LOG_DEBUG_F("M3D: importTextures ", mScene->mNumTextures); + ASSIMP_LOG_DEBUG("M3D: importTextures ", mScene->mNumTextures); if (!m3d->numtexture || !m3d->texture) { return; @@ -390,7 +380,7 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) { // individually. In assimp there're per mesh vertex and UV lists, and they must be // indexed simultaneously. void M3DImporter::importMeshes(const M3DWrapper &m3d) { - ASSIMP_LOG_DEBUG_F("M3D: importMeshes ", m3d->numface); + ASSIMP_LOG_DEBUG("M3D: importMeshes ", m3d->numface); if (!m3d->numface || !m3d->face || !m3d->numvertex || !m3d->vertex) { return; @@ -509,7 +499,7 @@ void M3DImporter::importBones(const M3DWrapper &m3d, unsigned int parentid, aiNo ai_assert(mScene != nullptr); ai_assert(m3d); - ASSIMP_LOG_DEBUG_F("M3D: importBones ", m3d->numbone, " parentid ", (int)parentid); + ASSIMP_LOG_DEBUG("M3D: importBones ", m3d->numbone, " parentid ", (int)parentid); if (!m3d->numbone || !m3d->bone) { return; @@ -550,7 +540,7 @@ void M3DImporter::importAnimations(const M3DWrapper &m3d) { mScene->mNumAnimations = m3d->numaction; - ASSIMP_LOG_DEBUG_F("M3D: importAnimations ", mScene->mNumAnimations); + ASSIMP_LOG_DEBUG("M3D: importAnimations ", mScene->mNumAnimations); if (!m3d->numaction || !m3d->action || !m3d->numbone || !m3d->bone || !m3d->vertex) { return; @@ -713,7 +703,7 @@ void M3DImporter::populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector ai_assert(vertexids != nullptr); ai_assert(m3d); - ASSIMP_LOG_DEBUG_F("M3D: populateMesh numvertices ", vertices->size(), " numfaces ", faces->size(), + ASSIMP_LOG_DEBUG("M3D: populateMesh numvertices ", vertices->size(), " numfaces ", faces->size(), " numnormals ", normals->size(), " numtexcoord ", texcoords->size(), " numbones ", m3d->numbone); if (vertices->size() && faces->size()) { diff --git a/code/AssetLib/M3D/M3DWrapper.h b/code/AssetLib/M3D/M3DWrapper.h index 5c370e607..782e908d2 100644 --- a/code/AssetLib/M3D/M3DWrapper.h +++ b/code/AssetLib/M3D/M3DWrapper.h @@ -54,7 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Assimp specific M3D configuration. Comment out these defines to remove functionality //#define ASSIMP_USE_M3D_READFILECB -//#define M3D_ASCII #include "m3d.h" diff --git a/code/AssetLib/M3D/m3d.h b/code/AssetLib/M3D/m3d.h index dfc30aec3..68265959e 100644 --- a/code/AssetLib/M3D/m3d.h +++ b/code/AssetLib/M3D/m3d.h @@ -231,14 +231,9 @@ enum { typedef struct { uint8_t format; uint8_t id; -#ifdef M3D_ASCII #define M3D_PROPERTYDEF(f, i, n) \ { (f), (i), (char *)(n) } char *key; -#else -#define M3D_PROPERTYDEF(f, i, n) \ - { (f), (i) } -#endif } m3dpd_t; /* material property types */ @@ -376,18 +371,11 @@ enum { #define M3D_CMDMAXARG 8 /* if you increase this, add more arguments to the macro below */ typedef struct { -#ifdef M3D_ASCII #define M3D_CMDDEF(t, n, p, a, b, c, d, e, f, g, h) \ { \ (char *)(n), (p), { (a), (b), (c), (d), (e), (f), (g), (h) } \ } char *key; -#else -#define M3D_CMDDEF(t, n, p, a, b, c, d, e, f, g, h) \ - { \ - (p), { (a), (b), (c), (d), (e), (f), (g), (h) } \ - } -#endif uint8_t p; uint8_t a[M3D_CMDMAXARG]; } m3dcd_t; @@ -2059,15 +2047,13 @@ unsigned char *_m3dstbi_zlib_compress(unsigned char *data, int data_len, int *ou #define M3D_CHUNKMAGIC(m, a, b, c, d) ((m)[0] == (a) && (m)[1] == (b) && (m)[2] == (c) && (m)[3] == (d)) -#ifdef M3D_ASCII #include /* sprintf and strtod cares about number locale */ #include /* get sprintf */ -#endif #ifdef M3D_PROFILING #include #endif -#if !defined(M3D_NOIMPORTER) && defined(M3D_ASCII) +#if !defined(M3D_NOIMPORTER) /* helper functions for the ASCII parser */ static char *_m3d_findarg(char *s) { while (s && *s && *s != ' ' && *s != '\t' && *s != '\r' && *s != '\n') @@ -2118,7 +2104,7 @@ static char *_m3d_getfloat(char *s, M3D_FLOAT *ret) { return _m3d_findarg(e); } #endif -#if !defined(M3D_NODUP) && (!defined(M3D_NOIMPORTER) || defined(M3D_ASCII) || defined(M3D_EXPORTER)) +#if !defined(M3D_NODUP) && (!defined(M3D_NOIMPORTER) || defined(M3D_EXPORTER)) /* helper function to create safe strings */ char *_m3d_safestr(char *in, int morelines) { char *out, *o, *i = in; @@ -2426,21 +2412,17 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d #ifndef M3D_NOWEIGHTS m3ds_t *sk; #endif -#ifdef M3D_ASCII m3ds_t s; M3D_INDEX bi[M3D_BONEMAXLEVEL + 1], level; const char *ol; char *ptr, *pe, *fn; -#endif #ifdef M3D_PROFILING struct timeval tv0, tv1, tvd; gettimeofday(&tv0, NULL); #endif if (!data || (!M3D_CHUNKMAGIC(data, '3', 'D', 'M', 'O') -#ifdef M3D_ASCII && !M3D_CHUNKMAGIC(data, '3', 'd', 'm', 'o') -#endif )) return NULL; model = (m3d_t *)M3D_MALLOC(sizeof(m3d_t)); @@ -2457,7 +2439,6 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d model->texture = mtllib->texture; model->flags |= M3D_FLG_MTLLIB; } -#ifdef M3D_ASCII /* ASCII variant? */ if (M3D_CHUNKMAGIC(data, '3', 'd', 'm', 'o')) { model->errcode = M3D_ERR_BADFILE; @@ -3034,7 +3015,6 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d setlocale(LC_NUMERIC, ol); goto postprocess; } -#endif /* Binary variant */ if (!M3D_CHUNKMAGIC(data + 8, 'H', 'E', 'A', 'D')) { buff = (unsigned char *)stbi_zlib_decode_malloc_guesssize_headerflag((const char *)data + 8, ((m3dchunk_t *)data)->length - 8, @@ -3698,9 +3678,7 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d } } /* calculate normals, normalize skin weights, create bone/vertex cross-references and calculate transform matrices */ -#ifdef M3D_ASCII postprocess: -#endif if (model) { M3D_LOG("Post-process"); #ifdef M3D_PROFILING @@ -3989,7 +3967,6 @@ void m3d_free(m3d_t *model) { unsigned int i, j; if (!model) return; -#ifdef M3D_ASCII /* if model imported from ASCII, we have to free all strings as well */ if (model->flags & M3D_FLG_FREESTR) { if (model->name) M3D_FREE(model->name); @@ -4047,7 +4024,6 @@ void m3d_free(m3d_t *model) { if (model->preview.data) M3D_FREE(model->preview.data); } -#endif if (model->flags & M3D_FLG_FREERAW) M3D_FREE(model->raw); if (model->tmap) M3D_FREE(model->tmap); @@ -4315,7 +4291,6 @@ static void _m3d_round(int quality, m3dv_t *src, m3dv_t *dst) { if (dst->w == (M3D_FLOAT)-0.0) dst->w = (M3D_FLOAT)0.0; } -#ifdef M3D_ASCII /* add a bone to ascii output */ static char *_m3d_prtbone(char *ptr, m3db_t *bone, M3D_INDEX numbone, M3D_INDEX parent, uint32_t level, M3D_INDEX *vrtxidx) { uint32_t i, j; @@ -4334,16 +4309,13 @@ static char *_m3d_prtbone(char *ptr, m3db_t *bone, M3D_INDEX numbone, M3D_INDEX } return ptr; } -#endif /** * Function to encode an in-memory model into on storage Model 3D format */ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size) { -#ifdef M3D_ASCII const char *ol; char *ptr; -#endif char vc_s, vi_s, si_s, ci_s, ti_s, bi_s, nb_s, sk_s, fc_s, hi_s, fi_s; char *sn = NULL, *sl = NULL, *sa = NULL, *sd = NULL; unsigned char *out = NULL, *z = NULL, weights[M3D_NUMBONE], *norm = NULL; @@ -4369,9 +4341,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size return NULL; } model->errcode = M3D_SUCCESS; -#ifdef M3D_ASCII if (flags & M3D_EXP_ASCII) quality = M3D_EXP_DOUBLE; -#endif vrtxidx = (M3D_INDEX *)M3D_MALLOC(model->numvertex * sizeof(M3D_INDEX)); if (!vrtxidx) goto memerr; memset(vrtxidx, 255, model->numvertex * sizeof(M3D_INDEX)); @@ -4800,7 +4770,6 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size } M3D_LOG("Serializing model"); -#ifdef M3D_ASCII if (flags & M3D_EXP_ASCII) { /* use CRLF to make model creators on Win happy... */ sd = _m3d_safestr(model->desc, 1); @@ -5073,7 +5042,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size ptr += sprintf(ptr, "\r\n"); } /* mathematical shapes face */ - if (model->numshape !(flags & M3D_EXP_NOFACE)) { + if (model->numshape && (!(flags & M3D_EXP_NOFACE))) { for (j = 0; j < model->numshape; j++) { sn = _m3d_safestr(model->shape[j].name, 0); if (!sn) { @@ -5287,7 +5256,6 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size if (!out) goto memerr; out[len] = 0; } else -#endif { /* stricly only use LF (newline) in binary */ sd = _m3d_safestr(model->desc, 3); diff --git a/code/AssetLib/MD2/MD2Loader.cpp b/code/AssetLib/MD2/MD2Loader.cpp index 9ccbcdfca..b7bf24ef7 100644 --- a/code/AssetLib/MD2/MD2Loader.cpp +++ b/code/AssetLib/MD2/MD2Loader.cpp @@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include @@ -148,46 +149,39 @@ void MD2Importer::ValidateHeader( ) if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE && m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE) { - char szBuffer[5]; - szBuffer[0] = ((char*)&m_pcHeader->magic)[0]; - szBuffer[1] = ((char*)&m_pcHeader->magic)[1]; - szBuffer[2] = ((char*)&m_pcHeader->magic)[2]; - szBuffer[3] = ((char*)&m_pcHeader->magic)[3]; - szBuffer[4] = '\0'; - - throw DeadlyImportError("Invalid MD2 magic word: should be IDP2, the " - "magic word found is " + std::string(szBuffer)); + throw DeadlyImportError("Invalid MD2 magic word: expected IDP2, found ", + ai_str_toprintable((char *)&m_pcHeader->magic, 4)); } // check file format version if (m_pcHeader->version != 8) - ASSIMP_LOG_WARN( "Unsupported md2 file version. Continuing happily ..."); + ASSIMP_LOG_WARN( "Unsupported MD2 file version. Continuing happily ..."); // check some values whether they are valid if (0 == m_pcHeader->numFrames) - throw DeadlyImportError( "Invalid md2 file: NUM_FRAMES is 0"); + throw DeadlyImportError( "Invalid MD2 file: NUM_FRAMES is 0"); if (m_pcHeader->offsetEnd > (uint32_t)fileSize) - throw DeadlyImportError( "Invalid md2 file: File is too small"); + throw DeadlyImportError( "Invalid MD2 file: File is too small"); if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) { - throw DeadlyImportError("Invalid MD2 header: too many skins, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many skins, would overflow"); } if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) { - throw DeadlyImportError("Invalid MD2 header: too many vertices, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many vertices, would overflow"); } if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) { - throw DeadlyImportError("Invalid MD2 header: too many texcoords, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many texcoords, would overflow"); } if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) { - throw DeadlyImportError("Invalid MD2 header: too many triangles, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many triangles, would overflow"); } if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) { - throw DeadlyImportError("Invalid MD2 header: too many frames, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many frames, would overflow"); } // -1 because Frame already contains one @@ -199,7 +193,7 @@ void MD2Importer::ValidateHeader( ) m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize || m_pcHeader->offsetEnd > fileSize) { - throw DeadlyImportError("Invalid MD2 header: some offsets are outside the file"); + throw DeadlyImportError("Invalid MD2 header: Some offsets are outside the file"); } if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS) @@ -210,7 +204,7 @@ void MD2Importer::ValidateHeader( ) ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports"); if (m_pcHeader->numFrames <= configFrameID ) - throw DeadlyImportError("The requested frame is not existing the file"); + throw DeadlyImportError("MD2: The requested frame (", configFrameID, ") does not exist in the file"); } // ------------------------------------------------------------------------------------------------ @@ -433,10 +427,6 @@ void MD2Importer::InternReadFile( const std::string& pFile, aiVector3D& vNormal = pcMesh->mNormals[iCurrent]; LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal); - // flip z and y to become right-handed - std::swap((float&)vNormal.z,(float&)vNormal.y); - std::swap((float&)vec.z,(float&)vec.y); - if (m_pcHeader->numTexCoords) { // validate texture coordinates iIndex = pcTriangles[i].textureIndices[c]; @@ -454,7 +444,15 @@ void MD2Importer::InternReadFile( const std::string& pFile, } pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent; } + // flip the face order + std::swap( pScene->mMeshes[0]->mFaces[i].mIndices[0], pScene->mMeshes[0]->mFaces[i].mIndices[2] ); } + // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4( + 1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f); } #endif // !! ASSIMP_BUILD_NO_MD2_IMPORTER diff --git a/code/AssetLib/MD2/MD2NormalTable.h b/code/AssetLib/MD2/MD2NormalTable.h index 3eff0d666..b2330d862 100644 --- a/code/AssetLib/MD2/MD2NormalTable.h +++ b/code/AssetLib/MD2/MD2NormalTable.h @@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_MDL_NORMALTABLE_H_INC -float g_avNormals[162][3] = { +const float g_avNormals[162][3] = { { -0.525731f, 0.000000f, 0.850651f }, { -0.442863f, 0.238856f, 0.864188f }, { -0.295242f, 0.000000f, 0.955423f }, diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp index 53a0eea41..abaabe47f 100644 --- a/code/AssetLib/MD3/MD3Loader.cpp +++ b/code/AssetLib/MD3/MD3Loader.cpp @@ -101,7 +101,7 @@ Q3Shader::BlendFunc StringToBlendFunc(const std::string &m) { if (m == "GL_ONE_MINUS_DST_COLOR") { return Q3Shader::BLEND_GL_ONE_MINUS_DST_COLOR; } - ASSIMP_LOG_ERROR("Q3Shader: Unknown blend function: " + m); + ASSIMP_LOG_ERROR("Q3Shader: Unknown blend function: ", m); return Q3Shader::BLEND_NONE; } @@ -112,7 +112,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem * if (!file.get()) return false; // if we can't access the file, don't worry and return - ASSIMP_LOG_INFO_F("Loading Quake3 shader file ", pFile); + ASSIMP_LOG_INFO("Loading Quake3 shader file ", pFile); // read file in memory const size_t s = file->FileSize(); @@ -226,7 +226,7 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io) if (!file.get()) return false; // if we can't access the file, don't worry and return - ASSIMP_LOG_INFO("Loading Quake3 skin file " + pFile); + ASSIMP_LOG_INFO("Loading Quake3 skin file ", pFile); // read file in memory const size_t s = file->FileSize(); @@ -706,7 +706,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy } filename = mFile.substr(s), path = mFile.substr(0, s); for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) { - *it = static_cast(tolower(*it)); + *it = static_cast(tolower(static_cast(*it))); } // Load multi-part model file, if necessary @@ -857,7 +857,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy if (it != skins.textures.end()) { texture_name = &*(_texture_name = (*it).second).begin(); - ASSIMP_LOG_VERBOSE_DEBUG_F("MD3: Assigning skin texture ", (*it).second, " to surface ", pcSurfaces->NAME); + ASSIMP_LOG_VERBOSE_DEBUG("MD3: Assigning skin texture ", (*it).second, " to surface ", pcSurfaces->NAME); (*it).resolved = true; // mark entry as resolved } @@ -891,9 +891,9 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy if (dit != shaders.blocks.end()) { // We made it! shader = &*dit; - ASSIMP_LOG_INFO("Found shader record for " + without_ext); + ASSIMP_LOG_INFO("Found shader record for ", without_ext); } else { - ASSIMP_LOG_WARN("Unable to find shader record for " + without_ext); + ASSIMP_LOG_WARN("Unable to find shader record for ", without_ext); } } @@ -1011,7 +1011,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy if (!DefaultLogger::isNullLogger()) { for (std::list::const_iterator it = skins.textures.begin(); it != skins.textures.end(); ++it) { if (!(*it).resolved) { - ASSIMP_LOG_ERROR_F("MD3: Failed to match skin ", (*it).first, " to surface ", (*it).second); + ASSIMP_LOG_ERROR("MD3: Failed to match skin ", (*it).first, " to surface ", (*it).second); } } } diff --git a/code/AssetLib/MD5/MD5Loader.cpp b/code/AssetLib/MD5/MD5Loader.cpp index b99638cd2..0d9c77b71 100644 --- a/code/AssetLib/MD5/MD5Loader.cpp +++ b/code/AssetLib/MD5/MD5Loader.cpp @@ -345,7 +345,7 @@ void MD5Importer::LoadMD5MeshFile() { // Check whether we can read from the file if (file.get() == nullptr || !file->FileSize()) { - ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + filename); + ASSIMP_LOG_WARN("Failed to access MD5MESH file: ", filename); return; } mHadMD5Mesh = true; @@ -567,7 +567,7 @@ void MD5Importer::LoadMD5AnimFile() { // Check whether we can read from the file if (!file.get() || !file->FileSize()) { - ASSIMP_LOG_WARN("Failed to read MD5ANIM file: " + pFile); + ASSIMP_LOG_WARN("Failed to read MD5ANIM file: ", pFile); return; } diff --git a/code/AssetLib/MDC/MDCLoader.cpp b/code/AssetLib/MDC/MDCLoader.cpp index 17a349768..8f089bbd8 100644 --- a/code/AssetLib/MDC/MDCLoader.cpp +++ b/code/AssetLib/MDC/MDCLoader.cpp @@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include @@ -143,16 +144,8 @@ void MDCImporter::ValidateHeader() { if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE && pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) { - char szBuffer[5]; - szBuffer[0] = ((char *)&pcHeader->ulIdent)[0]; - szBuffer[1] = ((char *)&pcHeader->ulIdent)[1]; - szBuffer[2] = ((char *)&pcHeader->ulIdent)[2]; - szBuffer[3] = ((char *)&pcHeader->ulIdent)[3]; - szBuffer[4] = '\0'; - - throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the " - "magic word found is " + - std::string(szBuffer)); + throw DeadlyImportError("Invalid MDC magic word: expected IDPC, found ", + ai_str_toprintable((char *)&pcHeader->ulIdent, 4)); } if (pcHeader->ulVersion != AI_MDC_VERSION) { @@ -465,6 +458,13 @@ void MDCImporter::InternReadFile( pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0)); } } + + // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4( + 1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f); } #endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER diff --git a/code/AssetLib/MDC/MDCNormalTable.h b/code/AssetLib/MDC/MDCNormalTable.h index f47e97f33..c96eba7bd 100644 --- a/code/AssetLib/MDC/MDCNormalTable.h +++ b/code/AssetLib/MDC/MDCNormalTable.h @@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define MDC_NORMAL_TABLE_INCLUDED /* mdc decoding normal table */ -float mdcNormals[ 256 ][ 3 ] = +const float mdcNormals[ 256 ][ 3 ] = { { 1.000000f, 0.000000f, 0.000000f }, { 0.980785f, 0.195090f, 0.000000f }, diff --git a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp index 4df0d0d1d..e6576b344 100644 --- a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp @@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #ifdef MDL_HALFLIFE_LOG_WARN_HEADER #undef MDL_HALFLIFE_LOG_WARN_HEADER @@ -868,7 +869,7 @@ void HL1MDLLoader::read_meshes() { scene_mesh->mNormals[v] = bind_pose_normals[pTrivert->normindex]; scene_mesh->mTextureCoords[0][v] = aiVector3D( pTrivert->s * texcoords_s_scale, - pTrivert->t * texcoords_t_scale, 0); + pTrivert->t * -texcoords_t_scale, 0); } // Add face and indices. @@ -879,9 +880,9 @@ void HL1MDLLoader::read_meshes() { aiFace *face = &scene_mesh->mFaces[f]; face->mNumIndices = 3; face->mIndices = new unsigned int[3]; - face->mIndices[0] = mesh_faces[f].v0; + face->mIndices[0] = mesh_faces[f].v2; face->mIndices[1] = mesh_faces[f].v1; - face->mIndices[2] = mesh_faces[f].v2; + face->mIndices[2] = mesh_faces[f].v0; } // Add mesh bones. @@ -1342,7 +1343,7 @@ bool HL1MDLLoader::get_num_blend_controllers(const int num_blend_animations, int return true; default: num_blend_controllers = 0; - ASSIMP_LOG_WARN(MDL_HALFLIFE_LOG_HEADER "Unsupported number of blend animations (" + std::to_string(num_blend_animations) + ")"); + ASSIMP_LOG_WARN(MDL_HALFLIFE_LOG_HEADER "Unsupported number of blend animations (", num_blend_animations, ")"); return false; } } diff --git a/code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp b/code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp index 72081ea73..dde81454b 100644 --- a/code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp +++ b/code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp @@ -95,7 +95,7 @@ void UniqueNameGenerator::make_unique(std::vector &names) { auto generate_unique_name = [&](const std::string &base_name) -> std::string { auto *duplicate_info = &names_to_duplicates[base_name]; - std::string new_name = ""; + std::string new_name; bool found_identical_name; bool tried_with_base_name_only = false; diff --git a/code/AssetLib/MDL/MDLLoader.cpp b/code/AssetLib/MDL/MDLLoader.cpp index a4286a716..51d76e740 100644 --- a/code/AssetLib/MDL/MDLLoader.cpp +++ b/code/AssetLib/MDL/MDLLoader.cpp @@ -199,6 +199,7 @@ void MDLImporter::InternReadFile(const std::string &pFile, const uint32_t iMagicWord = *((uint32_t *)mBuffer); // Determine the file subtype and call the appropriate member function + bool is_half_life = false; // Original Quake1 format if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) { @@ -240,6 +241,7 @@ void MDLImporter::InternReadFile(const std::string &pFile, else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) { iGSFileVersion = 0; + is_half_life = true; HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer; if (pHeader->version == AI_MDL_HL1_VERSION) { @@ -252,12 +254,22 @@ void MDLImporter::InternReadFile(const std::string &pFile, } else { // print the magic word to the log file throw DeadlyImportError("Unknown MDL subformat ", pFile, - ". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known"); + ". Magic word (", ai_str_toprintable((const char *)&iMagicWord, sizeof(iMagicWord)), ") is not known"); } - // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system - pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); + if (is_half_life){ + // Now rotate the whole scene 90 degrees around the z and x axes to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4( + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + -1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f); + } + else { + // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); + } DeleteBufferAndCleanup(); } catch (...) { diff --git a/code/AssetLib/MMD/MMDImporter.cpp b/code/AssetLib/MMD/MMDImporter.cpp index e4ecc1445..2895c3879 100644 --- a/code/AssetLib/MMD/MMDImporter.cpp +++ b/code/AssetLib/MMD/MMDImporter.cpp @@ -75,7 +75,7 @@ using namespace std; // Default constructor MMDImporter::MMDImporter() : m_Buffer(), - m_strAbsPath("") { + m_strAbsPath() { DefaultIOSystem io; m_strAbsPath = io.getOsSeparator(); } diff --git a/code/AssetLib/MMD/MMDPmxParser.cpp b/code/AssetLib/MMD/MMDPmxParser.cpp index 320182c3d..d57dc169a 100644 --- a/code/AssetLib/MMD/MMDPmxParser.cpp +++ b/code/AssetLib/MMD/MMDPmxParser.cpp @@ -91,7 +91,7 @@ namespace pmx std::vector buffer; if (size == 0) { - return std::string(""); + return std::string(); } buffer.reserve(size); stream->read((char*) buffer.data(), size); @@ -478,8 +478,7 @@ namespace pmx void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/) { - std::cerr << "Not Implemented Exception" << std::endl; - throw DeadlyImportError("MMD: Not Implemented Exception"); + throw DeadlyImportError("MMD: Soft Body support is not implemented."); } void PmxModel::Init() @@ -516,15 +515,13 @@ namespace pmx char magic[4]; stream->read((char*) magic, sizeof(char) * 4); if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20) - { - std::cerr << "invalid magic number." << std::endl; - throw DeadlyImportError("MMD: invalid magic number."); + { + throw DeadlyImportError("MMD: Invalid magic number."); } stream->read((char*) &version, sizeof(float)); if (version != 2.0f && version != 2.1f) { - std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl; - throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but ", ai_to_string(version)); + throw DeadlyImportError("MMD: Unsupported version (must be 2.0 or 2.1): ", ai_to_string(version)); } this->setting.Read(stream); diff --git a/code/AssetLib/MS3D/MS3DLoader.cpp b/code/AssetLib/MS3D/MS3DLoader.cpp index 192bcbe41..e4057a43a 100644 --- a/code/AssetLib/MS3D/MS3DLoader.cpp +++ b/code/AssetLib/MS3D/MS3DLoader.cpp @@ -215,7 +215,12 @@ void MS3DImporter :: CollectChildJoints(const std::vector& joints, ai void MS3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { - StreamReaderLE stream(pIOHandler->Open(pFile,"rb")); + + auto file = pIOHandler->Open(pFile, "rb"); + if (!file) + throw DeadlyImportError("MS3D: Could not open ", pFile); + + StreamReaderLE stream(file); // CanRead() should have done this already char head[10]; @@ -382,7 +387,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile, } const std::string& s = std::string(reinterpret_cast(stream.GetPtr()),len); - ASSIMP_LOG_DEBUG_F("MS3D: Model comment: ", s); + ASSIMP_LOG_DEBUG("MS3D: Model comment: ", s); } if(stream.GetRemainingSize() > 4 && inrange((stream >> subversion,subversion),1u,3u)) { diff --git a/code/AssetLib/NDO/NDOLoader.cpp b/code/AssetLib/NDO/NDOLoader.cpp index 77fe3e36c..0abc09dc8 100644 --- a/code/AssetLib/NDO/NDOLoader.cpp +++ b/code/AssetLib/NDO/NDOLoader.cpp @@ -116,7 +116,13 @@ void NDOImporter::SetupProperties(const Importer* /*pImp*/) void NDOImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { - StreamReaderBE reader(pIOHandler->Open( pFile, "rb")); + + auto file = pIOHandler->Open( pFile, "rb"); + if (!file) { + throw DeadlyImportError("Nendo: Could not open ", pFile); + } + + StreamReaderBE reader(file); // first 9 bytes are nendo file format ("nendo 1.n") const char* head = (const char*)reader.GetPtr(); @@ -141,7 +147,7 @@ void NDOImporter::InternReadFile( const std::string& pFile, ASSIMP_LOG_INFO("NDO file format is 1.2"); } else { - ASSIMP_LOG_WARN_F( "Unrecognized nendo file format version, continuing happily ... :", (head+6)); + ASSIMP_LOG_WARN( "Unrecognized nendo file format version, continuing happily ... :", (head+6)); } reader.IncPtr(2); /* skip flags */ diff --git a/code/AssetLib/NFF/NFFLoader.cpp b/code/AssetLib/NFF/NFFLoader.cpp index 11cce0990..15f46b5e6 100644 --- a/code/AssetLib/NFF/NFFLoader.cpp +++ b/code/AssetLib/NFF/NFFLoader.cpp @@ -132,7 +132,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output, // Check whether we can read from the file if (!file.get()) { - ASSIMP_LOG_ERROR("NFF2: Unable to open material library " + path + "."); + ASSIMP_LOG_ERROR("NFF2: Unable to open material library ", path, "."); return; } @@ -150,7 +150,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output, // The file should start with the magic sequence "mat" if (!TokenMatch(buffer, "mat", 3)) { - ASSIMP_LOG_ERROR_F("NFF2: Not a valid material library ", path, "."); + ASSIMP_LOG_ERROR("NFF2: Not a valid material library ", path, "."); return; } @@ -164,7 +164,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output, // 'version' defines the version of the file format if (TokenMatch(sz, "version", 7)) { - ASSIMP_LOG_INFO_F("NFF (Sense8) material library file format: ", std::string(sz)); + ASSIMP_LOG_INFO("NFF (Sense8) material library file format: ", std::string(sz)); } // 'matdef' starts a new material in the file else if (TokenMatch(sz, "matdef", 6)) { @@ -177,7 +177,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output, // check whether we have an active material at the moment if (!IsLineEnd(*sz)) { if (!curShader) { - ASSIMP_LOG_ERROR_F("NFF2 material library: Found element ", sz, "but there is no active material"); + ASSIMP_LOG_ERROR("NFF2 material library: Found element ", sz, "but there is no active material"); continue; } } else @@ -277,7 +277,7 @@ void NFFImporter::InternReadFile(const std::string &pFile, while (GetNextLine(buffer, line)) { SkipSpaces(line, &sz); if (TokenMatch(sz, "version", 7)) { - ASSIMP_LOG_INFO_F("NFF (Sense8) file format: ", sz); + ASSIMP_LOG_INFO("NFF (Sense8) file format: ", sz); } else if (TokenMatch(sz, "viewpos", 7)) { AI_NFF_PARSE_TRIPLE(camPos); hasCam = true; diff --git a/code/AssetLib/Obj/ObjFileParser.cpp b/code/AssetLib/Obj/ObjFileParser.cpp index a8039ae23..767805c10 100644 --- a/code/AssetLib/Obj/ObjFileParser.cpp +++ b/code/AssetLib/Obj/ObjFileParser.cpp @@ -556,7 +556,7 @@ void ObjFileParser::getMaterialDesc() { // This may be the case if the material library is missing. We don't want to lose all // materials if that happens, so create a new named material instead of discarding it // completely. - ASSIMP_LOG_ERROR("OBJ: failed to locate material " + strName + ", creating new material"); + ASSIMP_LOG_ERROR("OBJ: failed to locate material ", strName, ", creating new material"); m_pModel->m_pCurrentMaterial = new ObjFile::Material(); m_pModel->m_pCurrentMaterial->MaterialName.Set(strName); m_pModel->m_MaterialLib.push_back(strName); @@ -620,12 +620,12 @@ void ObjFileParser::getMaterialLib() { IOStream *pFile = m_pIO->Open(absName); if (nullptr == pFile) { - ASSIMP_LOG_ERROR("OBJ: Unable to locate material file " + strMatName); + ASSIMP_LOG_ERROR("OBJ: Unable to locate material file ", strMatName); std::string strMatFallbackName = m_originalObjFileName.substr(0, m_originalObjFileName.length() - 3) + "mtl"; - ASSIMP_LOG_INFO("OBJ: Opening fallback material file " + strMatFallbackName); + ASSIMP_LOG_INFO("OBJ: Opening fallback material file ", strMatFallbackName); pFile = m_pIO->Open(strMatFallbackName); if (!pFile) { - ASSIMP_LOG_ERROR("OBJ: Unable to locate fallback material file " + strMatFallbackName); + ASSIMP_LOG_ERROR("OBJ: Unable to locate fallback material file ", strMatFallbackName); m_DataIt = skipLine(m_DataIt, m_DataItEnd, m_uiLine); return; } @@ -660,7 +660,7 @@ void ObjFileParser::getNewMaterial() { std::map::iterator it = m_pModel->m_MaterialMap.find(strMat); if (it == m_pModel->m_MaterialMap.end()) { // Show a warning, if material was not found - ASSIMP_LOG_WARN("OBJ: Unsupported material requested: " + strMat); + ASSIMP_LOG_WARN("OBJ: Unsupported material requested: ", strMat); m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; } else { // Set new material diff --git a/code/AssetLib/Ogre/OgreBinarySerializer.cpp b/code/AssetLib/Ogre/OgreBinarySerializer.cpp index 0fc18feb9..1d20799a1 100644 --- a/code/AssetLib/Ogre/OgreBinarySerializer.cpp +++ b/code/AssetLib/Ogre/OgreBinarySerializer.cpp @@ -155,7 +155,7 @@ uint16_t OgreBinarySerializer::ReadHeader(bool readLen) { #if (OGRE_BINARY_SERIALIZER_DEBUG == 1) if (id != HEADER_CHUNK_ID) { - ASSIMP_LOG_DEBUG(Formatter::format() << (assetMode == AM_Mesh ? MeshHeaderToString(static_cast(id)) : SkeletonHeaderToString(static_cast(id)))); + ASSIMP_LOG_DEBUG((assetMode == AM_Mesh ? MeshHeaderToString(static_cast(id)) : SkeletonHeaderToString(static_cast(id)))); } #endif @@ -168,7 +168,7 @@ void OgreBinarySerializer::RollbackHeader() { void OgreBinarySerializer::SkipBytes(size_t numBytes) { #if (OGRE_BINARY_SERIALIZER_DEBUG == 1) - ASSIMP_LOG_VERBOSE_DEBUG_F("Skipping ", numBytes, " bytes"); + ASSIMP_LOG_VERBOSE_DEBUG("Skipping ", numBytes, " bytes"); #endif m_reader->IncPtr(numBytes); @@ -208,7 +208,7 @@ void OgreBinarySerializer::ReadMesh(Mesh *mesh) { mesh->hasSkeletalAnimations = Read(); ASSIMP_LOG_VERBOSE_DEBUG("Reading Mesh"); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Skeletal animations: ", mesh->hasSkeletalAnimations ? "true" : "false"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Skeletal animations: ", mesh->hasSkeletalAnimations ? "true" : "false"); if (!AtEnd()) { uint16_t id = ReadHeader(); @@ -364,9 +364,9 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh) { submesh->indexData->faceCount = static_cast(submesh->indexData->count / 3); submesh->indexData->is32bit = Read(); - ASSIMP_LOG_VERBOSE_DEBUG_F("Reading SubMesh ", mesh->subMeshes.size()); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Material: '", submesh->materialRef, "'"); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Uses shared geometry: ", submesh->usesSharedVertexData ? "true" : "false"); + ASSIMP_LOG_VERBOSE_DEBUG("Reading SubMesh ", mesh->subMeshes.size()); + ASSIMP_LOG_VERBOSE_DEBUG(" - Material: '", submesh->materialRef, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Uses shared geometry: ", submesh->usesSharedVertexData ? "true" : "false"); // Index buffer if (submesh->indexData->count > 0) { @@ -374,7 +374,7 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh) { uint8_t *indexBuffer = ReadBytes(numBytes); submesh->indexData->buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(indexBuffer, numBytes, true)); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - ", submesh->indexData->faceCount, + ASSIMP_LOG_VERBOSE_DEBUG(" - ", submesh->indexData->faceCount, " faces from ", submesh->indexData->count, (submesh->indexData->is32bit ? " 32bit" : " 16bit"), " indexes of ", numBytes, " bytes"); } @@ -475,7 +475,7 @@ void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) { } submesh->name = ReadLine(); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - SubMesh ", submesh->index, " name '", submesh->name, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" - SubMesh ", submesh->index, " name '", submesh->name, "'"); if (!AtEnd()) id = ReadHeader(); @@ -488,7 +488,7 @@ void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) { void OgreBinarySerializer::ReadGeometry(VertexData *dest) { dest->count = Read(); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Reading geometry of ", dest->count, " vertices"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Reading geometry of ", dest->count, " vertices"); if (!AtEnd()) { uint16_t id = ReadHeader(); @@ -536,7 +536,7 @@ void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest) { element.offset = Read(); element.index = Read(); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Vertex element ", element.SemanticToString(), " of type ", + ASSIMP_LOG_VERBOSE_DEBUG(" - Vertex element ", element.SemanticToString(), " of type ", element.TypeToString(), " index=", element.index, " source=", element.source); dest->vertexElements.push_back(element); @@ -557,7 +557,7 @@ void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest) { uint8_t *vertexBuffer = ReadBytes(numBytes); dest->vertexBindings[bindIndex] = MemoryStreamPtr(new Assimp::MemoryIOStream(vertexBuffer, numBytes, true)); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Read vertex buffer for source ", bindIndex, " of ", numBytes, " bytes"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Read vertex buffer for source ", bindIndex, " of ", numBytes, " bytes"); } void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/) { @@ -777,12 +777,12 @@ bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) { if (!EndsWith(filename, ".skeleton", false)) { - ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); + ASSIMP_LOG_ERROR("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); return MemoryStreamReaderPtr(); } if (!pIOHandler->Exists(filename)) { - ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); + ASSIMP_LOG_ERROR("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); return MemoryStreamReaderPtr(); } @@ -874,7 +874,7 @@ void OgreBinarySerializer::ReadBone(Skeleton *skeleton) { throw DeadlyImportError("Ogre Skeleton bone indexes not contiguous. Error at bone index ", bone->id); } - ASSIMP_LOG_VERBOSE_DEBUG_F(" ", bone->id, " ", bone->name); + ASSIMP_LOG_VERBOSE_DEBUG(" ", bone->id, " ", bone->name); skeleton->bones.push_back(bone); } @@ -919,7 +919,7 @@ void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton) { skeleton->animations.push_back(anim); - ASSIMP_LOG_VERBOSE_DEBUG_F(" ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)"); + ASSIMP_LOG_VERBOSE_DEBUG(" ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)"); } void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, Animation *dest) { diff --git a/code/AssetLib/Ogre/OgreMaterial.cpp b/code/AssetLib/Ogre/OgreMaterial.cpp index eced651f6..295dedde6 100644 --- a/code/AssetLib/Ogre/OgreMaterial.cpp +++ b/code/AssetLib/Ogre/OgreMaterial.cpp @@ -160,16 +160,16 @@ aiMaterial *OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste if (materialFile) { break; } - ASSIMP_LOG_VERBOSE_DEBUG_F("Source file for material '", materialName, "' ", potentialFiles[i], " does not exist"); + ASSIMP_LOG_VERBOSE_DEBUG("Source file for material '", materialName, "' ", potentialFiles[i], " does not exist"); } if (!materialFile) { - ASSIMP_LOG_ERROR_F("Failed to find source file for material '", materialName, "'"); + ASSIMP_LOG_ERROR("Failed to find source file for material '", materialName, "'"); return 0; } std::unique_ptr stream(materialFile); if (stream->FileSize() == 0) { - ASSIMP_LOG_WARN_F("Source file for material '", materialName, "' is empty (size is 0 bytes)"); + ASSIMP_LOG_WARN("Source file for material '", materialName, "' is empty (size is 0 bytes)"); return 0; } @@ -184,7 +184,7 @@ aiMaterial *OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste ss << &data[0]; } - ASSIMP_LOG_VERBOSE_DEBUG_F("Reading material '", materialName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG("Reading material '", materialName, "'"); aiMaterial *material = new aiMaterial(); m_textures.clear(); @@ -219,11 +219,11 @@ aiMaterial *OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste NextAfterNewLine(ss, linePart); if (linePart != partBlockStart) { - ASSIMP_LOG_ERROR_F("Invalid material: block start missing near index ", ss.tellg()); + ASSIMP_LOG_ERROR("Invalid material: block start missing near index ", ss.tellg()); return material; } - ASSIMP_LOG_VERBOSE_DEBUG_F("material '", materialName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG("material '", materialName, "'"); while (linePart != partBlockEnd) { // Proceed to the first technique @@ -303,11 +303,11 @@ bool OgreImporter::ReadTechnique(const std::string &techniqueName, stringstream ss >> linePart; if (linePart != partBlockStart) { - ASSIMP_LOG_ERROR_F("Invalid material: Technique block start missing near index ", ss.tellg()); + ASSIMP_LOG_ERROR("Invalid material: Technique block start missing near index ", ss.tellg()); return false; } - ASSIMP_LOG_VERBOSE_DEBUG_F(" technique '", techniqueName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" technique '", techniqueName, "'"); const string partPass = "pass"; @@ -334,11 +334,11 @@ bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMat ss >> linePart; if (linePart != partBlockStart) { - ASSIMP_LOG_ERROR_F("Invalid material: Pass block start missing near index ", ss.tellg()); + ASSIMP_LOG_ERROR("Invalid material: Pass block start missing near index ", ss.tellg()); return false; } - ASSIMP_LOG_VERBOSE_DEBUG_F(" pass '", passName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" pass '", passName, "'"); const string partAmbient = "ambient"; const string partDiffuse = "diffuse"; @@ -362,7 +362,7 @@ bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMat ss >> r >> g >> b; const aiColor3D color(r, g, b); - ASSIMP_LOG_VERBOSE_DEBUG_F(" ", linePart, " ", r, " ", g, " ", b); + ASSIMP_LOG_VERBOSE_DEBUG(" ", linePart, " ", r, " ", g, " ", b); if (linePart == partAmbient) { material->AddProperty(&color, 1, AI_MATKEY_COLOR_AMBIENT); @@ -386,11 +386,11 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr ss >> linePart; if (linePart != partBlockStart) { - ASSIMP_LOG_ERROR_F("Invalid material: Texture unit block start missing near index ", ss.tellg()); + ASSIMP_LOG_ERROR("Invalid material: Texture unit block start missing near index ", ss.tellg()); return false; } - ASSIMP_LOG_VERBOSE_DEBUG_F(" texture_unit '", textureUnitName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" texture_unit '", textureUnitName, "'"); const string partTexture = "texture"; const string partTextCoordSet = "tex_coord_set"; @@ -420,7 +420,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) { string identifier = ai_tolower(textureRef.substr(posUnderscore, posSuffix - posUnderscore)); - ASSIMP_LOG_VERBOSE_DEBUG_F("Detecting texture type from filename postfix '", identifier, "'"); + ASSIMP_LOG_VERBOSE_DEBUG("Detecting texture type from filename postfix '", identifier, "'"); if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") { textureType = aiTextureType_NORMALS; @@ -477,14 +477,14 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr return false; } if (textureType == aiTextureType_NONE) { - ASSIMP_LOG_WARN("Failed to detect texture type for '" + textureRef + "', ignoring texture_unit."); + ASSIMP_LOG_WARN("Failed to detect texture type for '", textureRef, "', ignoring texture_unit."); return false; } unsigned int textureTypeIndex = m_textures[textureType]; m_textures[textureType]++; - ASSIMP_LOG_VERBOSE_DEBUG_F(" texture '", textureRef, "' type ", textureType, + ASSIMP_LOG_VERBOSE_DEBUG(" texture '", textureRef, "' type ", textureType, " index ", textureTypeIndex, " UV ", uvCoord); aiString assimpTextureRef(textureRef); diff --git a/code/AssetLib/Ogre/OgreStructs.cpp b/code/AssetLib/Ogre/OgreStructs.cpp index 90e2d4465..a2d861172 100644 --- a/code/AssetLib/Ogre/OgreStructs.cpp +++ b/code/AssetLib/Ogre/OgreStructs.cpp @@ -545,7 +545,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) { dest->mNumUVComponents[0] = static_cast(uv1Element->ComponentCount()); dest->mTextureCoords[0] = new aiVector3D[dest->mNumVertices]; } else { - ASSIMP_LOG_WARN(Formatter::format() << "Ogre imported UV0 type " << uv1Element->TypeToString() << " is not compatible with Assimp. Ignoring UV."); + ASSIMP_LOG_WARN("Ogre imported UV0 type ", uv1Element->TypeToString(), " is not compatible with Assimp. Ignoring UV."); uv1 = 0; } } @@ -554,7 +554,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) { dest->mNumUVComponents[1] = static_cast(uv2Element->ComponentCount()); dest->mTextureCoords[1] = new aiVector3D[dest->mNumVertices]; } else { - ASSIMP_LOG_WARN(Formatter::format() << "Ogre imported UV0 type " << uv2Element->TypeToString() << " is not compatible with Assimp. Ignoring UV."); + ASSIMP_LOG_WARN("Ogre imported UV0 type ", uv2Element->TypeToString(), " is not compatible with Assimp. Ignoring UV."); uv2 = 0; } } diff --git a/code/AssetLib/Ogre/OgreXmlSerializer.cpp b/code/AssetLib/Ogre/OgreXmlSerializer.cpp index 938ae48f3..70671f251 100644 --- a/code/AssetLib/Ogre/OgreXmlSerializer.cpp +++ b/code/AssetLib/Ogre/OgreXmlSerializer.cpp @@ -256,7 +256,7 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) { void OgreXmlSerializer::ReadGeometry(XmlNode &node, VertexDataXml *dest) { dest->count = ReadAttribute(node, "vertexcount"); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Reading geometry of ", dest->count, " vertices"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Reading geometry of ", dest->count, " vertices"); for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); @@ -290,7 +290,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(XmlNode &node, VertexDataXml *d dest->tangents.reserve(dest->count); } if (uvs > 0) { - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Contains ", uvs, " texture coords"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Contains ", uvs, " texture coords"); dest->uvs.resize(uvs); for (size_t i = 0, len = dest->uvs.size(); i < len; ++i) { dest->uvs[i].reserve(dest->count); @@ -365,9 +365,9 @@ void OgreXmlSerializer::ReadSubMesh(XmlNode &node, MeshXml *mesh) { submesh->usesSharedVertexData = ReadAttribute(node, anUseSharedVertices); } - ASSIMP_LOG_VERBOSE_DEBUG_F("Reading SubMesh ", mesh->subMeshes.size()); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Material: '", submesh->materialRef, "'"); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Uses shared geometry: ", (submesh->usesSharedVertexData ? "true" : "false")); + ASSIMP_LOG_VERBOSE_DEBUG("Reading SubMesh ", mesh->subMeshes.size()); + ASSIMP_LOG_VERBOSE_DEBUG(" - Material: '", submesh->materialRef, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Uses shared geometry: ", (submesh->usesSharedVertexData ? "true" : "false")); // TODO: maybe we have always just 1 faces and 1 geometry and always in this order. this loop will only work correct, when the order // of faces and geometry changed, and not if we have more than one of one @@ -398,7 +398,7 @@ void OgreXmlSerializer::ReadSubMesh(XmlNode &node, MeshXml *mesh) { } } if (submesh->indexData->faces.size() == submesh->indexData->faceCount) { - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Faces ", submesh->indexData->faceCount); + ASSIMP_LOG_VERBOSE_DEBUG(" - Faces ", submesh->indexData->faceCount); } else { throw DeadlyImportError("Read only ", submesh->indexData->faces.size(), " faces when should have read ", submesh->indexData->faceCount); } @@ -459,7 +459,7 @@ void OgreXmlSerializer::ReadBoneAssignments(XmlNode &node, VertexDataXml *dest) } } - ASSIMP_LOG_VERBOSE_DEBUG_F(" - ", dest->boneAssignments.size(), " bone assignments"); + ASSIMP_LOG_VERBOSE_DEBUG(" - ", dest->boneAssignments.size(), " bone assignments"); } // Skeleton @@ -515,12 +515,12 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) XmlParserPtr OgreXmlSerializer::OpenXmlParser(Assimp::IOSystem *pIOHandler, const std::string &filename) { if (!EndsWith(filename, ".skeleton.xml", false)) { - ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); + ASSIMP_LOG_ERROR("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); return XmlParserPtr(); } if (!pIOHandler->Exists(filename)) { - ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); + ASSIMP_LOG_ERROR("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); return XmlParserPtr(); } @@ -631,7 +631,7 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(XmlNode &node, Animation *anim, V if (axis.Equal(zeroVec)) { axis.x = 1.0f; if (angle != 0) { - ASSIMP_LOG_WARN_F("Found invalid a key frame with a zero rotation axis in animation: ", anim->name); + ASSIMP_LOG_WARN("Found invalid a key frame with a zero rotation axis in animation: ", anim->name); } } keyframe.rotation = aiQuaternion(axis, angle); @@ -741,7 +741,7 @@ void OgreXmlSerializer::ReadBones(XmlNode &node, Skeleton *skeleton) { as per the Ogre skeleton spec. It might be more that other (later) code in this imported does not break. */ for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) { Bone *b = skeleton->bones[i]; - ASSIMP_LOG_VERBOSE_DEBUG_F(" ", b->id, " ", b->name); + ASSIMP_LOG_VERBOSE_DEBUG(" ", b->id, " ", b->name); if (b->id != static_cast(i)) { throw DeadlyImportError("Bone ids are not in sequence starting from 0. Missing index ", i); diff --git a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp index 14c9ea37f..9baaa4a12 100644 --- a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp +++ b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp @@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include @@ -206,7 +207,7 @@ USE_ODDLPARSER_NS //------------------------------------------------------------------------------------------------ static void propId2StdString(Property *prop, std::string &name, std::string &key) { - name = key = ""; + name = key = std::string(); if (nullptr == prop) { return; } @@ -223,6 +224,18 @@ static void propId2StdString(Property *prop, std::string &name, std::string &key } } +//------------------------------------------------------------------------------------------------ +static void logDDLParserMessage (LogSeverity severity, const std::string &rawmsg) { + std::string msg = ai_str_toprintable(rawmsg); + switch (severity) { + case ddl_debug_msg: ASSIMP_LOG_DEBUG(msg); break; + case ddl_info_msg: ASSIMP_LOG_INFO(msg); break; + case ddl_warn_msg: ASSIMP_LOG_WARN(msg); break; + case ddl_error_msg: ASSIMP_LOG_ERROR(msg); break; + default: ASSIMP_LOG_VERBOSE_DEBUG(msg); break; + } +} + //------------------------------------------------------------------------------------------------ OpenGEXImporter::VertexContainer::VertexContainer() : m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() { @@ -306,6 +319,7 @@ void OpenGEXImporter::InternReadFile(const std::string &filename, aiScene *pScen pIOHandler->Close(file); OpenDDLParser myParser; + myParser.setLogCallback(&logDDLParserMessage); myParser.setBuffer(&buffer[0], buffer.size()); bool success(myParser.parse()); if (success) { @@ -712,7 +726,7 @@ void OpenGEXImporter::handleMeshNode(ODDLParser::DDLNode *node, aiScene *pScene) } else if ("quads" == propKey) { m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; } else { - ASSIMP_LOG_WARN_F(propKey, " is not supported primitive type."); + ASSIMP_LOG_WARN(propKey, " is not supported primitive type."); } } } diff --git a/code/AssetLib/OpenGEX/OpenGEXImporter.h b/code/AssetLib/OpenGEX/OpenGEXImporter.h index 677ef73aa..3c26a4a30 100644 --- a/code/AssetLib/OpenGEX/OpenGEXImporter.h +++ b/code/AssetLib/OpenGEX/OpenGEXImporter.h @@ -79,7 +79,7 @@ struct MetricInfo { int m_intValue; MetricInfo() - : m_stringValue( "" ) + : m_stringValue( ) , m_floatValue( 0.0f ) , m_intValue( -1 ) { // empty diff --git a/code/AssetLib/Ply/PlyLoader.cpp b/code/AssetLib/Ply/PlyLoader.cpp index ce52636dd..93d48bcbf 100644 --- a/code/AssetLib/Ply/PlyLoader.cpp +++ b/code/AssetLib/Ply/PlyLoader.cpp @@ -172,7 +172,7 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy (headerCheck[1] != 'L' && headerCheck[1] != 'l') || (headerCheck[2] != 'Y' && headerCheck[2] != 'y')) { streamedBuffer.close(); - throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there"); + throw DeadlyImportError("Invalid .ply file: Incorrect magic number (expected 'ply' or 'PLY')."); } std::vector mBuffer2; diff --git a/code/AssetLib/Q3BSP/Q3BSPFileData.h b/code/AssetLib/Q3BSP/Q3BSPFileData.h index ba826d541..a121cdbcd 100644 --- a/code/AssetLib/Q3BSP/Q3BSPFileData.h +++ b/code/AssetLib/Q3BSP/Q3BSPFileData.h @@ -178,7 +178,7 @@ struct Q3BSPModel { m_Textures(), m_Lightmaps(), m_EntityData(), - m_ModelName( "" ) + m_ModelName() { // empty } diff --git a/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp b/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp index c66582fea..becfa41fc 100644 --- a/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp +++ b/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp @@ -75,7 +75,7 @@ static const aiImporterDesc desc = { 0, 0, 0, - "pk3" + "bsp pk3" }; namespace Assimp { @@ -113,7 +113,7 @@ static void extractIds(const std::string &key, int &id1, int &id2) { // ------------------------------------------------------------------------------------------------ // Local helper function to normalize filenames. static void normalizePathName(const std::string &rPath, std::string &normalizedPath) { - normalizedPath = ""; + normalizedPath = std::string(); if (rPath.empty()) { return; } @@ -183,7 +183,7 @@ void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene, throw DeadlyImportError("Failed to open file ", rFile, "."); } - std::string archiveName(""), mapName(""); + std::string archiveName, mapName; separateMapName(rFile, archiveName, mapName); if (mapName.empty()) { @@ -202,8 +202,8 @@ void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene, // ------------------------------------------------------------------------------------------------ // Separates the map name from the import name. void Q3BSPFileImporter::separateMapName(const std::string &importName, std::string &archiveName, std::string &mapName) { - archiveName = ""; - mapName = ""; + archiveName = std::string(); + mapName = std::string(); if (importName.empty()) { return; } @@ -221,7 +221,7 @@ void Q3BSPFileImporter::separateMapName(const std::string &importName, std::stri // ------------------------------------------------------------------------------------------------ // Returns the first map in the map archive. bool Q3BSPFileImporter::findFirstMapInArchive(ZipArchiveIOSystem &bspArchive, std::string &mapName) { - mapName = ""; + mapName = std::string(); std::vector fileList; bspArchive.getFileListExtension(fileList, "bsp"); if (fileList.empty()) { @@ -440,13 +440,13 @@ void Q3BSPFileImporter::createMaterials(const Q3BSP::Q3BSPModel *pModel, aiScene if (-1 != textureId) { sQ3BSPTexture *pTexture = pModel->m_Textures[textureId]; if (nullptr != pTexture) { - std::string tmp("*"), texName(""); + std::string tmp("*"), texName; tmp += pTexture->strName; tmp += ".jpg"; normalizePathName(tmp, texName); if (!importTextureFromArchive(pModel, pArchive, pScene, pMatHelper, textureId)) { - ASSIMP_LOG_ERROR("Cannot import texture from archive " + texName); + ASSIMP_LOG_ERROR("Cannot import texture from archive ", texName); } } } @@ -512,7 +512,7 @@ size_t Q3BSPFileImporter::countTriangles(const std::vector // ------------------------------------------------------------------------------------------------ // Creates the faces-to-material map. void Q3BSPFileImporter::createMaterialMap(const Q3BSP::Q3BSPModel *pModel) { - std::string key(""); + std::string key; std::vector *pCurFaceArray = nullptr; for (size_t idx = 0; idx < pModel->m_Faces.size(); idx++) { Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[idx]; @@ -660,7 +660,7 @@ bool Q3BSPFileImporter::expandFile(ZipArchiveIOSystem *pArchive, const std::stri if (rExtList.empty()) { rFile = rFilename; - rExt = ""; + rExt = std::string(); return true; } diff --git a/code/AssetLib/Q3D/Q3DLoader.cpp b/code/AssetLib/Q3D/Q3DLoader.cpp index b52f86672..f81026547 100644 --- a/code/AssetLib/Q3D/Q3DLoader.cpp +++ b/code/AssetLib/Q3D/Q3DLoader.cpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "Q3DLoader.h" +#include #include #include #include @@ -106,7 +107,12 @@ const aiImporterDesc *Q3DImporter::GetInfo() const { // Imports the given file into the given scene structure. void Q3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { - StreamReaderLE stream(pIOHandler->Open(pFile, "rb")); + + auto file = pIOHandler->Open(pFile, "rb"); + if (!file) + throw DeadlyImportError("Quick3D: Could not open ", pFile); + + StreamReaderLE stream(file); // The header is 22 bytes large if (stream.GetRemainingSize() < 22) @@ -115,11 +121,11 @@ void Q3DImporter::InternReadFile(const std::string &pFile, // Check the file's signature if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) && ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) { - throw DeadlyImportError("Not a Quick3D file. Signature string is: ", std::string((const char *)stream.GetPtr(), 8)); + throw DeadlyImportError("Not a Quick3D file. Signature string is: ", ai_str_toprintable((const char *)stream.GetPtr(), 8)); } // Print the file format version - ASSIMP_LOG_INFO_F("Quick3D File format version: ", + ASSIMP_LOG_INFO("Quick3D File format version: ", std::string(&((const char *)stream.GetPtr())[8], 2)); // ... an store it diff --git a/code/AssetLib/SIB/SIBImporter.cpp b/code/AssetLib/SIB/SIBImporter.cpp index 6898fb65c..0321e7064 100644 --- a/code/AssetLib/SIB/SIBImporter.cpp +++ b/code/AssetLib/SIB/SIBImporter.cpp @@ -68,6 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include @@ -166,21 +167,20 @@ static aiColor3D ReadColor(StreamReaderLE *stream) { } static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) { - char temp[5] = { + char temp[4] = { static_cast((chunk.Tag >> 24) & 0xff), static_cast((chunk.Tag >> 16) & 0xff), static_cast((chunk.Tag >> 8) & 0xff), - static_cast(chunk.Tag & 0xff), '\0' + static_cast(chunk.Tag & 0xff) }; - ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", temp, "' chunk.")); + ASSIMP_LOG_WARN("SIB: Skipping unknown '", ai_str_toprintable(temp, 4), "' chunk."); } // Reads a UTF-16LE string and returns it at UTF-8. static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) { if (nullptr == stream || 0 == numWChars) { - static const aiString empty; - return empty; + return aiString(); } // Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8) @@ -804,7 +804,12 @@ static void ReadScene(SIB *sib, StreamReaderLE *stream) { // Imports the given file into the given scene structure. void SIBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { - StreamReaderLE stream(pIOHandler->Open(pFile, "rb")); + + auto file = pIOHandler->Open(pFile, "rb"); + if (!file) + throw DeadlyImportError("SIB: Could not open ", pFile); + + StreamReaderLE stream(file); // We should have at least one chunk if (stream.GetRemainingSize() < 16) diff --git a/code/AssetLib/STEPParser/STEPFileReader.cpp b/code/AssetLib/STEPParser/STEPFileReader.cpp index cbf8c07c2..e97ea1e28 100644 --- a/code/AssetLib/STEPParser/STEPFileReader.cpp +++ b/code/AssetLib/STEPParser/STEPFileReader.cpp @@ -297,8 +297,8 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, } if ( !DefaultLogger::isNullLogger()){ - ASSIMP_LOG_DEBUG((Formatter::format(),"STEP: got ",map.size()," object records with ", - db.GetRefs().size()," inverse index entries")); + ASSIMP_LOG_DEBUG("STEP: got ",map.size()," object records with ", + db.GetRefs().size()," inverse index entries"); } } diff --git a/code/AssetLib/Unreal/UnrealLoader.cpp b/code/AssetLib/Unreal/UnrealLoader.cpp index 499b49c05..e3ebc05c3 100644 --- a/code/AssetLib/Unreal/UnrealLoader.cpp +++ b/code/AssetLib/Unreal/UnrealLoader.cpp @@ -228,9 +228,9 @@ void UnrealImporter::InternReadFile(const std::string &pFile, a_path = extension + "_a.3d"; uc_path = extension + ".uc"; - ASSIMP_LOG_DEBUG_F("UNREAL: data file is ", d_path); - ASSIMP_LOG_DEBUG_F("UNREAL: aniv file is ", a_path); - ASSIMP_LOG_DEBUG_F("UNREAL: uc file is ", uc_path); + ASSIMP_LOG_DEBUG("UNREAL: data file is ", d_path); + ASSIMP_LOG_DEBUG("UNREAL: aniv file is ", a_path); + ASSIMP_LOG_DEBUG("UNREAL: uc file is ", uc_path); // and open the files ... we can't live without them std::unique_ptr p(pIOHandler->Open(d_path)); diff --git a/code/AssetLib/X/XFileHelper.h b/code/AssetLib/X/XFileHelper.h index 8ba166350..5bdaf4d35 100644 --- a/code/AssetLib/X/XFileHelper.h +++ b/code/AssetLib/X/XFileHelper.h @@ -130,7 +130,7 @@ struct Mesh { std::vector mBones; - explicit Mesh(const std::string &pName = "") AI_NO_EXCEPT + explicit Mesh(const std::string &pName = std::string()) AI_NO_EXCEPT : mName( pName ) , mPositions() , mPosFaces() diff --git a/code/AssetLib/X/XFileImporter.cpp b/code/AssetLib/X/XFileImporter.cpp index cb245ed74..df1aba331 100644 --- a/code/AssetLib/X/XFileImporter.cpp +++ b/code/AssetLib/X/XFileImporter.cpp @@ -602,7 +602,7 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector &extensionList ) { - extensionList.insert("x3d"); -} - void X3DImporter::InternReadFile( const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler ) { std::shared_ptr stream(pIOHandler->Open(pFile, "rb")); if (!stream) { diff --git a/code/AssetLib/X3D/X3DImporter.hpp b/code/AssetLib/X3D/X3DImporter.hpp index 3d263a2cc..c96bb17d8 100644 --- a/code/AssetLib/X3D/X3DImporter.hpp +++ b/code/AssetLib/X3D/X3DImporter.hpp @@ -307,7 +307,6 @@ public: /// \param [in] pIOHandler - pointer to IO helper object. void ParseFile(const std::string &pFile, IOSystem *pIOHandler); bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const; - void GetExtensionList(std::set &pExtensionList); void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); const aiImporterDesc *GetInfo() const; void Clear(); diff --git a/code/AssetLib/XGL/XGLLoader.cpp b/code/AssetLib/XGL/XGLLoader.cpp index 824f0c2c3..3b84d7ba9 100644 --- a/code/AssetLib/XGL/XGLLoader.cpp +++ b/code/AssetLib/XGL/XGLLoader.cpp @@ -142,7 +142,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // check whether we can read from the file if (stream.get() == NULL) { - throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile + ""); + throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile); } // see if its compressed, if so uncompress it @@ -200,7 +200,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // parse the XML file mXmlParser = new XmlParser; if (!mXmlParser->parse(stream.get())) { - return; + throw DeadlyImportError("XML parse error while loading XGL file ", pFile); } TempScope scope; diff --git a/code/AssetLib/glTF/glTFAsset.h b/code/AssetLib/glTF/glTFAsset.h index 623f18173..da49a1737 100644 --- a/code/AssetLib/glTF/glTFAsset.h +++ b/code/AssetLib/glTF/glTFAsset.h @@ -1033,7 +1033,7 @@ namespace glTF AssetMetadata() : premultipliedAlpha(false) - , version("") + , version() { } }; diff --git a/code/AssetLib/glTF/glTFExporter.cpp b/code/AssetLib/glTF/glTFExporter.cpp index 0d644be8b..5e1992319 100644 --- a/code/AssetLib/glTF/glTFExporter.cpp +++ b/code/AssetLib/glTF/glTFExporter.cpp @@ -604,7 +604,7 @@ void glTFExporter::ExportMeshes() else msg = "mesh must has vertices and faces."; - ASSIMP_LOG_WARN_F("GLTF: can not use Open3DGC-compression: ", msg); + ASSIMP_LOG_WARN("GLTF: can not use Open3DGC-compression: ", msg); comp_allow = false; } diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index fad5cba83..26a2f64c3 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -1071,7 +1071,7 @@ struct AssetMetadata { void Read(Document &doc); AssetMetadata() : - version("") {} + version() {} }; // diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index f34b1b451..dbc8267d3 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -325,7 +325,7 @@ static aiMaterial *ImportMaterial(std::vector &embeddedTexIdxs, Asset &r, M void glTF2Importer::ImportMaterials(glTF2::Asset &r) { const unsigned int numImportedMaterials = unsigned(r.materials.Size()); - ASSIMP_LOG_DEBUG_F("Importing ", numImportedMaterials, " materials"); + ASSIMP_LOG_DEBUG("Importing ", numImportedMaterials, " materials"); Material defaultMaterial; mScene->mNumMaterials = numImportedMaterials + 1; @@ -402,7 +402,7 @@ aiColor4D* GetVertexColorsForType(glTF2::Ref input) { } void glTF2Importer::ImportMeshes(glTF2::Asset &r) { - ASSIMP_LOG_DEBUG_F("Importing ", r.meshes.Size(), " meshes"); + ASSIMP_LOG_DEBUG("Importing ", r.meshes.Size(), " meshes"); std::vector> meshes; unsigned int k = 0; @@ -455,14 +455,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { if (attr.normal.size() > 0 && attr.normal[0]) { if (attr.normal[0]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Normal count in mesh \"" + mesh.name + "\" does not match the vertex count, normals ignored."); + DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored."); } else { attr.normal[0]->ExtractData(aim->mNormals); // only extract tangents if normals are present if (attr.tangent.size() > 0 && attr.tangent[0]) { if (attr.tangent[0]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Tangent count in mesh \"" + mesh.name + "\" does not match the vertex count, tangents ignored."); + DefaultLogger::get()->warn("Tangent count in mesh \"", mesh.name, "\" does not match the vertex count, tangents ignored."); } else { // generate bitangents from normals and tangents according to spec Tangent *tangents = nullptr; @@ -485,7 +485,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) { if (attr.color[c]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Color stream size in mesh \"" + mesh.name + + DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name, "\" does not match the vertex count"); continue; } @@ -508,7 +508,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } if (attr.texcoord[tc]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name + + DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name, "\" does not match the vertex count"); continue; } @@ -539,7 +539,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { if (needPositions) { if (target.position[0]->count != aim->mNumVertices) { - ASSIMP_LOG_WARN_F("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); + ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { aiVector3D *positionDiff = nullptr; target.position[0]->ExtractData(positionDiff); @@ -551,7 +551,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } if (needNormals) { if (target.normal[0]->count != aim->mNumVertices) { - ASSIMP_LOG_WARN_F("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); + ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { aiVector3D *normalDiff = nullptr; target.normal[0]->ExtractData(normalDiff); @@ -563,7 +563,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } if (needTangents) { if (target.tangent[0]->count != aim->mNumVertices) { - ASSIMP_LOG_WARN_F("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); + ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { Tangent *tangent = nullptr; attr.tangent[0]->ExtractData(tangent); @@ -785,7 +785,7 @@ void glTF2Importer::ImportCameras(glTF2::Asset &r) { if (!r.cameras.Size()) return; const unsigned int numCameras = r.cameras.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numCameras, " cameras"); + ASSIMP_LOG_DEBUG("Importing ", numCameras, " cameras"); mScene->mNumCameras = numCameras; mScene->mCameras = new aiCamera *[numCameras]; std::fill(mScene->mCameras, mScene->mCameras + numCameras, nullptr); @@ -822,7 +822,7 @@ void glTF2Importer::ImportLights(glTF2::Asset &r) { return; const unsigned int numLights = r.lights.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numLights, " lights"); + ASSIMP_LOG_DEBUG("Importing ", numLights, " lights"); mScene->mNumLights = numLights; mScene->mLights = new aiLight *[numLights]; std::fill(mScene->mLights, mScene->mLights + numLights, nullptr); @@ -1329,7 +1329,7 @@ void glTF2Importer::ImportAnimations(glTF2::Asset &r) { if (!r.scene) return; const unsigned numAnimations = r.animations.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numAnimations, " animations"); + ASSIMP_LOG_DEBUG("Importing ", numAnimations, " animations"); mScene->mNumAnimations = numAnimations; if (mScene->mNumAnimations == 0) { return; @@ -1445,7 +1445,7 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) { if (numEmbeddedTexs == 0) return; - ASSIMP_LOG_DEBUG_F("Importing ", numEmbeddedTexs, " embedded textures"); + ASSIMP_LOG_DEBUG("Importing ", numEmbeddedTexs, " embedded textures"); mScene->mTextures = new aiTexture *[numEmbeddedTexs]; std::fill(mScene->mTextures, mScene->mTextures + numEmbeddedTexs, nullptr); diff --git a/code/CApi/CInterfaceIOWrapper.cpp b/code/CApi/CInterfaceIOWrapper.cpp index ac358a4a8..8e2ac95c0 100644 --- a/code/CApi/CInterfaceIOWrapper.cpp +++ b/code/CApi/CInterfaceIOWrapper.cpp @@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { -CIOStreamWrapper::~CIOStreamWrapper(void) { +CIOStreamWrapper::~CIOStreamWrapper() { /* Various places depend on this destructor to close the file */ if (mFile) { mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile); @@ -78,7 +78,7 @@ aiReturn CIOStreamWrapper::Seek(size_t pOffset, } // ................................................................... -size_t CIOStreamWrapper::Tell(void) const { +size_t CIOStreamWrapper::Tell() const { return mFile->TellProc(mFile); } diff --git a/code/Common/BaseImporter.cpp b/code/Common/BaseImporter.cpp index 0657216cf..0f41e9e65 100644 --- a/code/Common/BaseImporter.cpp +++ b/code/Common/BaseImporter.cpp @@ -65,20 +65,6 @@ using namespace Assimp; // Constructor to be privately used by Importer BaseImporter::BaseImporter() AI_NO_EXCEPT : m_progress() { - /** - * Assimp Importer - * unit conversions available - * if you need another measurment unit add it below. - * it's currently defined in assimp that we prefer meters. - * - * NOTE: Initialised here rather than in the header file - * to workaround a VS2013 bug with brace initialisers - * */ - importerUnits[ImporterUnits::M] = 1.0; - importerUnits[ImporterUnits::CM] = 0.01; - importerUnits[ImporterUnits::MM] = 0.001; - importerUnits[ImporterUnits::INCHES] = 0.0254; - importerUnits[ImporterUnits::FEET] = 0.3048; } // ------------------------------------------------------------------------------------------------ @@ -97,7 +83,7 @@ void BaseImporter::UpdateImporterScale(Importer *pImp) { // Set active scaling pImp->SetPropertyFloat(AI_CONFIG_APP_SCALE_KEY, static_cast(activeScale)); - ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale); + ASSIMP_LOG_DEBUG("UpdateImporterScale scale set: ", activeScale); } // ------------------------------------------------------------------------------------------------ @@ -193,7 +179,7 @@ void BaseImporter::GetExtensionList(std::set &extensions) { } for (size_t i = 0; i < read; ++i) { - buffer[i] = static_cast(::tolower(buffer[i])); + buffer[i] = static_cast(::tolower((unsigned char)buffer[i])); } // It is not a proper handling of unicode files here ... @@ -214,7 +200,7 @@ void BaseImporter::GetExtensionList(std::set &extensions) { token.clear(); const char *ptr(tokens[i]); for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) { - token.push_back(static_cast(tolower(*ptr))); + token.push_back(static_cast(tolower(static_cast(*ptr)))); ++ptr; } const char *r = strstr(buffer, token.c_str()); @@ -223,13 +209,13 @@ void BaseImporter::GetExtensionList(std::set &extensions) { } // We need to make sure that we didn't accidentially identify the end of another token as our token, // e.g. in a previous version the "gltf " present in some gltf files was detected as "f " - if (noAlphaBeforeTokens && (r != buffer && isalpha(r[-1]))) { + if (noAlphaBeforeTokens && (r != buffer && isalpha(static_cast(r[-1])))) { continue; } // We got a match, either we don't care where it is, or it happens to // be in the beginning of the file / line if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') { - ASSIMP_LOG_DEBUG_F("Found positive match for header keyword: ", tokens[i]); + ASSIMP_LOG_DEBUG("Found positive match for header keyword: ", tokens[i]); return true; } } @@ -271,7 +257,7 @@ std::string BaseImporter::GetExtension(const std::string &file) { // no file extension at all if (pos == std::string::npos) { - return ""; + return std::string(); } // thanks to Andy Maloney for the hint @@ -618,7 +604,7 @@ void BatchLoader::LoadAll() { if (!DefaultLogger::isNullLogger()) { ASSIMP_LOG_INFO("%%% BEGIN EXTERNAL FILE %%%"); - ASSIMP_LOG_INFO_F("File: ", (*it).file); + ASSIMP_LOG_INFO("File: ", (*it).file); } m_data->pImporter->ReadFile((*it).file, pp); (*it).scene = m_data->pImporter->GetOrphanedScene(); diff --git a/code/Common/DefaultIOSystem.cpp b/code/Common/DefaultIOSystem.cpp index ec7a311cf..98d51a17d 100644 --- a/code/Common/DefaultIOSystem.cpp +++ b/code/Common/DefaultIOSystem.cpp @@ -176,7 +176,7 @@ inline static std::string MakeAbsolutePath(const char *in) { if (!ret) { // preserve the input path, maybe someone else is able to fix // the path before it is accessed (e.g. our file system filter) - ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in)); + ASSIMP_LOG_WARN("Invalid path: ", std::string(in)); out = in; } return out; diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index aa13ca5ce..4fa9c865b 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -177,9 +177,7 @@ void Logger::debug(const char *message) { // ---------------------------------------------------------------------------------- void Logger::verboseDebug(const char *message) { - // SECURITY FIX: otherwise it's easy to produce overruns since - // sometimes importers will include data from the input file - // (i.e. node names) in their messages. + // SECURITY FIX: see above if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { return; } diff --git a/code/Common/FileSystemFilter.h b/code/Common/FileSystemFilter.h index 1440cf97d..6585f9df6 100644 --- a/code/Common/FileSystemFilter.h +++ b/code/Common/FileSystemFilter.h @@ -76,7 +76,7 @@ public: if (std::string::npos != (ss2 = mBase.find_last_of("\\/"))) { mBase.erase(ss2,mBase.length()-ss2); } else { - mBase = ""; + mBase = std::string(); } // make sure the directory is terminated properly @@ -89,7 +89,7 @@ public: mBase += getOsSeparator(); } - DefaultLogger::get()->info("Import root directory is \'" + mBase + "\'"); + DefaultLogger::get()->info("Import root directory is \'", mBase, "\'"); } /** Destructor. */ diff --git a/code/Common/Importer.cpp b/code/Common/Importer.cpp index db7fc9e1c..a2ad041fb 100644 --- a/code/Common/Importer.cpp +++ b/code/Common/Importer.cpp @@ -149,7 +149,7 @@ void AllocateFromAssimpHeap::operator delete[] ( void* data) { Importer::Importer() : pimpl( new ImporterPimpl ) { pimpl->mScene = nullptr; - pimpl->mErrorString = ""; + pimpl->mErrorString = std::string(); // Allocate a default IO handler pimpl->mIOHandler = new DefaultIOSystem; @@ -232,7 +232,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp) { #ifdef ASSIMP_BUILD_DEBUG if (IsExtensionSupported(*it)) { - ASSIMP_LOG_WARN_F("The file extension ", *it, " is already in use"); + ASSIMP_LOG_WARN("The file extension ", *it, " is already in use"); } #endif baked += *it; @@ -240,7 +240,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp) { // add the loader pimpl->mImporter.push_back(pImp); - ASSIMP_LOG_INFO_F("Registering custom importer for these file extensions: ", baked); + ASSIMP_LOG_INFO("Registering custom importer for these file extensions: ", baked); ASSIMP_END_EXCEPTION_REGION(aiReturn); return AI_SUCCESS; @@ -387,7 +387,7 @@ void Importer::FreeScene( ) { delete pimpl->mScene; pimpl->mScene = nullptr; - pimpl->mErrorString = ""; + pimpl->mErrorString = std::string(); pimpl->mException = std::exception_ptr(); ASSIMP_END_EXCEPTION_REGION(void); } @@ -434,7 +434,7 @@ aiScene* Importer::GetOrphanedScene() { ASSIMP_BEGIN_EXCEPTION_REGION(); pimpl->mScene = nullptr; - pimpl->mErrorString = ""; // reset error string + pimpl->mErrorString = std::string(); pimpl->mException = std::exception_ptr(); ASSIMP_END_EXCEPTION_REGION(aiScene*); @@ -519,7 +519,7 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer, // ------------------------------------------------------------------------------------------------ void WriteLogOpening(const std::string& file) { - ASSIMP_LOG_INFO_F("Load ", file); + ASSIMP_LOG_INFO("Load ", file); // print a full version dump. This is nice because we don't // need to ask the authors of incoming bug reports for @@ -665,7 +665,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { if ( nullptr != desc ) { ext = desc->mName; } - ASSIMP_LOG_INFO("Found a matching importer for this file format: " + ext + "." ); + ASSIMP_LOG_INFO("Found a matching importer for this file format: ", ext, "." ); pimpl->mProgressHandler->UpdateFileRead( 0, fileSize ); if (profiler) { diff --git a/code/Common/ImporterRegistry.cpp b/code/Common/ImporterRegistry.cpp index a902fc89d..ddfcf6798 100644 --- a/code/Common/ImporterRegistry.cpp +++ b/code/Common/ImporterRegistry.cpp @@ -48,6 +48,7 @@ corresponding preprocessor flag to selectively disable formats. #include #include +#include // ------------------------------------------------------------------------------------------------ // Importers @@ -204,7 +205,17 @@ corresponding preprocessor flag to selectively disable formats. namespace Assimp { // ------------------------------------------------------------------------------------------------ -void GetImporterInstanceList(std::vector &out) { +void GetImporterInstanceList(std::vector &out) { + + // Some importers may be unimplemented or otherwise unsuitable for general use + // in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their + // local environment to enable them, otherwise they're left out of the registry. + const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS"); + bool devImportersEnabled = envStr && strcmp(envStr, "0"); + + // Ensure no unused var warnings if all uses are #ifndef'd away below: + (void)devImportersEnabled; + // ---------------------------------------------------------------------------- // Add an instance of each worker class here // (register_new_importers_here) @@ -354,7 +365,9 @@ void GetImporterInstanceList(std::vector &out) { out.push_back(new D3MFImporter()); #endif #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - out.push_back(new X3DImporter()); + if (devImportersEnabled) { // https://github.com/assimp/assimp/issues/3647 + out.push_back(new X3DImporter()); + } #endif #ifndef ASSIMP_BUILD_NO_MMD_IMPORTER out.push_back(new MMDImporter()); diff --git a/code/Common/SceneCombiner.cpp b/code/Common/SceneCombiner.cpp index e39660cd6..555d46b6a 100644 --- a/code/Common/SceneCombiner.cpp +++ b/code/Common/SceneCombiner.cpp @@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // possible as new fields are added to assimp structures. // ---------------------------------------------------------------------------- -/** +/** * @file Implements Assimp::SceneCombiner. This is a smart utility * class that combines multiple scenes, meshes, ... into one. Currently * these utilities are used by the IRR and LWS loaders and the @@ -359,7 +359,7 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vectormNumTextures) { - aiTexture **pip = dest->mTextures = new aiTexture *[dest->mNumMaterials]; + aiTexture **pip = dest->mTextures = new aiTexture *[dest->mNumTextures]; cnt = 0; for (unsigned int n = 0; n < src.size(); ++n) { SceneHelper *cur = &src[n]; @@ -612,7 +612,7 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vectormName.data, + ASSIMP_LOG_ERROR("SceneCombiner: Failed to resolve attachment ", (*it).node->mName.data, " ", (*it).attachToNode->mName.data); } } @@ -638,6 +638,8 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vectormMaterials = nullptr; delete[] deleteMe->mAnimations; deleteMe->mAnimations = nullptr; + delete[] deleteMe->mTextures; + deleteMe->mTextures = nullptr; deleteMe->mRootNode = nullptr; diff --git a/code/Common/Subdivision.cpp b/code/Common/Subdivision.cpp index 76fc83404..9e7577a04 100644 --- a/code/Common/Subdivision.cpp +++ b/code/Common/Subdivision.cpp @@ -336,7 +336,7 @@ void CatmullClarkSubdivider::InternSubdivide( // Report the number of bad edges. bad edges are referenced by less than two // faces in the mesh. They occur at outer model boundaries in non-closed // shapes. - ASSIMP_LOG_VERBOSE_DEBUG_F("Catmull-Clark Subdivider: got ", bad_cnt, " bad edges touching only one face (totally ", + ASSIMP_LOG_VERBOSE_DEBUG("Catmull-Clark Subdivider: got ", bad_cnt, " bad edges touching only one face (totally ", static_cast(edges.size()), " edges). "); } } diff --git a/code/Common/scene.cpp b/code/Common/scene.cpp index 82430f5fc..67feb7afb 100644 --- a/code/Common/scene.cpp +++ b/code/Common/scene.cpp @@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include aiNode::aiNode() -: mName("") +: mName() , mParent(nullptr) , mNumChildren(0) , mChildren(nullptr) diff --git a/code/Material/MaterialSystem.cpp b/code/Material/MaterialSystem.cpp index 310dea29d..c35a1aa93 100644 --- a/code/Material/MaterialSystem.cpp +++ b/code/Material/MaterialSystem.cpp @@ -160,7 +160,7 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial *pMat, break; } if (!IsSpace(*cur)) { - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + + ASSIMP_LOG_ERROR("Material property", pKey, " is a string; failed to parse a float array out of it."); return AI_FAILURE; } @@ -238,7 +238,7 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial *pMat, break; } if (!IsSpace(*cur)) { - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + + ASSIMP_LOG_ERROR("Material property", pKey, " is a string; failed to parse an integer array out of it."); return AI_FAILURE; } @@ -306,8 +306,7 @@ aiReturn aiGetMaterialString(const aiMaterial *pMat, memcpy(pOut->data, prop->mData + 4, pOut->length + 1); } else { // TODO - implement lexical cast as well - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + - " was found, but is no string"); + ASSIMP_LOG_ERROR("Material property", pKey, " was found, but is no string"); return AI_FAILURE; } return AI_SUCCESS; diff --git a/code/PostProcessing/ArmaturePopulate.cpp b/code/PostProcessing/ArmaturePopulate.cpp index 88b0b2d7c..fdf7508d0 100644 --- a/code/PostProcessing/ArmaturePopulate.cpp +++ b/code/PostProcessing/ArmaturePopulate.cpp @@ -77,12 +77,12 @@ void ArmaturePopulate::Execute(aiScene *out) { BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes); - ASSIMP_LOG_DEBUG_F("Bone stack size: ", bone_stack.size()); + ASSIMP_LOG_DEBUG("Bone stack size: ", bone_stack.size()); for (std::pair kvp : bone_stack) { aiBone *bone = kvp.first; aiNode *bone_node = kvp.second; - ASSIMP_LOG_VERBOSE_DEBUG_F("active node lookup: ", bone->mName.C_Str()); + ASSIMP_LOG_VERBOSE_DEBUG("active node lookup: ", bone->mName.C_Str()); // lcl transform grab - done in generate_nodes :) // bone->mOffsetMatrix = bone_node->mTransformation; @@ -179,7 +179,7 @@ void ArmaturePopulate::BuildBoneStack(aiNode *, if (node == nullptr) { node_stack.clear(); BuildNodeList(root_node, node_stack); - ASSIMP_LOG_VERBOSE_DEBUG_F("Resetting bone stack: nullptr element ", bone->mName.C_Str()); + ASSIMP_LOG_VERBOSE_DEBUG("Resetting bone stack: nullptr element ", bone->mName.C_Str()); node = GetNodeFromStack(bone->mName, node_stack); @@ -189,7 +189,7 @@ void ArmaturePopulate::BuildBoneStack(aiNode *, } } - ASSIMP_LOG_VERBOSE_DEBUG_F("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str()); + ASSIMP_LOG_VERBOSE_DEBUG("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str()); bone_stack.insert(std::pair(bone, node)); } @@ -203,7 +203,7 @@ aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node, std::vector &bone_list) { while (nullptr != bone_node) { if (!IsBoneNode(bone_node->mName, bone_list)) { - ASSIMP_LOG_VERBOSE_DEBUG_F("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str()); + ASSIMP_LOG_VERBOSE_DEBUG("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str()); return bone_node; } @@ -247,7 +247,7 @@ aiNode *ArmaturePopulate::GetNodeFromStack(const aiString &node_name, } if (found != nullptr) { - ASSIMP_LOG_INFO_F("Removed node from stack: ", found->mName.C_Str()); + ASSIMP_LOG_INFO("Removed node from stack: ", found->mName.C_Str()); // now pop the element from the node list nodes.erase(iter); diff --git a/code/PostProcessing/CalcTangentsProcess.cpp b/code/PostProcessing/CalcTangentsProcess.cpp index cdafda3b6..46feff4a1 100644 --- a/code/PostProcessing/CalcTangentsProcess.cpp +++ b/code/PostProcessing/CalcTangentsProcess.cpp @@ -129,7 +129,7 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) { return false; } if (configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV]) { - ASSIMP_LOG_ERROR((Formatter::format("Failed to compute tangents; need UV data in channel"), configSourceUV)); + ASSIMP_LOG_ERROR("Failed to compute tangents; need UV data in channel", configSourceUV); return false; } diff --git a/code/PostProcessing/DeboneProcess.cpp b/code/PostProcessing/DeboneProcess.cpp index b5ed66268..3783bb65c 100644 --- a/code/PostProcessing/DeboneProcess.cpp +++ b/code/PostProcessing/DeboneProcess.cpp @@ -148,7 +148,7 @@ void DeboneProcess::Execute( aiScene* pScene) } if(!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Removed %u bones. Input bones:", in - out, ". Output bones: ", out); + ASSIMP_LOG_INFO("Removed %u bones. Input bones:", in - out, ". Output bones: ", out); } // and destroy the source mesh. It should be completely contained inside the new submeshes diff --git a/code/PostProcessing/EmbedTexturesProcess.cpp b/code/PostProcessing/EmbedTexturesProcess.cpp index dc304ff9c..7e435e556 100644 --- a/code/PostProcessing/EmbedTexturesProcess.cpp +++ b/code/PostProcessing/EmbedTexturesProcess.cpp @@ -93,7 +93,7 @@ void EmbedTexturesProcess::Execute(aiScene* pScene) { } } - ASSIMP_LOG_INFO_F("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." ); + ASSIMP_LOG_INFO("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." ); } bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { @@ -103,7 +103,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { // Test path directly std::ifstream file(imagePath, std::ios::binary | std::ios::ate); if ((imageSize = file.tellg()) == std::streampos(-1)) { - ASSIMP_LOG_WARN_F("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder."); + ASSIMP_LOG_WARN("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder."); // Test path in root path imagePath = mRootPath + path; @@ -113,7 +113,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u); file.open(imagePath, std::ios::binary | std::ios::ate); if ((imageSize = file.tellg()) == std::streampos(-1)) { - ASSIMP_LOG_ERROR_F("EmbedTexturesProcess: Unable to embed texture: ", path, "."); + ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", path, "."); return false; } } diff --git a/code/PostProcessing/FindDegenerates.cpp b/code/PostProcessing/FindDegenerates.cpp index 1fc58cf59..eae91ff02 100644 --- a/code/PostProcessing/FindDegenerates.cpp +++ b/code/PostProcessing/FindDegenerates.cpp @@ -291,7 +291,7 @@ evil_jump_outside: } if (deg && !DefaultLogger::isNullLogger()) { - ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives"); + ASSIMP_LOG_WARN( "Found ", deg, " degenerated primitives"); } return false; } diff --git a/code/PostProcessing/FindInstancesProcess.cpp b/code/PostProcessing/FindInstancesProcess.cpp index 98527e531..ab5f52b78 100644 --- a/code/PostProcessing/FindInstancesProcess.cpp +++ b/code/PostProcessing/FindInstancesProcess.cpp @@ -267,7 +267,7 @@ void FindInstancesProcess::Execute( aiScene* pScene) // write to log if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F( "FindInstancesProcess finished. Found ", (pScene->mNumMeshes - numMeshesOut), " instances" ); + ASSIMP_LOG_INFO( "FindInstancesProcess finished. Found ", (pScene->mNumMeshes - numMeshesOut), " instances" ); } pScene->mNumMeshes = numMeshesOut; } else { diff --git a/code/PostProcessing/FindInvalidDataProcess.cpp b/code/PostProcessing/FindInvalidDataProcess.cpp index 9c19c606a..ea7d99094 100644 --- a/code/PostProcessing/FindInvalidDataProcess.cpp +++ b/code/PostProcessing/FindInvalidDataProcess.cpp @@ -200,7 +200,7 @@ inline bool ProcessArray(T *&in, unsigned int num, const char *name, const std::vector &dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) { const char *err = ValidateArrayContents(in, num, dirtyMask, mayBeIdentical, mayBeZero); if (err) { - ASSIMP_LOG_ERROR_F("FindInvalidDataProcess fails on mesh ", name, ": ", err); + ASSIMP_LOG_ERROR("FindInvalidDataProcess fails on mesh ", name, ": ", err); delete[] in; in = nullptr; return true; diff --git a/code/PostProcessing/FixNormalsStep.cpp b/code/PostProcessing/FixNormalsStep.cpp index 850da5e25..09b1f1908 100644 --- a/code/PostProcessing/FixNormalsStep.cpp +++ b/code/PostProcessing/FixNormalsStep.cpp @@ -164,7 +164,7 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index) // now compare the volumes of the bounding boxes if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) < std::fabs(fDelta1_x * fDelta1_yz)) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Mesh ", index, ": Normals are facing inwards (or the mesh is planar)", index); + ASSIMP_LOG_INFO("Mesh ", index, ": Normals are facing inwards (or the mesh is planar)", index); } // Invert normals diff --git a/code/PostProcessing/GenFaceNormalsProcess.cpp b/code/PostProcessing/GenFaceNormalsProcess.cpp index a73df2b5d..3e8612d29 100644 --- a/code/PostProcessing/GenFaceNormalsProcess.cpp +++ b/code/PostProcessing/GenFaceNormalsProcess.cpp @@ -70,6 +70,7 @@ GenFaceNormalsProcess::~GenFaceNormalsProcess() { // Returns whether the processing step is present in the given flag field. bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const { force_ = (pFlags & aiProcess_ForceGenNormals) != 0; + flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0; return (pFlags & aiProcess_GenNormals) != 0; } @@ -134,6 +135,8 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals(aiMesh *pMesh) { const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]]; + if (flippedWindingOrder_) + std::swap( pV2, pV3 ); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe(); for (unsigned int i = 0; i < face.mNumIndices; ++i) { diff --git a/code/PostProcessing/GenFaceNormalsProcess.h b/code/PostProcessing/GenFaceNormalsProcess.h index 4b9222af3..eefff6c73 100644 --- a/code/PostProcessing/GenFaceNormalsProcess.h +++ b/code/PostProcessing/GenFaceNormalsProcess.h @@ -80,6 +80,7 @@ public: private: bool GenMeshFaceNormals(aiMesh* pcMesh); mutable bool force_ = false; + mutable bool flippedWindingOrder_ = false; }; } // end of namespace Assimp diff --git a/code/PostProcessing/GenVertexNormalsProcess.cpp b/code/PostProcessing/GenVertexNormalsProcess.cpp index 5c9a6b754..e82bc3e6f 100644 --- a/code/PostProcessing/GenVertexNormalsProcess.cpp +++ b/code/PostProcessing/GenVertexNormalsProcess.cpp @@ -70,6 +70,7 @@ GenVertexNormalsProcess::~GenVertexNormalsProcess() { // Returns whether the processing step is present in the given flag field. bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const { force_ = (pFlags & aiProcess_ForceGenNormals) != 0; + flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0; return (pFlags & aiProcess_GenSmoothNormals) != 0; } @@ -142,6 +143,8 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int m const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]]; + if (flippedWindingOrder_) + std::swap( pV2, pV3 ); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe(); for (unsigned int i = 0; i < face.mNumIndices; ++i) { diff --git a/code/PostProcessing/GenVertexNormalsProcess.h b/code/PostProcessing/GenVertexNormalsProcess.h index 8b98ea8e6..8fc301ab7 100644 --- a/code/PostProcessing/GenVertexNormalsProcess.h +++ b/code/PostProcessing/GenVertexNormalsProcess.h @@ -104,6 +104,7 @@ private: /** Configuration option: maximum smoothing angle, in radians*/ ai_real configMaxAngle; mutable bool force_ = false; + mutable bool flippedWindingOrder_ = false; }; } // end of namespace Assimp diff --git a/code/PostProcessing/ImproveCacheLocality.cpp b/code/PostProcessing/ImproveCacheLocality.cpp index 38d5c5a5b..3243c40b4 100644 --- a/code/PostProcessing/ImproveCacheLocality.cpp +++ b/code/PostProcessing/ImproveCacheLocality.cpp @@ -109,7 +109,7 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene) { } if (!DefaultLogger::isNullLogger()) { if (numf > 0) { - ASSIMP_LOG_INFO_F("Cache relevant are ", numm, " meshes (", numf, " faces). Average output ACMR is ", out / numf); + ASSIMP_LOG_INFO("Cache relevant are ", numm, " meshes (", numf, " faces). Average output ACMR is ", out / numf); } ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess finished. "); } @@ -355,7 +355,7 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me // very intense verbose logging ... prepare for much text if there are many meshes if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) { - ASSIMP_LOG_VERBOSE_DEBUG_F("Mesh %u | ACMR in: ", meshNum, " out: ", fACMR, " | ~", fACMR2, ((fACMR - fACMR2) / fACMR) * 100.f); + ASSIMP_LOG_VERBOSE_DEBUG("Mesh %u | ACMR in: ", meshNum, " out: ", fACMR, " | ~", fACMR2, ((fACMR - fACMR2) / fACMR) * 100.f); } fACMR2 *= pMesh->mNumFaces; diff --git a/code/PostProcessing/JoinVerticesProcess.cpp b/code/PostProcessing/JoinVerticesProcess.cpp index 22b399471..60c64f3bf 100644 --- a/code/PostProcessing/JoinVerticesProcess.cpp +++ b/code/PostProcessing/JoinVerticesProcess.cpp @@ -100,7 +100,7 @@ void JoinVerticesProcess::Execute( aiScene* pScene) if (iNumOldVertices == iNumVertices) { ASSIMP_LOG_DEBUG("JoinVerticesProcess finished "); } else { - ASSIMP_LOG_INFO_F("JoinVerticesProcess finished | Verts in: ", iNumOldVertices, + ASSIMP_LOG_INFO("JoinVerticesProcess finished | Verts in: ", iNumOldVertices, " out: ", iNumVertices, " | ~", ((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f ); } @@ -373,7 +373,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) } if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) { - ASSIMP_LOG_VERBOSE_DEBUG_F( + ASSIMP_LOG_VERBOSE_DEBUG( "Mesh ",meshIndex, " (", (pMesh->mName.length ? pMesh->mName.data : "unnamed"), diff --git a/code/PostProcessing/LimitBoneWeightsProcess.cpp b/code/PostProcessing/LimitBoneWeightsProcess.cpp index c7ecf1b00..fb8b49b91 100644 --- a/code/PostProcessing/LimitBoneWeightsProcess.cpp +++ b/code/PostProcessing/LimitBoneWeightsProcess.cpp @@ -191,6 +191,6 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh) pMesh->mNumBones = writeBone; if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones); + ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones); } } diff --git a/code/PostProcessing/OptimizeGraph.cpp b/code/PostProcessing/OptimizeGraph.cpp index ad49b635a..e33c2ab18 100644 --- a/code/PostProcessing/OptimizeGraph.cpp +++ b/code/PostProcessing/OptimizeGraph.cpp @@ -335,7 +335,7 @@ void OptimizeGraphProcess::Execute(aiScene *pScene) { pScene->mRootNode->mParent = nullptr; if (!DefaultLogger::isNullLogger()) { if (nodes_in != nodes_out) { - ASSIMP_LOG_INFO_F("OptimizeGraphProcess finished; Input nodes: ", nodes_in, ", Output nodes: ", nodes_out); + ASSIMP_LOG_INFO("OptimizeGraphProcess finished; Input nodes: ", nodes_in, ", Output nodes: ", nodes_out); } else { ASSIMP_LOG_DEBUG("OptimizeGraphProcess finished"); } diff --git a/code/PostProcessing/OptimizeMeshes.cpp b/code/PostProcessing/OptimizeMeshes.cpp index dd81644de..939284ee4 100644 --- a/code/PostProcessing/OptimizeMeshes.cpp +++ b/code/PostProcessing/OptimizeMeshes.cpp @@ -151,7 +151,7 @@ void OptimizeMeshesProcess::Execute( aiScene* pScene) std::copy(output.begin(),output.end(),mScene->mMeshes); if (output.size() != num_old) { - ASSIMP_LOG_DEBUG_F("OptimizeMeshesProcess finished. Input meshes: ", num_old, ", Output meshes: ", pScene->mNumMeshes); + ASSIMP_LOG_DEBUG("OptimizeMeshesProcess finished. Input meshes: ", num_old, ", Output meshes: ", pScene->mNumMeshes); } else { ASSIMP_LOG_DEBUG( "OptimizeMeshesProcess finished" ); } diff --git a/code/PostProcessing/PretransformVertices.cpp b/code/PostProcessing/PretransformVertices.cpp index d1740f30b..e9a3af0d2 100644 --- a/code/PostProcessing/PretransformVertices.cpp +++ b/code/PostProcessing/PretransformVertices.cpp @@ -429,7 +429,7 @@ void PretransformVertices::Execute(aiScene *pScene) { const unsigned int iOldNodes = CountNodes(pScene->mRootNode); if (configTransform) { - pScene->mRootNode->mTransformation = configTransformation; + pScene->mRootNode->mTransformation = configTransformation * pScene->mRootNode->mTransformation; } // first compute absolute transformation matrices for all nodes @@ -680,9 +680,9 @@ void PretransformVertices::Execute(aiScene *pScene) { if (!DefaultLogger::isNullLogger()) { ASSIMP_LOG_DEBUG("PretransformVerticesProcess finished"); - ASSIMP_LOG_INFO_F("Removed ", iOldNodes, " nodes and ", iOldAnimationChannels, " animation channels (", + ASSIMP_LOG_INFO("Removed ", iOldNodes, " nodes and ", iOldAnimationChannels, " animation channels (", CountNodes(pScene->mRootNode), " output nodes)"); - ASSIMP_LOG_INFO_F("Kept ", pScene->mNumLights, " lights and ", pScene->mNumCameras, " cameras."); - ASSIMP_LOG_INFO_F("Moved ", iOldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")"); + ASSIMP_LOG_INFO("Kept ", pScene->mNumLights, " lights and ", pScene->mNumCameras, " cameras."); + ASSIMP_LOG_INFO("Moved ", iOldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")"); } } diff --git a/code/PostProcessing/RemoveRedundantMaterials.cpp b/code/PostProcessing/RemoveRedundantMaterials.cpp index 5264d3608..c252f37a5 100644 --- a/code/PostProcessing/RemoveRedundantMaterials.cpp +++ b/code/PostProcessing/RemoveRedundantMaterials.cpp @@ -122,7 +122,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) // Keep this material even if no mesh references it abReferenced[i] = true; - ASSIMP_LOG_VERBOSE_DEBUG_F( "Found positive match in exclusion list: \'", name.data, "\'"); + ASSIMP_LOG_VERBOSE_DEBUG( "Found positive match in exclusion list: \'", name.data, "\'"); } } } @@ -215,7 +215,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) } else { - ASSIMP_LOG_INFO_F("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ", + ASSIMP_LOG_INFO("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ", unreferencedRemoved, " unused materials."); } } diff --git a/code/PostProcessing/RemoveRedundantMaterials.h b/code/PostProcessing/RemoveRedundantMaterials.h index 6b4f8b1fb..4210a7fe2 100644 --- a/code/PostProcessing/RemoveRedundantMaterials.h +++ b/code/PostProcessing/RemoveRedundantMaterials.h @@ -81,7 +81,7 @@ public: /** @brief Set list of fixed (inmutable) materials * @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST */ - void SetFixedMaterialsString(const std::string& fixed = "") { + void SetFixedMaterialsString(const std::string& fixed = std::string()) { mConfigFixedMaterials = fixed; } diff --git a/code/PostProcessing/SplitByBoneCountProcess.cpp b/code/PostProcessing/SplitByBoneCountProcess.cpp index 1f4170a6a..2613d8561 100644 --- a/code/PostProcessing/SplitByBoneCountProcess.cpp +++ b/code/PostProcessing/SplitByBoneCountProcess.cpp @@ -103,7 +103,7 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene) if( !isNecessary ) { - ASSIMP_LOG_DEBUG( format() << "SplitByBoneCountProcess early-out: no meshes with more than " << mMaxBoneCount << " bones." ); + ASSIMP_LOG_DEBUG("SplitByBoneCountProcess early-out: no meshes with more than ", mMaxBoneCount, " bones." ); return; } @@ -151,7 +151,7 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene) // recurse through all nodes and translate the node's mesh indices to fit the new mesh array UpdateNode( pScene->mRootNode); - ASSIMP_LOG_DEBUG( format() << "SplitByBoneCountProcess end: split " << mSubMeshIndices.size() << " meshes into " << meshes.size() << " submeshes." ); + ASSIMP_LOG_DEBUG( "SplitByBoneCountProcess end: split ", mSubMeshIndices.size(), " meshes into ", meshes.size(), " submeshes." ); } // ------------------------------------------------------------------------------------------------ diff --git a/code/PostProcessing/TextureTransform.cpp b/code/PostProcessing/TextureTransform.cpp index a2f20a082..681b047c0 100644 --- a/code/PostProcessing/TextureTransform.cpp +++ b/code/PostProcessing/TextureTransform.cpp @@ -108,7 +108,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info) if (rounded) { out -= rounded * static_cast(AI_MATH_PI); - ASSIMP_LOG_INFO_F("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out); + ASSIMP_LOG_INFO("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out); } // Next step - convert negative rotation angles to positives @@ -448,7 +448,7 @@ void TextureTransformStep::Execute( aiScene* pScene) if (size > AI_MAX_NUMBER_OF_TEXTURECOORDS) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_ERROR_F(static_cast(trafo.size()), " UV channels required but just ", + ASSIMP_LOG_ERROR(static_cast(trafo.size()), " UV channels required but just ", AI_MAX_NUMBER_OF_TEXTURECOORDS, " available"); } size = AI_MAX_NUMBER_OF_TEXTURECOORDS; @@ -557,7 +557,7 @@ void TextureTransformStep::Execute( aiScene* pScene) if (!DefaultLogger::isNullLogger()) { if (transformedChannels) { - ASSIMP_LOG_INFO_F("TransformUVCoordsProcess end: ", outChannels, " output channels (in: ", inChannels, ", modified: ", transformedChannels,")"); + ASSIMP_LOG_INFO("TransformUVCoordsProcess end: ", outChannels, " output channels (in: ", inChannels, ", modified: ", transformedChannels,")"); } else { ASSIMP_LOG_DEBUG("TransformUVCoordsProcess finished"); } diff --git a/code/PostProcessing/ValidateDataStructure.cpp b/code/PostProcessing/ValidateDataStructure.cpp index 3058ca6ce..6a872ef11 100644 --- a/code/PostProcessing/ValidateDataStructure.cpp +++ b/code/PostProcessing/ValidateDataStructure.cpp @@ -99,7 +99,7 @@ void ValidateDSProcess::ReportWarning(const char *msg, ...) { ai_assert(iLen > 0); va_end(args); - ASSIMP_LOG_WARN("Validation warning: " + std::string(szBuffer, iLen)); + ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen)); } // ------------------------------------------------------------------------------------------------ diff --git a/contrib/draco/src/draco/io/parser_utils.cc b/contrib/draco/src/draco/io/parser_utils.cc index 753a1b314..4f95f6f84 100644 --- a/contrib/draco/src/draco/io/parser_utils.cc +++ b/contrib/draco/src/draco/io/parser_utils.cc @@ -252,7 +252,7 @@ DecoderBuffer ParseLineIntoDecoderBuffer(DecoderBuffer *buffer) { std::string ToLower(const std::string &str) { std::string out; - std::transform(str.begin(), str.end(), std::back_inserter(out), tolower); + std::transform(str.begin(), str.end(), std::back_inserter(out), [](unsigned char c){return tolower(c);}); return out; } diff --git a/contrib/draco/src/draco/io/ply_reader.cc b/contrib/draco/src/draco/io/ply_reader.cc index ea7f2689a..cb32df225 100644 --- a/contrib/draco/src/draco/io/ply_reader.cc +++ b/contrib/draco/src/draco/io/ply_reader.cc @@ -268,14 +268,14 @@ std::vector PlyReader::SplitWords(const std::string &line) { while ((end = line.find_first_of(" \t\n\v\f\r", start)) != std::string::npos) { const std::string word(line.substr(start, end - start)); - if (!std::all_of(word.begin(), word.end(), isspace)) { + if (!std::all_of(word.begin(), word.end(), [](unsigned char c){return isspace(c);})) { output.push_back(word); } start = end + 1; } const std::string last_word(line.substr(start)); - if (!std::all_of(last_word.begin(), last_word.end(), isspace)) { + if (!std::all_of(last_word.begin(), last_word.end(), [](unsigned char c){return isspace(c);})) { output.push_back(last_word); } return output; diff --git a/contrib/gtest/include/gtest/internal/gtest-param-util.h b/contrib/gtest/include/gtest/internal/gtest-param-util.h index 82cab9b02..9d725a433 100644 --- a/contrib/gtest/include/gtest/internal/gtest-param-util.h +++ b/contrib/gtest/include/gtest/internal/gtest-param-util.h @@ -644,7 +644,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { // Check for invalid characters for (std::string::size_type index = 0; index < name.size(); ++index) { - if (!isalnum(name[index]) && name[index] != '_') + if (!IsAlNum(name[index]) && name[index] != '_') return false; } diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 024c26f41..6a9f802ec 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -72,13 +72,15 @@ const char *getTypeToken(Value::ValueType type) { } static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) { - std::stringstream stream; - stream << "Invalid token \"" << *in << "\"" - << " expected \"" << exp << "\"" << std::endl; - std::string full(in); - std::string part(full.substr(0, 50)); - stream << part; - callback(ddl_error_msg, stream.str()); + if (callback) { + std::string full(in); + std::string part(full.substr(0, 50)); + std::stringstream stream; + stream << "Invalid token \"" << *in << "\" " + << "(expected \"" << exp << "\") " + << "in: \"" << part << "\""; + callback(ddl_error_msg, stream.str()); + } } static bool isIntegerType(Value::ValueType integerType) { @@ -111,26 +113,8 @@ static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) { return node; } -static void logMessage(LogSeverity severity, const std::string &msg) { - std::string log; - if (ddl_debug_msg == severity) { - log += "Debug:"; - } else if (ddl_info_msg == severity) { - log += "Info :"; - } else if (ddl_warn_msg == severity) { - log += "Warn :"; - } else if (ddl_error_msg == severity) { - log += "Error:"; - } else { - log += "None :"; - } - - log += msg; - std::cout << log; -} - OpenDDLParser::OpenDDLParser() : - m_logCallback(logMessage), + m_logCallback(nullptr), m_buffer(), m_stack(), m_context(nullptr) { @@ -138,7 +122,7 @@ OpenDDLParser::OpenDDLParser() : } OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) : - m_logCallback(&logMessage), m_buffer(), m_context(nullptr) { + m_logCallback(nullptr), m_buffer(), m_context(nullptr) { if (0 != len) { setBuffer(buffer, len); } @@ -149,13 +133,8 @@ OpenDDLParser::~OpenDDLParser() { } void OpenDDLParser::setLogCallback(logCallback callback) { - if (nullptr != callback) { - // install user-specific log callback - m_logCallback = callback; - } else { - // install default log callback - m_logCallback = &logMessage; - } + // install user-specific log callback; null = no log callback + m_logCallback = callback; } OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const { diff --git a/contrib/zip/.gitignore b/contrib/zip/.gitignore deleted file mode 100644 index 49b2cb2fd..000000000 --- a/contrib/zip/.gitignore +++ /dev/null @@ -1,58 +0,0 @@ -/build/ -/test/build/ -/xcodeproj/ -.vscode/ - -# Object files -*.o -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib -*.suo - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Temporary -*.swp -.DS_Store - -# CMake -CMakeScripts -*.cmake - -# Xcode -*.build -*.xcodeproj -zip.sln -zip.vcxproj.filters -zip.vcxproj -ALL_BUILD.vcxproj.filters -ALL_BUILD.vcxproj -CMakeFiles/ -zip.dir/ -test/test.exe.vcxproj.filters -test/test.exe.vcxproj -test/test.exe.dir/ - diff --git a/contrib/zip/CMakeLists.txt b/contrib/zip/CMakeLists.txt index cdfa94b3b..bba4e7bde 100644 --- a/contrib/zip/CMakeLists.txt +++ b/contrib/zip/CMakeLists.txt @@ -1,26 +1,29 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.4) project(zip LANGUAGES C - VERSION "0.1.18") + VERSION "0.1.19") set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) - +set(CMAKE_VERBOSE_MAKEFILE ON) option(CMAKE_DISABLE_TESTING "Disable test creation" OFF) -if (MSVC) - # Use secure functions by default and suppress warnings about "deprecated" functions - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1") -elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR - "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR - "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Werror -pedantic") -endif (MSVC) - # zip set(SRC src/miniz.h src/zip.h src/zip.c) -add_library(${PROJECT_NAME} ${SRC}) + +# this is the "object library" target: compiles the sources only once +add_library(OBJLIB OBJECT ${SRC}) +# shared libraries need PIC +set_property(TARGET OBJLIB PROPERTY POSITION_INDEPENDENT_CODE 1) + +# static and shared libraries built from the same object files +if (BUILD_SHARED_LIBS) + add_library(${PROJECT_NAME} SHARED $) + include(GenerateExportHeader) + generate_export_header(${PROJECT_NAME}) +else() + add_library(${PROJECT_NAME} STATIC $) +endif() + target_include_directories(${PROJECT_NAME} PUBLIC $ $ @@ -34,6 +37,17 @@ if (NOT CMAKE_DISABLE_TESTING) add_sanitizers(${PROJECT_NAME} ${test_out}) endif() +if (MSVC) + # Use secure functions by default and suppress warnings about "deprecated" functions + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1") +elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR + "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR + "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror -pedantic -Wno-deprecated") +endif (MSVC) + #### # Installation (https://github.com/forexample/package-example) { diff --git a/contrib/zip/README.md b/contrib/zip/README.md index bdd0822b6..308327a3f 100644 --- a/contrib/zip/README.md +++ b/contrib/zip/README.md @@ -2,7 +2,6 @@ This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API. [![Build](https://github.com/kuba--/zip/workflows/build/badge.svg)](https://github.com/kuba--/zip/actions?query=workflow%3Abuild) -[![Version](https://badge.fury.io/gh/kuba--%2Fzip.svg)](https://github.com/kuba--/zip/releases) # The Idea @@ -155,10 +154,52 @@ struct zip_t *zip = zip_open("foo.zip", 0, 'r'); zip_close(zip); ``` +* Create a new zip archive in memory (stream API). + +```c +char *outbuf = NULL; +size_t outbufsize = 0; + +const char *inbuf = "Append some data here...\0"; +struct zip_t *zip = zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w'); +{ + zip_entry_open(zip, "foo-1.txt"); + { + zip_entry_write(zip, inbuf, strlen(inbuf)); + } + zip_entry_close(zip); + + /* copy compressed stream into outbuf */ + zip_stream_copy(zip, (void **)&outbuf, &outbufsize); +} +zip_stream_close(zip); + +free(outbuf); +``` + +* Extract a zip entry into a memory (stream API). + +```c +char *buf = NULL; +ssize_t bufsize = 0; + +struct zip_t *zip = zip_stream_open(zipstream, zipstreamsize, 0, 'r'); +{ + zip_entry_open(zip, "foo-1.txt"); + { + zip_entry_read(zip, (void **)&buf, &bufsize); + } + zip_entry_close(zip); +} +zip_stream_close(zip); + +free(buf); +``` + * List of all zip entries ```c struct zip_t *zip = zip_open("foo.zip", 0, 'r'); -int i, n = zip_total_entries(zip); +int i, n = zip_entries_total(zip); for (i = 0; i < n; ++i) { zip_entry_openbyindex(zip, i); { @@ -172,6 +213,49 @@ for (i = 0; i < n; ++i) { zip_close(zip); ``` +* Compress folder (recursively) +```c +void zip_walk(struct zip_t *zip, const char *path) { + DIR *dir; + struct dirent *entry; + char fullpath[MAX_PATH]; + struct stat s; + + memset(fullpath, 0, MAX_PATH); + dir = opendir(path); + assert(dir); + + while ((entry = readdir(dir))) { + // skip "." and ".." + if (!strcmp(entry->d_name, ".\0") || !strcmp(entry->d_name, "..\0")) + continue; + + snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name); + stat(fullpath, &s); + if (S_ISDIR(s.st_mode)) + zip_walk(zip, fullpath); + else { + zip_entry_open(zip, fullpath); + zip_entry_fwrite(zip, fullpath); + zip_entry_close(zip); + } + } + + closedir(dir); +} +``` + +* Deletes zip archive entries. +```c +char *entries[] = {"unused.txt", "remove.ini", "delete.me"}; + +struct zip_t *zip = zip_open("foo.zip", 0, 'd'); +{ + zip_entries_delete(zip, entries, 3); +} +zip_close(zip); +``` + # Bindings Compile zip library as a dynamic library. ```shell @@ -181,7 +265,7 @@ $ cmake -DBUILD_SHARED_LIBS=true .. $ make ``` -### Go (cgo) +### [Go](https://golang.org) (cgo) ```go package main @@ -211,7 +295,7 @@ func main() { } ``` -### Rust (ffi) +### [Rust](https://www.rust-lang.org) (ffi) ```rust extern crate libc; use std::ffi::CString; @@ -236,7 +320,7 @@ extern "C" { } fn main() { - let path = CString::new("/tmp/test.zip").unwrap(); + let path = CString::new("/tmp/rust.zip").unwrap(); let mode: libc::c_char = 'w' as libc::c_char; let entryname = CString::new("test.txt").unwrap(); @@ -258,7 +342,7 @@ fn main() { } ``` -### Ruby (ffi) +### [Ruby](http://www.ruby-lang.org) (ffi) Install _ffi_ gem. ```shell $ gem install ffi @@ -291,7 +375,7 @@ Zip.zip_entry_close(ptr) Zip.zip_close(ptr) ``` -### Python (cffi) +### [Python](https://www.python.org) (cffi) Install _cffi_ package ```shell $ pip install cffi @@ -325,7 +409,36 @@ Zip.zip_entry_close(ptr) Zip.zip_close(ptr) ``` -### Ring +### [Never](https://never-lang.readthedocs.io/) (ffi) +```never +extern "libzip.so" func zip_open(zipname: string, level: int, mode: char) -> c_ptr +extern "libzip.so" func zip_close(zip: c_ptr) -> void + +extern "libzip.so" func zip_entry_open(zip: c_ptr, entryname: string) -> int +extern "libzip.so" func zip_entry_close(zip: c_ptr) -> int +extern "libzip.so" func zip_entry_write(zip: c_ptr, buf: string, bufsize: int) -> int +extern "libzip.so" func zip_entry_fwrite(zip: c_ptr, filename: string) -> int + +func main() -> int +{ + let content = "Test content" + + let zip = zip_open("/tmp/never.zip", 6, 'w'); + + zip_entry_open(zip, "test.file"); + zip_entry_fwrite(zip, "/tmp/test.txt"); + zip_entry_close(zip); + + zip_entry_open(zip, "test.content"); + zip_entry_write(zip, content, length(content)); + zip_entry_close(zip); + + zip_close(zip); + 0 +} +``` + +### [Ring](http://ring-lang.net) The language comes with RingZip based on this library ```ring load "ziplib.ring" @@ -342,13 +455,15 @@ new Zip { } ``` -# Contribution Rules/Coding Standards -No need to throw away your coding style, just do your best to follow default clang-format style. -Apply `clang-format` to the source files before commit: -```sh -for file in $(git ls-files | \grep -E '\.(c|h)$' | \grep -v -- '#') -do - clang-format -i $file -done -``` +# Check out more cool projects which use this library: +- [Filament](https://github.com/google/filament): Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be as small as possible and as efficient as possible on Android. +- [Hermes JS Engine](https://github.com/facebook/hermes): Hermes is a JavaScript engine optimized for fast start-up of React Native apps on Android. It features ahead-of-time static optimization and compact bytecode. +- [Open Asset Import Library](https://github.com/assimp/assimp): A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data. +- [PowerToys](https://github.com/microsoft/PowerToys): Set of utilities for power users to tune and streamline their Windows 10 experience for greater productivity. +- [The Ring Programming Language](https://ring-lang.github.io): Innovative and practical general-purpose multi-paradigm language. +- [The V Programming Language](https://github.com/vlang/v): Simple, fast, safe, compiled. For developing maintainable software. +- [TIC-80](https://github.com/nesbox/TIC-80): TIC-80 is a FREE and OPEN SOURCE fantasy computer for making, playing and sharing tiny games. +- [Urho3D](https://github.com/urho3d/Urho3D): Urho3D is a free lightweight, cross-platform 2D and 3D game engine implemented in C++ and released under the MIT license. Greatly inspired by OGRE and Horde3D. +- [Vcpkg](https://github.com/microsoft/vcpkg): Vcpkg helps you manage C and C++ libraries on Windows, Linux and MacOS. +- [and more...](https://grep.app/search?q=kuba--/zip) diff --git a/contrib/zip/src/miniz.h b/contrib/zip/src/miniz.h index 7570ae929..0a5560b24 100644 --- a/contrib/zip/src/miniz.h +++ b/contrib/zip/src/miniz.h @@ -400,7 +400,7 @@ typedef enum { #ifndef MINIZ_NO_ZLIB_APIS // Heap allocation callbacks. -// Note that mz_alloc_func parameter types purpsosely differ from zlib's: +// Note that mz_alloc_func parameter types purposely differ from zlib's: // items/size is size_t, not unsigned long. typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); typedef void (*mz_free_func)(void *opaque, void *address); @@ -2194,7 +2194,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, } else tree_cur = pTable->m_tree[-tree_cur - 1]; } - tree_cur -= ((rev_code >>= 1) & 1); + rev_code >>= 1; + tree_cur -= (rev_code & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; } if (r->m_type == 2) { @@ -3970,6 +3971,7 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, #ifdef _MSC_VER #pragma warning(push) +#pragma warning(disable : 4121 4127 4244) #pragma warning(disable : 4204) // nonstandard extension used : non-constant // aggregate initializer (also supported by GNU // C and C99, so no big deal) @@ -4098,10 +4100,6 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, pLen_out, 6, MZ_FALSE); } -#ifdef _MSC_VER -#pragma warning(pop) -#endif - // ------------------- .ZIP archive reading #ifndef MINIZ_NO_ARCHIVE_APIS @@ -4112,18 +4110,39 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, #include #include -#if defined(_MSC_VER) +#if defined(_MSC_VER) || defined(__MINGW32__) + +#include + +static wchar_t *str2wstr(const char *str) { + int len = (int) strlen(str) + 1; + wchar_t *wstr = malloc(len * sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, str, len * sizeof(char), wstr, len); + return wstr; +} + static FILE *mz_fopen(const char *pFilename, const char *pMode) { - FILE *pFile = NULL; - fopen_s(&pFile, pFilename, pMode); + wchar_t *wFilename = str2wstr(pFilename); + wchar_t *wMode = str2wstr(pMode); + FILE *pFile = _wfopen(wFilename, wMode); + + free(wFilename); + free(wMode); + return pFile; } + static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { - FILE *pFile = NULL; - if (freopen_s(&pFile, pPath, pMode, pStream)) - return NULL; + wchar_t *wPath = str2wstr(pPath); + wchar_t *wMode = str2wstr(pMode); + FILE *pFile = _wfreopen(wPath, wMode, pStream); + + free(wPath); + free(wMode); + return pFile; } + #ifndef MINIZ_NO_TIME #include #endif @@ -4144,7 +4163,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { #include #endif #define MZ_FILE FILE -#define MZ_FOPEN(f, m) fopen(f, m) +#define MZ_FOPEN(f, m) mz_fopen #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite @@ -4153,7 +4172,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { #define MZ_FILE_STAT_STRUCT _stat #define MZ_FILE_STAT _stat #define MZ_FFLUSH fflush -#define MZ_FREOPEN(f, m, s) freopen(f, m, s) +#define MZ_FREOPEN(f, m, s) mz_freopen #define MZ_DELETE_FILE remove #elif defined(__TINYC__) #ifndef MINIZ_NO_TIME @@ -5361,13 +5380,9 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, } else { // Temporarily allocate a read buffer. read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); -#if defined(_MSC_VER) && !defined(__clang__) - if (((0, sizeof(size_t) == sizeof(mz_uint32))) && - (read_buf_size > 0x7FFFFFFF)) -#else if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) -#endif return MZ_FALSE; + if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) return MZ_FALSE; @@ -5454,11 +5469,7 @@ void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size; -#if defined(_MSC_VER) && !defined(__clang__) - if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) -#else if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) -#endif return NULL; if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) @@ -5560,14 +5571,10 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) { // The file is stored or the caller has requested the compressed data. if (pZip->m_pState->m_pMem) { -#if defined (_MSC_VER) && !defined(__clang__) - if (((0, sizeof(size_t) == sizeof(mz_uint32))) && - (file_stat.m_comp_size > 0xFFFFFFFF)) -#else if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF)) -#endif return MZ_FALSE; + if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size) status = TINFL_STATUS_FAILED; @@ -6085,7 +6092,7 @@ mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) { if (!pZip->m_file_offset_alignment) return 0; n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); - return (mz_uint)(pZip->m_file_offset_alignment - n) & + return (pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1); } @@ -6289,7 +6296,10 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, mz_uint32 ext_attributes) { mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; mz_uint16 method = 0, dos_time = 0, dos_date = 0; +#ifndef MINIZ_NO_TIME time_t file_modified_time; +#endif + mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0, comp_size = 0; size_t archive_name_size; @@ -6326,10 +6336,12 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, comment_size + archive_name_size) > 0xFFFFFFFF)) return MZ_FALSE; +#ifndef MINIZ_NO_TIME memset(&file_modified_time, 0, sizeof(file_modified_time)); if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time)) return MZ_FALSE; mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date); +#endif pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); if (!pSrc_file) @@ -6814,6 +6826,10 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, return p; } +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #endif // #ifndef MINIZ_NO_STDIO #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS diff --git a/contrib/zip/src/zip.c b/contrib/zip/src/zip.c index 83e8e2a41..29af2ec99 100644 --- a/contrib/zip/src/zip.c +++ b/contrib/zip/src/zip.c @@ -18,11 +18,6 @@ /* Win32, DOS, MSVC, MSVS */ #include -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4706) -#endif // _MSC_VER - #define MKDIR(DIRNAME) _mkdir(DIRNAME) #define STRCLONE(STR) ((STR) ? _strdup(STR) : NULL) #define HAS_DEVICE(P) \ @@ -32,17 +27,29 @@ #else -#include // needed for symlink() on BSD -int symlink(const char *target, const char *linkpath); // needed on Linux +#include // needed for symlink() #define MKDIR(DIRNAME) mkdir(DIRNAME, 0755) #define STRCLONE(STR) ((STR) ? strdup(STR) : NULL) #endif +#ifdef __MINGW32__ +#include +#include +#endif + #include "miniz.h" #include "zip.h" +#ifdef _MSC_VER +#include +#pragma warning(disable : 4706 4244 4028) + +#define ftruncate(fd, sz) (-(_chsize_s((fd), (sz)) != 0)) +#define fileno _fileno +#endif + #ifndef HAS_DEVICE #define HAS_DEVICE(P) 0 #endif @@ -63,7 +70,84 @@ int symlink(const char *target, const char *linkpath); // needed on Linux } \ } while (0) -static const char *base_name(const char *name) { +struct zip_entry_t { + int index; + char *name; + mz_uint64 uncomp_size; + mz_uint64 comp_size; + mz_uint32 uncomp_crc32; + mz_uint64 offset; + mz_uint8 header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; + mz_uint64 header_offset; + mz_uint16 method; + mz_zip_writer_add_state state; + tdefl_compressor comp; + mz_uint32 external_attr; + time_t m_time; +}; + +struct zip_t { + mz_zip_archive archive; + mz_uint level; + struct zip_entry_t entry; +}; + +enum zip_modify_t { + MZ_KEEP = 0, + MZ_DELETE = 1, + MZ_MOVE = 2, +}; + +struct zip_entry_mark_t { + int file_index; + enum zip_modify_t type; + mz_uint64 m_local_header_ofs; + mz_uint64 lf_length; +}; + +static const char *const zip_errlist[30] = { + NULL, + "not initialized\0", + "invalid entry name\0", + "entry not found\0", + "invalid zip mode\0", + "invalid compression level\0", + "no zip 64 support\0", + "memset error\0", + "cannot write data to entry\0", + "cannot initialize tdefl compressor\0", + "invalid index\0", + "header not found\0", + "cannot flush tdefl buffer\0", + "cannot write entry header\0", + "cannot create entry header\0", + "cannot write to central dir\0", + "cannot open file\0", + "invalid entry type\0", + "extracting data using no memory allocation\0", + "file not found\0", + "no permission\0", + "out of memory\0", + "invalid zip archive name\0", + "make dir error\0" + "symlink error\0" + "close archive error\0" + "capacity size too small\0", + "fseek error\0", + "fread error\0", + "fwrite error\0", +}; + +const char *zip_strerror(int errnum) { + errnum = -errnum; + if (errnum <= 0 || errnum >= 30) { + return NULL; + } + + return zip_errlist[errnum]; +} + +static const char *zip_basename(const char *name) { char const *p; char const *base = name += FILESYSTEM_PREFIX_LEN(name); int all_slashes = 1; @@ -82,7 +166,7 @@ static const char *base_name(const char *name) { return base; } -static int mkpath(char *path) { +static int zip_mkpath(char *path) { char *p; char npath[MAX_PATH + 1]; int len = 0; @@ -107,7 +191,7 @@ static int mkpath(char *path) { if (MKDIR(npath) == -1) { if (errno != EEXIST) { - return -1; + return ZIP_EMKDIR; } } } @@ -117,7 +201,7 @@ static int mkpath(char *path) { return 0; } -static char *strrpl(const char *str, size_t n, char oldchar, char newchar) { +static char *zip_strrpl(const char *str, size_t n, char oldchar, char newchar) { char c; size_t i; char *rpl = (char *)calloc((1 + n), sizeof(char)); @@ -136,27 +220,562 @@ static char *strrpl(const char *str, size_t n, char oldchar, char newchar) { return begin; } -struct zip_entry_t { - int index; - char *name; - mz_uint64 uncomp_size; - mz_uint64 comp_size; - mz_uint32 uncomp_crc32; - mz_uint64 offset; - mz_uint8 header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; - mz_uint64 header_offset; - mz_uint16 method; - mz_zip_writer_add_state state; - tdefl_compressor comp; - mz_uint32 external_attr; - time_t m_time; -}; +static char *zip_name_normalize(char *name, char *const nname, size_t len) { + size_t offn = 0; + size_t offnn = 0, ncpy = 0; -struct zip_t { - mz_zip_archive archive; - mz_uint level; - struct zip_entry_t entry; -}; + if (name == NULL || nname == NULL || len <= 0) { + return NULL; + } + // skip trailing '/' + while (ISSLASH(*name)) + name++; + + for (; offn < len; offn++) { + if (ISSLASH(name[offn])) { + if (ncpy > 0 && strcmp(&nname[offnn], ".\0") && + strcmp(&nname[offnn], "..\0")) { + offnn += ncpy; + nname[offnn++] = name[offn]; // append '/' + } + ncpy = 0; + } else { + nname[offnn + ncpy] = name[offn]; + ncpy++; + } + } + + // at the end, extra check what we've already copied + if (ncpy == 0 || !strcmp(&nname[offnn], ".\0") || + !strcmp(&nname[offnn], "..\0")) { + nname[offnn] = 0; + } + return nname; +} + +static mz_bool zip_name_match(const char *name1, const char *name2) { + int len2 = (int) strlen(name2); + char *nname2 = zip_strrpl(name2, len2, '\\', '/'); + if (!nname2) { + return MZ_FALSE; + } + + mz_bool res = (strcmp(name1, nname2) == 0) ? MZ_TRUE : MZ_FALSE; + CLEANUP(nname2); + return res; +} + +static int zip_archive_truncate(mz_zip_archive *pzip) { + mz_zip_internal_state *pState = pzip->m_pState; + mz_uint64 file_size = pzip->m_archive_size; + if ((pzip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) { + return 0; + } + if (pzip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED) { + if (pState->m_pFile) { + int fd = fileno(pState->m_pFile); + return ftruncate(fd, file_size); + } + } + return 0; +} + +static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir, + int (*on_extract)(const char *filename, + void *arg), + void *arg) { + int err = 0; + mz_uint i, n; + char path[MAX_PATH + 1]; + char symlink_to[MAX_PATH + 1]; + mz_zip_archive_file_stat info; + size_t dirlen = 0; + mz_uint32 xattr = 0; + + memset(path, 0, sizeof(path)); + memset(symlink_to, 0, sizeof(symlink_to)); + + dirlen = strlen(dir); + if (dirlen + 1 > MAX_PATH) { + return ZIP_EINVENTNAME; + } + + memset((void *)&info, 0, sizeof(mz_zip_archive_file_stat)); + +#if defined(_MSC_VER) + strcpy_s(path, MAX_PATH, dir); +#else + strcpy(path, dir); +#endif + + if (!ISSLASH(path[dirlen - 1])) { +#if defined(_WIN32) || defined(__WIN32__) + path[dirlen] = '\\'; +#else + path[dirlen] = '/'; +#endif + ++dirlen; + } + + // Get and print information about each file in the archive. + n = mz_zip_reader_get_num_files(zip_archive); + for (i = 0; i < n; ++i) { + if (!mz_zip_reader_file_stat(zip_archive, i, &info)) { + // Cannot get information about zip archive; + err = ZIP_ENOENT; + goto out; + } + + if (!zip_name_normalize(info.m_filename, info.m_filename, + strlen(info.m_filename))) { + // Cannot normalize file name; + err = ZIP_EINVENTNAME; + goto out; + } +#if defined(_MSC_VER) + strncpy_s(&path[dirlen], MAX_PATH - dirlen, info.m_filename, + MAX_PATH - dirlen); +#else + strncpy(&path[dirlen], info.m_filename, MAX_PATH - dirlen); +#endif + err = zip_mkpath(path); + if (err < 0) { + // Cannot make a path + goto out; + } + + if ((((info.m_version_made_by >> 8) == 3) || + ((info.m_version_made_by >> 8) == + 19)) // if zip is produced on Unix or macOS (3 and 19 from + // section 4.4.2.2 of zip standard) + && info.m_external_attr & + (0x20 << 24)) { // and has sym link attribute (0x80 is file, 0x40 + // is directory) +#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ + defined(__MINGW32__) +#else + if (info.m_uncomp_size > MAX_PATH || + !mz_zip_reader_extract_to_mem_no_alloc(zip_archive, i, symlink_to, + MAX_PATH, 0, NULL, 0)) { + err = ZIP_EMEMNOALLOC; + goto out; + } + symlink_to[info.m_uncomp_size] = '\0'; + if (symlink(symlink_to, path) != 0) { + err = ZIP_ESYMLINK; + goto out; + } +#endif + } else { + if (!mz_zip_reader_is_file_a_directory(zip_archive, i)) { + if (!mz_zip_reader_extract_to_file(zip_archive, i, path, 0)) { + // Cannot extract zip archive to file + err = ZIP_ENOFILE; + goto out; + } + } + +#if defined(_MSC_VER) + (void)xattr; // unused +#else + xattr = (info.m_external_attr >> 16) & 0xFFFF; + if (xattr > 0) { + if (chmod(path, (mode_t)xattr) < 0) { + err = ZIP_ENOPERM; + goto out; + } + } +#endif + } + + if (on_extract) { + if (on_extract(path, arg) < 0) { + goto out; + } + } + } + +out: + // Close the archive, freeing any resources it was using + if (!mz_zip_reader_end(zip_archive)) { + // Cannot end zip reader + err = ZIP_ECLSZIP; + } + return err; +} + +static inline void zip_archive_finalize(mz_zip_archive *pzip) { + mz_zip_writer_finalize_archive(pzip); + zip_archive_truncate(pzip); +} + +static int zip_entry_mark(struct zip_t *zip, + struct zip_entry_mark_t *entry_mark, int n, + char *const entries[], const size_t len) { + int err = 0; + if (!zip || !entry_mark || !entries) { + return ZIP_ENOINIT; + } + + mz_zip_archive_file_stat file_stat; + mz_uint64 d_pos = (mz_uint64) ~0; + for (int i = 0; i < n; ++i) { + err = zip_entry_openbyindex(zip, i); + if (err) { + return err; + } + + mz_bool name_matches = MZ_FALSE; + for (int j = 0; j < (const int)len; ++j) { + if (zip_name_match(zip->entry.name, entries[j])) { + name_matches = MZ_TRUE; + break; + } + } + if (name_matches) { + entry_mark[i].type = MZ_DELETE; + } else { + entry_mark[i].type = MZ_KEEP; + } + + if (!mz_zip_reader_file_stat(&zip->archive, i, &file_stat)) { + return ZIP_ENOENT; + } + + zip_entry_close(zip); + + entry_mark[i].m_local_header_ofs = file_stat.m_local_header_ofs; + entry_mark[i].file_index = -1; + entry_mark[i].lf_length = 0; + if ((entry_mark[i].type) == MZ_DELETE && + (d_pos > entry_mark[i].m_local_header_ofs)) { + d_pos = entry_mark[i].m_local_header_ofs; + } + } + for (int i = 0; i < n; ++i) { + if ((entry_mark[i].m_local_header_ofs > d_pos) && + (entry_mark[i].type != MZ_DELETE)) { + entry_mark[i].type = MZ_MOVE; + } + } + return err; +} + +static int zip_index_next(mz_uint64 *local_header_ofs_array, int cur_index) { + int new_index = 0; + for (int i = cur_index - 1; i >= 0; --i) { + if (local_header_ofs_array[cur_index] > local_header_ofs_array[i]) { + new_index = i + 1; + return new_index; + } + } + return new_index; +} + +static int zip_sort(mz_uint64 *local_header_ofs_array, int cur_index) { + int nxt_index = zip_index_next(local_header_ofs_array, cur_index); + + if (nxt_index != cur_index) { + mz_uint64 temp = local_header_ofs_array[cur_index]; + for (int i = cur_index; i > nxt_index; i--) { + local_header_ofs_array[i] = local_header_ofs_array[i - 1]; + } + local_header_ofs_array[nxt_index] = temp; + } + return nxt_index; +} + +static int zip_index_update(struct zip_entry_mark_t *entry_mark, int last_index, + int nxt_index) { + for (int j = 0; j < last_index; j++) { + if (entry_mark[j].file_index >= nxt_index) { + entry_mark[j].file_index += 1; + } + } + entry_mark[nxt_index].file_index = last_index; + return 0; +} + +static int zip_entry_finalize(struct zip_t *zip, + struct zip_entry_mark_t *entry_mark, + const int n) { + + mz_uint64 *local_header_ofs_array = (mz_uint64 *)calloc(n, sizeof(mz_uint64)); + if (!local_header_ofs_array) { + return ZIP_EOOMEM; + } + + for (int i = 0; i < n; ++i) { + local_header_ofs_array[i] = entry_mark[i].m_local_header_ofs; + int index = zip_sort(local_header_ofs_array, i); + + if (index != i) { + zip_index_update(entry_mark, i, index); + } + entry_mark[i].file_index = index; + } + + mz_uint64 *length = (mz_uint64 *)calloc(n, sizeof(mz_uint64)); + if (!length) { + CLEANUP(local_header_ofs_array); + return ZIP_EOOMEM; + } + for (int i = 0; i < n - 1; i++) { + length[i] = local_header_ofs_array[i + 1] - local_header_ofs_array[i]; + } + length[n - 1] = zip->archive.m_archive_size - local_header_ofs_array[n - 1]; + + for (int i = 0; i < n; i++) { + entry_mark[i].lf_length = length[entry_mark[i].file_index]; + } + + CLEANUP(length); + CLEANUP(local_header_ofs_array); + return 0; +} + +static int zip_entry_set(struct zip_t *zip, struct zip_entry_mark_t *entry_mark, + int n, char *const entries[], const size_t len) { + int err = 0; + + if ((err = zip_entry_mark(zip, entry_mark, n, entries, len)) < 0) { + return err; + } + if ((err = zip_entry_finalize(zip, entry_mark, n)) < 0) { + return err; + } + return 0; +} + +static mz_int64 zip_file_move(MZ_FILE *m_pFile, const mz_uint64 to, + const mz_uint64 from, const mz_uint64 length, + mz_uint8 *move_buf, + const mz_int64 capacity_size) { + if ((mz_int64)length > capacity_size) { + return ZIP_ECAPSIZE; + } + if (MZ_FSEEK64(m_pFile, from, SEEK_SET)) { + MZ_FCLOSE(m_pFile); + return ZIP_EFSEEK; + } + + if (fread(move_buf, 1, length, m_pFile) != length) { + MZ_FCLOSE(m_pFile); + return ZIP_EFREAD; + } + if (MZ_FSEEK64(m_pFile, to, SEEK_SET)) { + MZ_FCLOSE(m_pFile); + return ZIP_EFSEEK; + } + if (fwrite(move_buf, 1, length, m_pFile) != length) { + MZ_FCLOSE(m_pFile); + return ZIP_EFWRITE; + } + return (mz_int64)length; +} + +static mz_int64 zip_files_move(MZ_FILE *m_pFile, mz_uint64 writen_num, + mz_uint64 read_num, mz_uint64 length) { + int n = 0; + const mz_int64 page_size = 1 << 12; // 4K + mz_uint8 *move_buf = (mz_uint8 *)calloc(1, page_size); + if (move_buf == NULL) { + return ZIP_EOOMEM; + } + + mz_int64 moved_length = 0; + mz_int64 move_count = 0; + while ((mz_int64)length > 0) { + move_count = ((mz_int64)length >= page_size) ? page_size : (mz_int64)length; + n = (int) zip_file_move(m_pFile, writen_num, read_num, move_count, move_buf, + page_size); + if (n < 0) { + moved_length = n; + goto cleanup; + } + + if (n != move_count) { + goto cleanup; + } + + writen_num += move_count; + read_num += move_count; + length -= move_count; + moved_length += move_count; + } + +cleanup: + CLEANUP(move_buf); + return moved_length; +} + +static int zip_central_dir_move(mz_zip_internal_state *pState, int begin, + int end, int entry_num) { + if (begin == entry_num) { + return 0; + } + + mz_uint64 l_size = 0; + mz_uint64 r_size = 0; + mz_uint64 d_size = 0; + mz_uint8 *next = NULL; + mz_uint8 *deleted = &MZ_ZIP_ARRAY_ELEMENT( + &pState->m_central_dir, mz_uint8, + MZ_ZIP_ARRAY_ELEMENT(&pState->m_central_dir_offsets, mz_uint32, begin)); + l_size = (mz_uint32)(deleted - (mz_uint8 *)(pState->m_central_dir.m_p)); + if (end == entry_num) { + r_size = 0; + } else { + next = &MZ_ZIP_ARRAY_ELEMENT( + &pState->m_central_dir, mz_uint8, + MZ_ZIP_ARRAY_ELEMENT(&pState->m_central_dir_offsets, mz_uint32, end)); + r_size = pState->m_central_dir.m_size - + (mz_uint32)(next - (mz_uint8 *)(pState->m_central_dir.m_p)); + d_size = next - deleted; + } + + if (l_size == 0) { + memmove(pState->m_central_dir.m_p, next, r_size); + pState->m_central_dir.m_p = MZ_REALLOC(pState->m_central_dir.m_p, r_size); + for (int i = end; i < entry_num; i++) { + MZ_ZIP_ARRAY_ELEMENT(&pState->m_central_dir_offsets, mz_uint64, i) -= + d_size; + } + } + + if (l_size * r_size != 0) { + memmove(deleted, next, r_size); + for (int i = end; i < entry_num; i++) { + MZ_ZIP_ARRAY_ELEMENT(&pState->m_central_dir_offsets, mz_uint64, i) -= + d_size; + } + } + + pState->m_central_dir.m_size = l_size + r_size; + return 0; +} + +static int zip_central_dir_delete(mz_zip_internal_state *pState, + int *deleted_entry_index_array, + int entry_num) { + int i = 0; + int begin = 0; + int end = 0; + int d_num = 0; + while (i < entry_num) { + while ((!deleted_entry_index_array[i]) && (i < entry_num)) { + i++; + } + begin = i; + + while ((deleted_entry_index_array[i]) && (i < entry_num)) { + i++; + } + end = i; + zip_central_dir_move(pState, begin, end, entry_num); + } + + i = 0; + while (i < entry_num) { + while ((!deleted_entry_index_array[i]) && (i < entry_num)) { + i++; + } + begin = i; + if (begin == entry_num) { + break; + } + while ((deleted_entry_index_array[i]) && (i < entry_num)) { + i++; + } + end = i; + int k = 0; + for (int j = end; j < entry_num; j++) { + MZ_ZIP_ARRAY_ELEMENT(&pState->m_central_dir_offsets, mz_uint32, + begin + k) = + (mz_uint32)MZ_ZIP_ARRAY_ELEMENT(&pState->m_central_dir_offsets, + mz_uint32, j); + k++; + } + d_num += end - begin; + } + + pState->m_central_dir_offsets.m_size = + sizeof(mz_uint32) * (entry_num - d_num); + return 0; +} + +static int zip_entries_delete_mark(struct zip_t *zip, + struct zip_entry_mark_t *entry_mark, + int entry_num) { + mz_uint64 writen_num = 0; + mz_uint64 read_num = 0; + mz_uint64 deleted_length = 0; + mz_uint64 move_length = 0; + int i = 0; + int deleted_entry_num = 0; + int n = 0; + + mz_bool *deleted_entry_flag_array = + (mz_bool *)calloc(entry_num, sizeof(mz_bool)); + if (deleted_entry_flag_array == NULL) { + return ZIP_EOOMEM; + } + + mz_zip_internal_state *pState = zip->archive.m_pState; + zip->archive.m_zip_mode = MZ_ZIP_MODE_WRITING; + + if (MZ_FSEEK64(pState->m_pFile, 0, SEEK_SET)) { + CLEANUP(deleted_entry_flag_array); + return ZIP_ENOENT; + } + + while (i < entry_num) { + while ((entry_mark[i].type == MZ_KEEP) && (i < entry_num)) { + writen_num += entry_mark[i].lf_length; + read_num = writen_num; + i++; + } + + while ((entry_mark[i].type == MZ_DELETE) && (i < entry_num)) { + deleted_entry_flag_array[i] = MZ_TRUE; + read_num += entry_mark[i].lf_length; + deleted_length += entry_mark[i].lf_length; + i++; + deleted_entry_num++; + } + + while ((entry_mark[i].type == MZ_MOVE) && (i < entry_num)) { + move_length += entry_mark[i].lf_length; + mz_uint8 *p = &MZ_ZIP_ARRAY_ELEMENT( + &pState->m_central_dir, mz_uint8, + MZ_ZIP_ARRAY_ELEMENT(&pState->m_central_dir_offsets, mz_uint32, i)); + if (!p) { + CLEANUP(deleted_entry_flag_array); + return ZIP_ENOENT; + } + mz_uint32 offset = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); + offset -= (mz_uint32)deleted_length; + MZ_WRITE_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS, offset); + i++; + } + + n = (int) zip_files_move(pState->m_pFile, writen_num, read_num, move_length); + if (n != (mz_int64)move_length) { + CLEANUP(deleted_entry_flag_array); + return n; + } + writen_num += move_length; + read_num += move_length; + } + + zip->archive.m_archive_size -= deleted_length; + zip->archive.m_total_files = entry_num - deleted_entry_num; + + zip_central_dir_delete(pState, deleted_entry_flag_array, entry_num); + CLEANUP(deleted_entry_flag_array); + + return deleted_entry_num; +} struct zip_t *zip_open(const char *zipname, int level, char mode) { struct zip_t *zip = NULL; @@ -189,6 +808,7 @@ struct zip_t *zip_open(const char *zipname, int level, char mode) { case 'r': case 'a': + case 'd': if (!mz_zip_reader_init_file( &(zip->archive), zipname, zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) { @@ -196,7 +816,7 @@ struct zip_t *zip_open(const char *zipname, int level, char mode) { // zip_archive reader goto cleanup; } - if (mode == 'a' && + if ((mode == 'a' || mode == 'd') && !mz_zip_writer_init_from_reader(&(zip->archive), zipname)) { mz_zip_reader_end(&(zip->archive)); goto cleanup; @@ -219,7 +839,7 @@ void zip_close(struct zip_t *zip) { // Always finalize, even if adding failed for some reason, so we have a // valid central directory. mz_zip_writer_finalize_archive(&(zip->archive)); - + zip_archive_truncate(&(zip->archive)); mz_zip_writer_end(&(zip->archive)); mz_zip_reader_end(&(zip->archive)); @@ -228,14 +848,9 @@ void zip_close(struct zip_t *zip) { } int zip_is64(struct zip_t *zip) { - if (!zip) { - // zip_t handler is not initialized - return -1; - } - - if (!zip->archive.m_pState) { - // zip state is not initialized - return -1; + if (!zip || !zip->archive.m_pState) { + // zip_t handler or zip state is not initialized + return ZIP_ENOINIT; } return (int)zip->archive.m_pState->m_zip64; @@ -246,14 +861,19 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { mz_zip_archive *pzip = NULL; mz_uint num_alignment_padding_bytes, level; mz_zip_archive_file_stat stats; + int err = 0; - if (!zip || !entryname) { - return -1; + if (!zip) { + return ZIP_ENOINIT; + } + + if (!entryname) { + return ZIP_EINVENTNAME; } entrylen = strlen(entryname); - if (entrylen < 1) { - return -1; + if (entrylen == 0) { + return ZIP_EINVENTNAME; } /* @@ -267,10 +887,13 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { and UNIX file systems etc. If input came from standard input, there is no file name field. */ - zip->entry.name = strrpl(entryname, entrylen, '\\', '/'); + if (zip->entry.name) { + CLEANUP(zip->entry.name); + } + zip->entry.name = zip_strrpl(entryname, entrylen, '\\', '/'); if (!zip->entry.name) { // Cannot parse zip entry name - return -1; + return ZIP_EINVENTNAME; } pzip = &(zip->archive); @@ -278,10 +901,12 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { zip->entry.index = mz_zip_reader_locate_file(pzip, zip->entry.name, NULL, 0); if (zip->entry.index < 0) { + err = ZIP_ENOENT; goto cleanup; } if (!mz_zip_reader_file_stat(pzip, (mz_uint)zip->entry.index, &stats)) { + err = ZIP_ENOENT; goto cleanup; } @@ -292,7 +917,9 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { zip->entry.header_offset = stats.m_local_header_ofs; zip->entry.method = stats.m_method; zip->entry.external_attr = stats.m_external_attr; +#ifndef MINIZ_NO_TIME zip->entry.m_time = stats.m_time; +#endif return 0; } @@ -318,11 +945,13 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { mz_zip_writer_compute_padding_needed_for_file_alignment(pzip); if (!pzip->m_pState || (pzip->m_zip_mode != MZ_ZIP_MODE_WRITING)) { - // Wrong zip mode + // Invalid zip mode + err = ZIP_EINVMODE; goto cleanup; } if (zip->level & MZ_ZIP_FLAG_COMPRESSED_DATA) { - // Wrong zip compression level + // Invalid zip compression level + err = ZIP_EINVLVL; goto cleanup; } // no zip64 support yet @@ -331,12 +960,14 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + entrylen) > 0xFFFFFFFF)) { // No zip64 support yet + err = ZIP_ENOSUP64; goto cleanup; } if (!mz_zip_writer_write_zeros(pzip, zip->entry.offset, num_alignment_padding_bytes + sizeof(zip->entry.header))) { // Cannot memset zip entry header + err = ZIP_EMEMSET; goto cleanup; } @@ -350,6 +981,7 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, zip->entry.name, entrylen) != entrylen) { // Cannot write data to zip entry + err = ZIP_EWRTENT; goto cleanup; } @@ -366,6 +998,7 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { (int)level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) { // Cannot initialize the zip compressor + err = ZIP_ETDEFLINIT; goto cleanup; } } @@ -376,7 +1009,7 @@ int zip_entry_open(struct zip_t *zip, const char *entryname) { cleanup: CLEANUP(zip->entry.name); - return -1; + return err; } int zip_entry_openbyindex(struct zip_t *zip, int index) { @@ -388,28 +1021,26 @@ int zip_entry_openbyindex(struct zip_t *zip, int index) { if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } pZip = &(zip->archive); if (pZip->m_zip_mode != MZ_ZIP_MODE_READING) { // open by index requires readonly mode - return -1; + return ZIP_EINVMODE; } if (index < 0 || (mz_uint)index >= pZip->m_total_files) { // index out of range - return -1; + return ZIP_EINVIDX; } - if (!(pHeader = &MZ_ZIP_ARRAY_ELEMENT( &pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, index)))) { // cannot find header in central directory - return -1; + return ZIP_ENOHDR; } - namelen = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; @@ -424,14 +1055,17 @@ int zip_entry_openbyindex(struct zip_t *zip, int index) { and UNIX file systems etc. If input came from standard input, there is no file name field. */ - zip->entry.name = strrpl(pFilename, namelen, '\\', '/'); + if (zip->entry.name) { + CLEANUP(zip->entry.name); + } + zip->entry.name = zip_strrpl(pFilename, namelen, '\\', '/'); if (!zip->entry.name) { // local entry name is NULL - return -1; + return ZIP_EINVENTNAME; } if (!mz_zip_reader_file_stat(pZip, (mz_uint)index, &stats)) { - return -1; + return ZIP_ENOENT; } zip->entry.index = index; @@ -442,7 +1076,9 @@ int zip_entry_openbyindex(struct zip_t *zip, int index) { zip->entry.header_offset = stats.m_local_header_ofs; zip->entry.method = stats.m_method; zip->entry.external_attr = stats.m_external_attr; +#ifndef MINIZ_NO_TIME zip->entry.m_time = stats.m_time; +#endif return 0; } @@ -452,17 +1088,17 @@ int zip_entry_close(struct zip_t *zip) { mz_uint level; tdefl_status done; mz_uint16 entrylen; - mz_uint16 dos_time, dos_date; - int status = -1; + mz_uint16 dos_time = 0, dos_date = 0; + int err = 0; if (!zip) { // zip_t handler is not initialized + err = ZIP_ENOINIT; goto cleanup; } pzip = &(zip->archive); if (pzip->m_zip_mode == MZ_ZIP_MODE_READING) { - status = 0; goto cleanup; } @@ -471,6 +1107,7 @@ int zip_entry_close(struct zip_t *zip) { done = tdefl_compress_buffer(&(zip->entry.comp), "", 0, TDEFL_FINISH); if (done != TDEFL_STATUS_DONE && done != TDEFL_STATUS_OKAY) { // Cannot flush compressed buffer + err = ZIP_ETDEFLBUF; goto cleanup; } zip->entry.comp_size = zip->entry.state.m_comp_size; @@ -479,18 +1116,22 @@ int zip_entry_close(struct zip_t *zip) { } entrylen = (mz_uint16)strlen(zip->entry.name); - // no zip64 support yet if ((zip->entry.comp_size > 0xFFFFFFFF) || (zip->entry.offset > 0xFFFFFFFF)) { // No zip64 support, yet + err = ZIP_ENOSUP64; goto cleanup; } +#ifndef MINIZ_NO_TIME mz_zip_time_t_to_dos_time(zip->entry.m_time, &dos_time, &dos_date); +#endif + if (!mz_zip_writer_create_local_dir_header( pzip, zip->entry.header, entrylen, 0, zip->entry.uncomp_size, zip->entry.comp_size, zip->entry.uncomp_crc32, zip->entry.method, 0, dos_time, dos_date)) { // Cannot create zip entry header + err = ZIP_ECRTHDR; goto cleanup; } @@ -498,6 +1139,7 @@ int zip_entry_close(struct zip_t *zip) { zip->entry.header, sizeof(zip->entry.header)) != sizeof(zip->entry.header)) { // Cannot write zip entry header + err = ZIP_EWRTHDR; goto cleanup; } @@ -507,19 +1149,19 @@ int zip_entry_close(struct zip_t *zip) { zip->entry.method, 0, dos_time, dos_date, zip->entry.header_offset, zip->entry.external_attr)) { // Cannot write to zip central dir + err = ZIP_EWRTDIR; goto cleanup; } pzip->m_total_files++; pzip->m_archive_size = zip->entry.offset; - status = 0; cleanup: if (zip) { zip->entry.m_time = 0; CLEANUP(zip->entry.name); } - return status; + return err; } const char *zip_entry_name(struct zip_t *zip) { @@ -534,7 +1176,7 @@ const char *zip_entry_name(struct zip_t *zip) { int zip_entry_index(struct zip_t *zip) { if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } return zip->entry.index; @@ -543,12 +1185,12 @@ int zip_entry_index(struct zip_t *zip) { int zip_entry_isdir(struct zip_t *zip) { if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } if (zip->entry.index < 0) { // zip entry is not opened - return -1; + return ZIP_EINVIDX; } return (int)mz_zip_reader_is_file_a_directory(&zip->archive, @@ -570,7 +1212,7 @@ int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) { if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } pzip = &(zip->archive); @@ -584,7 +1226,7 @@ int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) { if ((pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, buf, bufsize) != bufsize)) { // Cannot write buffer - return -1; + return ZIP_EWRTENT; } zip->entry.offset += bufsize; zip->entry.comp_size += bufsize; @@ -593,7 +1235,7 @@ int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) { TDEFL_NO_FLUSH); if (status != TDEFL_STATUS_DONE && status != TDEFL_STATUS_OKAY) { // Cannot compress buffer - return -1; + return ZIP_ETDEFLBUF; } } } @@ -602,7 +1244,7 @@ int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) { } int zip_entry_fwrite(struct zip_t *zip, const char *filename) { - int status = 0; + int err = 0; size_t n = 0; FILE *stream = NULL; mz_uint8 buf[MZ_ZIP_MAX_IO_BUF_SIZE]; @@ -610,14 +1252,14 @@ int zip_entry_fwrite(struct zip_t *zip, const char *filename) { if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } memset(buf, 0, MZ_ZIP_MAX_IO_BUF_SIZE); memset((void *)&file_stat, 0, sizeof(struct MZ_FILE_STAT_STRUCT)); if (MZ_FILE_STAT(filename, &file_stat) != 0) { // problem getting information - check errno - return -1; + return ZIP_ENOENT; } if ((file_stat.st_mode & 0200) == 0) { @@ -634,19 +1276,19 @@ int zip_entry_fwrite(struct zip_t *zip, const char *filename) { #endif { // Cannot open filename - return -1; + return ZIP_EOPNFILE; } while ((n = fread(buf, sizeof(mz_uint8), MZ_ZIP_MAX_IO_BUF_SIZE, stream)) > 0) { if (zip_entry_write(zip, buf, n) < 0) { - status = -1; + err = ZIP_EWRTENT; break; } } fclose(stream); - return status; + return err; } ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize) { @@ -656,19 +1298,19 @@ ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize) { if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } pzip = &(zip->archive); if (pzip->m_zip_mode != MZ_ZIP_MODE_READING || zip->entry.index < 0) { // the entry is not found or we do not have read access - return -1; + return ZIP_ENOENT; } idx = (mz_uint)zip->entry.index; if (mz_zip_reader_is_file_a_directory(pzip, idx)) { // the entry is a directory - return -1; + return ZIP_EINVENTTYPE; } *buf = mz_zip_reader_extract_to_heap(pzip, idx, &size, 0); @@ -683,18 +1325,18 @@ ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf, size_t bufsize) { if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } pzip = &(zip->archive); if (pzip->m_zip_mode != MZ_ZIP_MODE_READING || zip->entry.index < 0) { // the entry is not found or we do not have read access - return -1; + return ZIP_ENOENT; } if (!mz_zip_reader_extract_to_mem_no_alloc(pzip, (mz_uint)zip->entry.index, buf, bufsize, 0, NULL, 0)) { - return -1; + return ZIP_EMEMNOALLOC; } return (ssize_t)zip->entry.uncomp_size; @@ -703,45 +1345,43 @@ ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf, size_t bufsize) { int zip_entry_fread(struct zip_t *zip, const char *filename) { mz_zip_archive *pzip = NULL; mz_uint idx; -#if defined(_MSC_VER) -#else mz_uint32 xattr = 0; -#endif mz_zip_archive_file_stat info; if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } memset((void *)&info, 0, sizeof(mz_zip_archive_file_stat)); pzip = &(zip->archive); if (pzip->m_zip_mode != MZ_ZIP_MODE_READING || zip->entry.index < 0) { // the entry is not found or we do not have read access - return -1; + return ZIP_ENOENT; } idx = (mz_uint)zip->entry.index; if (mz_zip_reader_is_file_a_directory(pzip, idx)) { // the entry is a directory - return -1; + return ZIP_EINVENTTYPE; } if (!mz_zip_reader_extract_to_file(pzip, idx, filename, 0)) { - return -1; + return ZIP_ENOFILE; } #if defined(_MSC_VER) + (void)xattr; // unused #else if (!mz_zip_reader_file_stat(pzip, idx, &info)) { // Cannot get information about zip archive; - return -1; + return ZIP_ENOFILE; } xattr = (info.m_external_attr >> 16) & 0xFFFF; if (xattr > 0) { if (chmod(filename, (mode_t)xattr) < 0) { - return -1; + return ZIP_ENOPERM; } } #endif @@ -758,32 +1398,147 @@ int zip_entry_extract(struct zip_t *zip, if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } pzip = &(zip->archive); if (pzip->m_zip_mode != MZ_ZIP_MODE_READING || zip->entry.index < 0) { // the entry is not found or we do not have read access - return -1; + return ZIP_ENOENT; } idx = (mz_uint)zip->entry.index; return (mz_zip_reader_extract_to_callback(pzip, idx, on_extract, arg, 0)) ? 0 - : -1; + : ZIP_EINVIDX; } -int zip_total_entries(struct zip_t *zip) { +int zip_entries_total(struct zip_t *zip) { if (!zip) { // zip_t handler is not initialized - return -1; + return ZIP_ENOINIT; } return (int)zip->archive.m_total_files; } +int zip_entries_delete(struct zip_t *zip, char *const entries[], + const size_t len) { + int n = 0; + int err = 0; + struct zip_entry_mark_t *entry_mark = NULL; + + if (zip == NULL || (entries == NULL && len != 0)) { + return ZIP_ENOINIT; + } + + if (entries == NULL && len == 0) { + return 0; + } + + n = zip_entries_total(zip); + + entry_mark = + (struct zip_entry_mark_t *)calloc(n, sizeof(struct zip_entry_mark_t)); + if (!entry_mark) { + return ZIP_EOOMEM; + } + + zip->archive.m_zip_mode = MZ_ZIP_MODE_READING; + + err = zip_entry_set(zip, entry_mark, n, entries, len); + if (err < 0) { + CLEANUP(entry_mark); + return err; + } + + err = zip_entries_delete_mark(zip, entry_mark, n); + CLEANUP(entry_mark); + return err; +} + +int zip_stream_extract(const char *stream, size_t size, const char *dir, + int (*on_extract)(const char *filename, void *arg), + void *arg) { + mz_zip_archive zip_archive; + if (!stream || !dir) { + // Cannot parse zip archive stream + return ZIP_ENOINIT; + } + if (!memset(&zip_archive, 0, sizeof(mz_zip_archive))) { + // Cannot memset zip archive + return ZIP_EMEMSET; + } + if (!mz_zip_reader_init_mem(&zip_archive, stream, size, 0)) { + // Cannot initialize zip_archive reader + return ZIP_ENOINIT; + } + + return zip_archive_extract(&zip_archive, dir, on_extract, arg); +} + +struct zip_t *zip_stream_open(const char *stream, size_t size, int level, + char mode) { + struct zip_t *zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t)); + if (!zip) { + return NULL; + } + + if (level < 0) { + level = MZ_DEFAULT_LEVEL; + } + if ((level & 0xF) > MZ_UBER_COMPRESSION) { + // Wrong compression level + goto cleanup; + } + zip->level = (mz_uint)level; + + if ((stream != NULL) && (size > 0) && (mode == 'r')) { + if (!mz_zip_reader_init_mem(&(zip->archive), stream, size, 0)) { + goto cleanup; + } + } else if ((stream == NULL) && (size == 0) && (mode == 'w')) { + // Create a new archive. + if (!mz_zip_writer_init_heap(&(zip->archive), 0, 1024)) { + // Cannot initialize zip_archive writer + goto cleanup; + } + } else { + goto cleanup; + } + return zip; + +cleanup: + CLEANUP(zip); + return NULL; +} + +ssize_t zip_stream_copy(struct zip_t *zip, void **buf, ssize_t *bufsize) { + if (!zip) { + return ZIP_ENOINIT; + } + + zip_archive_finalize(&(zip->archive)); + + if (bufsize != NULL) { + *bufsize = zip->archive.m_archive_size; + } + *buf = calloc(sizeof(unsigned char), zip->archive.m_archive_size); + memcpy(*buf, zip->archive.m_pState->m_pMem, zip->archive.m_archive_size); + + return zip->archive.m_archive_size; +} + +void zip_stream_close(struct zip_t *zip) { + if (zip) { + mz_zip_writer_end(&(zip->archive)); + mz_zip_reader_end(&(zip->archive)); + CLEANUP(zip); + } +} + int zip_create(const char *zipname, const char *filenames[], size_t len) { - int status = 0; + int err = 0; size_t i; mz_zip_archive zip_archive; struct MZ_FILE_STAT_STRUCT file_stat; @@ -791,32 +1546,34 @@ int zip_create(const char *zipname, const char *filenames[], size_t len) { if (!zipname || strlen(zipname) < 1) { // zip_t archive name is empty or NULL - return -1; + return ZIP_EINVZIPNAME; } // Create a new archive. if (!memset(&(zip_archive), 0, sizeof(zip_archive))) { // Cannot memset zip archive - return -1; + return ZIP_EMEMSET; } if (!mz_zip_writer_init_file(&zip_archive, zipname, 0)) { // Cannot initialize zip_archive writer - return -1; + return ZIP_ENOINIT; } - memset((void *)&file_stat, 0, sizeof(struct MZ_FILE_STAT_STRUCT)); + if (!memset((void *)&file_stat, 0, sizeof(struct MZ_FILE_STAT_STRUCT))) { + return ZIP_EMEMSET; + } for (i = 0; i < len; ++i) { const char *name = filenames[i]; if (!name) { - status = -1; + err = ZIP_EINVENTNAME; break; } if (MZ_FILE_STAT(name, &file_stat) != 0) { // problem getting information - check errno - status = -1; + err = ZIP_ENOFILE; break; } @@ -826,150 +1583,39 @@ int zip_create(const char *zipname, const char *filenames[], size_t len) { } ext_attributes |= (mz_uint32)((file_stat.st_mode & 0xFFFF) << 16); - if (!mz_zip_writer_add_file(&zip_archive, base_name(name), name, "", 0, + if (!mz_zip_writer_add_file(&zip_archive, zip_basename(name), name, "", 0, ZIP_DEFAULT_COMPRESSION_LEVEL, ext_attributes)) { // Cannot add file to zip_archive - status = -1; + err = ZIP_ENOFILE; break; } } mz_zip_writer_finalize_archive(&zip_archive); mz_zip_writer_end(&zip_archive); - return status; + return err; } int zip_extract(const char *zipname, const char *dir, int (*on_extract)(const char *filename, void *arg), void *arg) { - int status = -1; - mz_uint i, n; - char path[MAX_PATH + 1]; - char symlink_to[MAX_PATH + 1]; mz_zip_archive zip_archive; - mz_zip_archive_file_stat info; - size_t dirlen = 0; -#if defined(_MSC_VER) -#else - mz_uint32 xattr = 0; -#endif - - - memset(path, 0, sizeof(path)); - memset(symlink_to, 0, sizeof(symlink_to)); - if (!memset(&(zip_archive), 0, sizeof(zip_archive))) { - // Cannot memset zip archive - return -1; - } if (!zipname || !dir) { // Cannot parse zip archive name - return -1; + return ZIP_EINVZIPNAME; } - dirlen = strlen(dir); - if (dirlen + 1 > MAX_PATH) { - return -1; + if (!memset(&zip_archive, 0, sizeof(mz_zip_archive))) { + // Cannot memset zip archive + return ZIP_EMEMSET; } // Now try to open the archive. if (!mz_zip_reader_init_file(&zip_archive, zipname, 0)) { // Cannot initialize zip_archive reader - return -1; + return ZIP_ENOINIT; } - memset((void *)&info, 0, sizeof(mz_zip_archive_file_stat)); - -#if defined(_MSC_VER) - strcpy_s(path, MAX_PATH, dir); -#else - strcpy(path, dir); -#endif - - if (!ISSLASH(path[dirlen - 1])) { -#if defined(_WIN32) || defined(__WIN32__) - path[dirlen] = '\\'; -#else - path[dirlen] = '/'; -#endif - ++dirlen; - } - - // Get and print information about each file in the archive. - n = mz_zip_reader_get_num_files(&zip_archive); - for (i = 0; i < n; ++i) { - if (!mz_zip_reader_file_stat(&zip_archive, i, &info)) { - // Cannot get information about zip archive; - goto out; - } -#if defined(_MSC_VER) - strncpy_s(&path[dirlen], MAX_PATH - dirlen, info.m_filename, - MAX_PATH - dirlen); -#else - strncpy(&path[dirlen], info.m_filename, MAX_PATH - dirlen); -#endif - if (mkpath(path) < 0) { - // Cannot make a path - goto out; - } - - if ((((info.m_version_made_by >> 8) == 3) || - ((info.m_version_made_by >> 8) == - 19)) // if zip is produced on Unix or macOS (3 and 19 from - // section 4.4.2.2 of zip standard) - && info.m_external_attr & - (0x20 << 24)) { // and has sym link attribute (0x80 is file, 0x40 - // is directory) -#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ - defined(__MINGW32__) -#else - if (info.m_uncomp_size > MAX_PATH || - !mz_zip_reader_extract_to_mem_no_alloc(&zip_archive, i, symlink_to, - MAX_PATH, 0, NULL, 0)) { - goto out; - } - symlink_to[info.m_uncomp_size] = '\0'; - if (symlink(symlink_to, path) != 0) { - goto out; - } -#endif - } else { - if (!mz_zip_reader_is_file_a_directory(&zip_archive, i)) { - if (!mz_zip_reader_extract_to_file(&zip_archive, i, path, 0)) { - // Cannot extract zip archive to file - goto out; - } - } - -#if defined(_MSC_VER) -#else - xattr = (info.m_external_attr >> 16) & 0xFFFF; - if (xattr > 0) { - if (chmod(path, (mode_t)xattr) < 0) { - goto out; - } - } -#endif - } - - if (on_extract) { - if (on_extract(path, arg) < 0) { - goto out; - } - } - } - status = 0; - -out: - // Close the archive, freeing any resources it was using - if (!mz_zip_reader_end(&zip_archive)) { - // Cannot end zip reader - status = -1; - } - - return status; + return zip_archive_extract(&zip_archive, dir, on_extract, arg); } - -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER diff --git a/contrib/zip/src/zip.h b/contrib/zip/src/zip.h index 87f3654f4..70ab2cee6 100644 --- a/contrib/zip/src/zip.h +++ b/contrib/zip/src/zip.h @@ -15,19 +15,11 @@ #include #include -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4127 ) -#endif //_MSC_VER - #ifdef __cplusplus extern "C" { #endif -#if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_DEFINED_) && \ - !defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) && \ - !defined(_SSIZE_T) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DECLARED) - +#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER) // 64-bit Windows is the only mainstream platform // where sizeof(long) != sizeof(void*) #ifdef _WIN64 @@ -35,15 +27,6 @@ typedef long long ssize_t; /* byte count or error */ #else typedef long ssize_t; /* byte count or error */ #endif - -#define _SSIZE_T_DEFINED -#define _SSIZE_T_DEFINED_ -#define __DEFINED_ssize_t -#define __ssize_t_defined -#define _SSIZE_T -#define _SSIZE_T_ -#define _SSIZE_T_DECLARED - #endif #ifndef MAX_PATH @@ -64,9 +47,49 @@ typedef long ssize_t; /* byte count or error */ /** * Default zip compression level. */ - #define ZIP_DEFAULT_COMPRESSION_LEVEL 6 +/** + * Error codes + */ +#define ZIP_ENOINIT -1 // not initialized +#define ZIP_EINVENTNAME -2 // invalid entry name +#define ZIP_ENOENT -3 // entry not found +#define ZIP_EINVMODE -4 // invalid zip mode +#define ZIP_EINVLVL -5 // invalid compression level +#define ZIP_ENOSUP64 -6 // no zip 64 support +#define ZIP_EMEMSET -7 // memset error +#define ZIP_EWRTENT -8 // cannot write data to entry +#define ZIP_ETDEFLINIT -9 // cannot initialize tdefl compressor +#define ZIP_EINVIDX -10 // invalid index +#define ZIP_ENOHDR -11 // header not found +#define ZIP_ETDEFLBUF -12 // cannot flush tdefl buffer +#define ZIP_ECRTHDR -13 // cannot create entry header +#define ZIP_EWRTHDR -14 // cannot write entry header +#define ZIP_EWRTDIR -15 // cannot write to central dir +#define ZIP_EOPNFILE -16 // cannot open file +#define ZIP_EINVENTTYPE -17 // invalid entry type +#define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation +#define ZIP_ENOFILE -19 // file not found +#define ZIP_ENOPERM -20 // no permission +#define ZIP_EOOMEM -21 // out of memory +#define ZIP_EINVZIPNAME -22 // invalid zip archive name +#define ZIP_EMKDIR -23 // make dir error +#define ZIP_ESYMLINK -24 // symlink error +#define ZIP_ECLSZIP -25 // close archive error +#define ZIP_ECAPSIZE -26 // capacity size too small +#define ZIP_EFSEEK -27 // fseek error +#define ZIP_EFREAD -28 // fread error +#define ZIP_EFWRITE -29 // fwrite error + +/** + * Looks up the error message string coresponding to an error number. + * @param errnum error number + * @return error message string coresponding to errnum or NULL if error is not + * found. + */ +extern const char *zip_strerror(int errnum); + /** * @struct zip_t * @@ -242,8 +265,8 @@ extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize); * * @note ensure supplied output buffer is large enough. * zip_entry_size function (returns uncompressed size for the current - * entry) can be handy to estimate how big buffer is needed. for large - * entries, please take a look at zip_entry_extract function. + * entry) can be handy to estimate how big buffer is needed. + * For large entries, please take a look at zip_entry_extract function. * * @return the return code - the number of bytes actually read on success. * Otherwise a -1 on error (e.g. bufsize is not large enough). @@ -285,7 +308,71 @@ zip_entry_extract(struct zip_t *zip, * @return the return code - the number of entries on success, negative number * (< 0) on error. */ -extern int zip_total_entries(struct zip_t *zip); +extern int zip_entries_total(struct zip_t *zip); + +/** + * Deletes zip archive entries. + * + * @param zip zip archive handler. + * @param entries array of zip archive entries to be deleted. + * @param len the number of entries to be deleted. + * @return the number of deleted entries, or negative number (< 0) on error. + */ +extern int zip_entries_delete(struct zip_t *zip, char *const entries[], + size_t len); + +/** + * Extracts a zip archive stream into directory. + * + * If on_extract is not NULL, the callback will be called after + * successfully extracted each zip entry. + * Returning a negative value from the callback will cause abort and return an + * error. The last argument (void *arg) is optional, which you can use to pass + * data to the on_extract callback. + * + * @param stream zip archive stream. + * @param size stream size. + * @param dir output directory. + * @param on_extract on extract callback. + * @param arg opaque pointer. + * + * @return the return code - 0 on success, negative number (< 0) on error. + */ +extern int zip_stream_extract(const char *stream, size_t size, const char *dir, + int (*on_extract)(const char *filename, + void *arg), + void *arg); + +/** + * Opens zip archive stream into memory. + * + * @param stream zip archive stream. + * @param size stream size. + * + * @return the zip archive handler or NULL on error + */ +extern struct zip_t *zip_stream_open(const char *stream, size_t size, int level, + char mode); + +/** + * Copy zip archive stream output buffer. + * + * @param zip zip archive handler. + * @param buf output buffer. User should free buf. + * @param bufsize output buffer size (in bytes). + * + * @return copy size + */ +extern ssize_t zip_stream_copy(struct zip_t *zip, void **buf, ssize_t *bufsize); + +/** + * Close zip archive releases resources. + * + * @param zip zip archive handler. + * + * @return + */ +extern void zip_stream_close(struct zip_t *zip); /** * Creates a new archive and puts files into a single zip archive. @@ -319,11 +406,6 @@ extern int zip_extract(const char *zipname, const char *dir, void *arg); /** @} */ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif //_MSC_VER - #ifdef __cplusplus } #endif diff --git a/contrib/zip/test/CMakeLists.txt b/contrib/zip/test/CMakeLists.txt index a7c3650f7..0da1684d4 100644 --- a/contrib/zip/test/CMakeLists.txt +++ b/contrib/zip/test/CMakeLists.txt @@ -1,11 +1,38 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.4) -# test -set(test_out test.out) +# tests +set(test_write_out test_write.out) +add_executable(${test_write_out} test_write.c) +target_link_libraries(${test_write_out} zip) +add_test(NAME ${test_write_out} COMMAND ${test_write_out}) +set(test_write_out ${test_write_out} PARENT_SCOPE) -add_executable(${test_out} test.c) -target_link_libraries(${test_out} zip) +set(test_append_out test_append.out) +add_executable(${test_append_out} test_append.c) +target_link_libraries(${test_append_out} zip) +add_test(NAME ${test_append_out} COMMAND ${test_append_out}) +set(test_append_out ${test_append_out} PARENT_SCOPE) -add_test(NAME ${test_out} COMMAND ${test_out}) +set(test_read_out test_read.out) +add_executable(${test_read_out} test_read.c) +target_link_libraries(${test_read_out} zip) +add_test(NAME ${test_read_out} COMMAND ${test_read_out}) +set(test_read_out ${test_read_out} PARENT_SCOPE) -set(test_out ${test_out} PARENT_SCOPE) +set(test_extract_out test_extract.out) +add_executable(${test_extract_out} test_extract.c) +target_link_libraries(${test_extract_out} zip) +add_test(NAME ${test_extract_out} COMMAND ${test_extract_out}) +set(test_extract_out ${test_extract_out} PARENT_SCOPE) + +set(test_entry_out test_entry.out) +add_executable(${test_entry_out} test_entry.c) +target_link_libraries(${test_entry_out} zip) +add_test(NAME ${test_entry_out} COMMAND ${test_entry_out}) +set(test_entry_out ${test_entry_out} PARENT_SCOPE) + +set(test_permissions_out test_permissions.out) +add_executable(${test_permissions_out} test_permissions.c) +target_link_libraries(${test_permissions_out} zip) +add_test(NAME ${test_permissions_out} COMMAND ${test_permissions_out}) +set(test_permissions_out ${test_permissions_out} PARENT_SCOPE) diff --git a/doc/Fileformats.md b/doc/Fileformats.md index c9116e2e7..89b68e17f 100644 --- a/doc/Fileformats.md +++ b/doc/Fileformats.md @@ -81,6 +81,7 @@ __Exporters__: - JSON (for WebGl, via https://github.com/acgessler/assimp2json) - ASSBIN - STEP +- [PBRTv4](https://github.com/mmp/pbrt-v4) - glTF 1.0 (partial) - glTF 2.0 (partial) - 3MF ( experimental ) diff --git a/include/assimp/BaseImporter.h b/include/assimp/BaseImporter.h index 86d7ba70f..38bec1afd 100644 --- a/include/assimp/BaseImporter.h +++ b/include/assimp/BaseImporter.h @@ -51,10 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Exceptional.h" -#include #include #include -#include #include #include #include @@ -179,42 +177,10 @@ public: /** * Will be called only by scale process when scaling is requested. */ - virtual void SetFileScale(double scale) { + void SetFileScale(double scale) { fileScale = scale; } - virtual double GetFileScale() const { - return fileScale; - } - - enum ImporterUnits { - M, - MM, - CM, - INCHES, - FEET - }; - - /** - * Assimp Importer - * unit conversions available - * NOTE: Valid options are initialised in the - * constructor in the implementation file to - * work around a VS2013 compiler bug if support - * for that compiler is dropped in the future - * initialisation can be moved back here - * */ - std::map importerUnits; - - virtual void SetApplicationUnits(const ImporterUnits &unit) { - importerScale = importerUnits[unit]; - applicationUnits = unit; - } - - virtual const ImporterUnits &GetApplicationUnits() { - return applicationUnits; - } - // ------------------------------------------------------------------- /** Called by #Importer::GetExtensionList for each loaded importer. * Take the extension list contained in the structure returned by @@ -223,7 +189,6 @@ public: void GetExtensionList(std::set &extensions); protected: - ImporterUnits applicationUnits = ImporterUnits::M; double importerScale = 1.0; double fileScale = 1.0; @@ -420,7 +385,7 @@ public: // static utilities private: /* Pushes state into importer for the importer scale */ - virtual void UpdateImporterScale(Importer *pImp); + void UpdateImporterScale(Importer *pImp); protected: /// Error description in case there was one. diff --git a/include/assimp/Bitmap.h b/include/assimp/Bitmap.h index d56bb4c73..e4ce194d9 100644 --- a/include/assimp/Bitmap.h +++ b/include/assimp/Bitmap.h @@ -75,13 +75,12 @@ protected: uint32_t offset; // We define the struct size because sizeof(Header) might return a wrong result because of structure padding. - // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). - static const std::size_t header_size = - sizeof(uint16_t) + // type - sizeof(uint32_t) + // size - sizeof(uint16_t) + // reserved1 - sizeof(uint16_t) + // reserved2 - sizeof(uint32_t); // offset + static constexpr std::size_t header_size = + sizeof(type) + + sizeof(size) + + sizeof(reserved1) + + sizeof(reserved2) + + sizeof(offset); }; struct DIB { @@ -98,22 +97,21 @@ protected: uint32_t nb_important_colors; // We define the struct size because sizeof(DIB) might return a wrong result because of structure padding. - // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). - static const std::size_t dib_size = - sizeof(uint32_t) + // size - sizeof(int32_t) + // width - sizeof(int32_t) + // height - sizeof(uint16_t) + // planes - sizeof(uint16_t) + // bits_per_pixel - sizeof(uint32_t) + // compression - sizeof(uint32_t) + // image_size - sizeof(int32_t) + // x_resolution - sizeof(int32_t) + // y_resolution - sizeof(uint32_t) + // nb_colors - sizeof(uint32_t); // nb_important_colors + static constexpr std::size_t dib_size = + sizeof(size) + + sizeof(width) + + sizeof(height) + + sizeof(planes) + + sizeof(bits_per_pixel) + + sizeof(compression) + + sizeof(image_size) + + sizeof(x_resolution) + + sizeof(y_resolution) + + sizeof(nb_colors) + + sizeof(nb_important_colors); }; - static const std::size_t mBytesPerPixel = 4; + static constexpr std::size_t mBytesPerPixel = 4; public: static void Save(aiTexture* texture, IOStream* file); diff --git a/include/assimp/DefaultIOStream.h b/include/assimp/DefaultIOStream.h index b1bb66902..6d0e13149 100644 --- a/include/assimp/DefaultIOStream.h +++ b/include/assimp/DefaultIOStream.h @@ -119,7 +119,7 @@ private: AI_FORCE_INLINE DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT : mFile(nullptr) -, mFilename("") +, mFilename() , mCachedSize(SIZE_MAX) { // empty } diff --git a/include/assimp/Exceptional.h b/include/assimp/Exceptional.h index 36d60d63a..98e2a3321 100644 --- a/include/assimp/Exceptional.h +++ b/include/assimp/Exceptional.h @@ -71,6 +71,9 @@ protected: * nullptr instead of a valid aiScene then. */ class ASSIMP_API DeadlyImportError : public DeadlyErrorBase { public: + DeadlyImportError(const char *message) : + DeadlyErrorBase(Assimp::Formatter::format(), std::forward(message)) {} + /** Constructor with arguments */ template explicit DeadlyImportError(T&&... args) : diff --git a/include/assimp/IOSystem.hpp b/include/assimp/IOSystem.hpp index b05eebce6..76f876440 100644 --- a/include/assimp/IOSystem.hpp +++ b/include/assimp/IOSystem.hpp @@ -294,7 +294,7 @@ bool IOSystem::PushDirectory( const std::string &path ) { AI_FORCE_INLINE const std::string &IOSystem::CurrentDirectory() const { if ( m_pathStack.empty() ) { - static const std::string Dummy(""); + static const std::string Dummy; return Dummy; } return m_pathStack[ m_pathStack.size()-1 ]; diff --git a/include/assimp/Importer.hpp b/include/assimp/Importer.hpp index 18734c302..09b5b6883 100644 --- a/include/assimp/Importer.hpp +++ b/include/assimp/Importer.hpp @@ -286,7 +286,7 @@ public: * @see GetPropertyInteger() */ std::string GetPropertyString(const char *szName, - const std::string &sErrorReturn = "") const; + const std::string &sErrorReturn = std::string()) const; // ------------------------------------------------------------------- /** Get a matrix configuration property diff --git a/include/assimp/LineSplitter.h b/include/assimp/LineSplitter.h index 7cb71476c..44e6f0f1e 100644 --- a/include/assimp/LineSplitter.h +++ b/include/assimp/LineSplitter.h @@ -72,7 +72,7 @@ for(LineSplitter splitter(stream);splitter;++splitter) { if (strtol(splitter[2]) > 5) { .. } } - ASSIMP_LOG_VERBOSE_DEBUG_F("Current line is: ", splitter.get_index()); + ASSIMP_LOG_VERBOSE_DEBUG("Current line is: ", splitter.get_index()); } @endcode */ diff --git a/include/assimp/LogAux.h b/include/assimp/LogAux.h index b0a1f9ddd..065433648 100644 --- a/include/assimp/LogAux.h +++ b/include/assimp/LogAux.h @@ -64,82 +64,49 @@ public: template static void ThrowException(T&&... args) { - throw DeadlyImportError(Prefix(), args...); + throw DeadlyImportError(Prefix(), std::forward(args)...); } // ------------------------------------------------------------------------------------------------ - static void LogWarn(const Formatter::format& message) { + template + static void LogWarn(T&&... args) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_WARN(Prefix()+(std::string)message); + ASSIMP_LOG_WARN(Prefix(), std::forward(args)...); } } // ------------------------------------------------------------------------------------------------ - static void LogError(const Formatter::format& message) { + template + static void LogError(T&&... args) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_ERROR(Prefix()+(std::string)message); + ASSIMP_LOG_ERROR(Prefix(), std::forward(args)...); } } // ------------------------------------------------------------------------------------------------ - static void LogInfo(const Formatter::format& message) { + template + static void LogInfo(T&&... args) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO(Prefix()+(std::string)message); + ASSIMP_LOG_INFO(Prefix(), std::forward(args)...); } } // ------------------------------------------------------------------------------------------------ - static void LogDebug(const Formatter::format& message) { + template + static void LogDebug(T&&... args) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_DEBUG(Prefix()+(std::string)message); - } - } - - static void LogVerboseDebug(const Formatter::format& message) { - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_VERBOSE_DEBUG(Prefix()+(std::string)message); - } - } - - // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 -#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) - - // ------------------------------------------------------------------------------------------------ - static void LogWarn (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogWarn(Formatter::format(message)); + ASSIMP_LOG_DEBUG(Prefix(), std::forward(args)...); } } // ------------------------------------------------------------------------------------------------ - static void LogError (const char* message) { + template + static void LogVerboseDebug(T&&... args) { if (!DefaultLogger::isNullLogger()) { - LogError(Formatter::format(message)); + ASSIMP_LOG_VERBOSE_DEBUG(Prefix(), std::forward(args)...); } } - // ------------------------------------------------------------------------------------------------ - static void LogInfo (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogInfo(Formatter::format(message)); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogDebug (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogDebug(Formatter::format(message)); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogVerboseDebug (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogVerboseDebug(Formatter::format(message)); - } - } -#endif - private: static const char* Prefix(); diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index ee6eab507..3ca4a6cb2 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -99,34 +99,54 @@ public: virtual ~Logger(); // ---------------------------------------------------------------------- - /** @brief Writes a debug message - * @param message Debug message*/ + /** @brief Writes a info message + * @param message Info message*/ void debug(const char* message); - void debug(const std::string &message); + + template + void debug(T&&... args) { + debug(formatMessage(std::forward(args)...).c_str()); + } // ---------------------------------------------------------------------- /** @brief Writes a debug message * @param message Debug message*/ - void verboseDebug(const char *message); - void verboseDebug(const std::string &message); + void verboseDebug(const char* message); + + template + void verboseDebug(T&&... args) { + verboseDebug(formatMessage(std::forward(args)...).c_str()); + } // ---------------------------------------------------------------------- /** @brief Writes a info message * @param message Info message*/ void info(const char* message); - void info(const std::string &message); + + template + void info(T&&... args) { + info(formatMessage(std::forward(args)...).c_str()); + } // ---------------------------------------------------------------------- /** @brief Writes a warning message * @param message Warn message*/ void warn(const char* message); - void warn(const std::string &message); + + template + void warn(T&&... args) { + warn(formatMessage(std::forward(args)...).c_str()); + } // ---------------------------------------------------------------------- /** @brief Writes an error message - * @param message Error message*/ + * @param message Info message*/ void error(const char* message); - void error(const std::string &message); + + template + void error(T&&... args) { + error(formatMessage(std::forward(args)...).c_str()); + } // ---------------------------------------------------------------------- /** @brief Set a new log severity. @@ -224,6 +244,15 @@ protected: * the function is left. */ virtual void OnError(const char* message) = 0; +protected: + std::string formatMessage(Assimp::Formatter::format f) { + return f; + } + + template + std::string formatMessage(Assimp::Formatter::format f, U&& u, T&&... args) { + return formatMessage(std::move(f << std::forward(u)), std::forward(args)...); + } protected: LogSeverity m_Severity; @@ -266,66 +295,22 @@ Logger::LogSeverity Logger::getLogSeverity() const { return m_Severity; } -// ---------------------------------------------------------------------------------- -inline -void Logger::debug(const std::string &message) { - return debug(message.c_str()); -} - -// ---------------------------------------------------------------------------------- -inline void Logger::verboseDebug(const std::string &message) { - return verboseDebug(message.c_str()); -} - -// ---------------------------------------------------------------------------------- -inline -void Logger::error(const std::string &message) { - return error(message.c_str()); -} - -// ---------------------------------------------------------------------------------- -inline -void Logger::warn(const std::string &message) { - return warn(message.c_str()); -} - -// ---------------------------------------------------------------------------------- -inline -void Logger::info(const std::string &message) { - return info(message.c_str()); -} - } // Namespace Assimp // ------------------------------------------------------------------------------------------------ -#define ASSIMP_LOG_WARN_F(string, ...) \ - Assimp::DefaultLogger::get()->warn((Assimp::Formatter::format(string), __VA_ARGS__)) +#define ASSIMP_LOG_WARN(...) \ + Assimp::DefaultLogger::get()->warn(__VA_ARGS__) -#define ASSIMP_LOG_ERROR_F(string, ...) \ - Assimp::DefaultLogger::get()->error((Assimp::Formatter::format(string), __VA_ARGS__)) +#define ASSIMP_LOG_ERROR(...) \ + Assimp::DefaultLogger::get()->error(__VA_ARGS__) -#define ASSIMP_LOG_DEBUG_F(string, ...) \ - Assimp::DefaultLogger::get()->debug((Assimp::Formatter::format(string), __VA_ARGS__)) +#define ASSIMP_LOG_DEBUG(...) \ + Assimp::DefaultLogger::get()->debug(__VA_ARGS__) -#define ASSIMP_LOG_VERBOSE_DEBUG_F(string, ...) \ - Assimp::DefaultLogger::get()->verboseDebug((Assimp::Formatter::format(string), __VA_ARGS__)) +#define ASSIMP_LOG_VERBOSE_DEBUG(...) \ + Assimp::DefaultLogger::get()->verboseDebug(__VA_ARGS__) -#define ASSIMP_LOG_INFO_F(string, ...) \ - Assimp::DefaultLogger::get()->info((Assimp::Formatter::format(string), __VA_ARGS__)) - -#define ASSIMP_LOG_WARN(string) \ - Assimp::DefaultLogger::get()->warn(string) - -#define ASSIMP_LOG_ERROR(string) \ - Assimp::DefaultLogger::get()->error(string) - -#define ASSIMP_LOG_DEBUG(string) \ - Assimp::DefaultLogger::get()->debug(string) - -#define ASSIMP_LOG_VERBOSE_DEBUG(string) \ - Assimp::DefaultLogger::get()->verboseDebug(string) - -#define ASSIMP_LOG_INFO(string) \ - Assimp::DefaultLogger::get()->info(string) +#define ASSIMP_LOG_INFO(...) \ + Assimp::DefaultLogger::get()->info(__VA_ARGS__) #endif // !! INCLUDED_AI_LOGGER_H diff --git a/include/assimp/ParsingUtils.h b/include/assimp/ParsingUtils.h index b52b0610e..b5074869e 100644 --- a/include/assimp/ParsingUtils.h +++ b/include/assimp/ParsingUtils.h @@ -262,7 +262,7 @@ AI_FORCE_INLINE unsigned int tokenize(const string_type &str, std::vector elapsedSeconds = std::chrono::system_clock::now() - regions[region]; - ASSIMP_LOG_DEBUG((format("END `"),region,"`, dt= ", elapsedSeconds.count()," s")); + ASSIMP_LOG_DEBUG("END `",region,"`, dt= ", elapsedSeconds.count()," s"); } private: diff --git a/include/assimp/StringComparison.h b/include/assimp/StringComparison.h index 6dad01294..b0161664f 100644 --- a/include/assimp/StringComparison.h +++ b/include/assimp/StringComparison.h @@ -146,8 +146,8 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2) { #else char c1, c2; do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); + c1 = tolower((unsigned char)*(s1++)); + c2 = tolower((unsigned char)*(s2++)); } while (c1 && (c1 == c2)); return c1 - c2; #endif @@ -197,8 +197,8 @@ inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) { unsigned int p = 0; do { if (p++ >= n) return 0; - c1 = tolower(*s1++); - c2 = tolower(*s2++); + c1 = tolower((unsigned char)*(s1++)); + c2 = tolower((unsigned char)*(s2++)); } while (c1 && (c1 == c2)); return c1 - c2; diff --git a/include/assimp/StringUtils.h b/include/assimp/StringUtils.h index 4afd717cf..025a826d2 100644 --- a/include/assimp/StringUtils.h +++ b/include/assimp/StringUtils.h @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2021, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -55,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #ifdef _MSC_VER #define AI_SIZEFMT "%Iu" @@ -157,7 +157,7 @@ AI_FORCE_INLINE std::string ai_decimal_to_hexa(T toConvert) { ss >> result; for (size_t i = 0; i < result.size(); ++i) { - result[i] = (char)toupper(result[i]); + result[i] = (char)toupper((unsigned char)result[i]); } return result; @@ -177,7 +177,7 @@ AI_FORCE_INLINE std::string ai_rgba2hex(int r, int g, int b, int a, bool with_he if (with_head) { ss << "#"; } - ss << std::hex << (r << 24 | g << 16 | b << 8 | a); + ss << std::hex << std::setfill('0') << std::setw(8) << (r << 24 | g << 16 | b << 8 | a); return ss.str(); } @@ -249,4 +249,31 @@ AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) { return out; } -#endif +// --------------------------------------------------------------------------------- +/// @brief Make a string printable by replacing all non-printable characters with +/// the specified placeholder character. +/// @param in The incoming string. +/// @param placeholder Placeholder character, default is a question mark. +/// @return The string, with all non-printable characters replaced. +AI_FORCE_INLINE std::string ai_str_toprintable(const std::string &in, char placeholder = '?') { + std::string out(in); + std::transform(out.begin(), out.end(), out.begin(), [placeholder] (unsigned char c) { + return isprint(c) ? (char)c : placeholder; + }); + return out; +} + +// --------------------------------------------------------------------------------- +/// @brief Make a string printable by replacing all non-printable characters with +/// the specified placeholder character. +/// @param in The incoming string. +/// @param len The length of the incoming string. +/// @param placeholder Placeholder character, default is a question mark. +/// @return The string, with all non-printable characters replaced. Will return an +/// empty string if in is null or len is <= 0. +AI_FORCE_INLINE std::string ai_str_toprintable(const char *in, int len, char placeholder = '?') { + return (in && len > 0) ? ai_str_toprintable(std::string(in, len), placeholder) : std::string(); +} + + +#endif // INCLUDED_AI_STRINGUTILS_H diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 15c4ff9ff..18d48f337 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -43,8 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define INCLUDED_AI_IRRXML_WRAPPER #include +#include + #include "BaseImporter.h" #include "IOStream.hpp" + #include #include @@ -63,6 +66,8 @@ struct find_node_by_name_predicate { } }; +/// @brief Will convert an attribute to its int value. +/// @tparam TNodeType The node type. template struct NodeConverter { public: @@ -75,19 +80,37 @@ public: using XmlNode = pugi::xml_node; using XmlAttribute = pugi::xml_attribute; +/// @brief The Xml-Parser class. +/// +/// Use this parser if you have to import any kind of xml-format. +/// +/// An example: +/// @code +/// TXmlParser theParser; +/// if (theParser.parse(fileStream)) { +/// auto node = theParser.getRootNode(); +/// for ( auto currentNode : node.children()) { +/// // Will loop over all children +/// } +/// } +/// @endcode +/// @tparam TNodeType template class TXmlParser { public: + /// @brief The default class constructor. TXmlParser() : mDoc(nullptr), mData() { // empty } + /// @brief The class destructor. ~TXmlParser() { clear(); } + /// @brief Will clear the parsed xml-file. void clear() { if(mData.empty()) { mDoc = nullptr; @@ -98,6 +121,9 @@ public: mDoc = nullptr; } + /// @brief Will search for a child-node by its name + /// @param name [in] The name of the child-node. + /// @return The node instance or nullptr, if nothing was found. TNodeType *findNode(const std::string &name) { if (name.empty()) { return nullptr; @@ -116,10 +142,16 @@ public: return &mCurrent; } + /// @brief Will return true, if the node is a child-node. + /// @param name [in] The name of the child node to look for. + /// @return true, if the node is a child-node or false if not. bool hasNode(const std::string &name) { return nullptr != findNode(name); } + /// @brief Will parse an xml-file from a given stream. + /// @param stream The input stream. + /// @return true, if the parsing was successful, false if not. bool parse(IOStream *stream) { if (nullptr == stream) { ASSIMP_LOG_DEBUG("Stream is nullptr."); @@ -135,34 +167,67 @@ public: pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full); if (parse_result.status == pugi::status_ok) { return true; - } else { - ASSIMP_LOG_DEBUG("Error while parse xml."); - return false; - } + } + + ASSIMP_LOG_DEBUG("Error while parse xml.", std::string(parse_result.description()), " @ ", parse_result.offset); + + return false; } + /// @brief Will return truem if a root node is there. + /// @return true in case of an existing root. + bool hasRoot() const { + return nullptr != mDoc; + } + /// @brief Will return the document pointer, is nullptr if no xml-file was parsed. + /// @return The pointer showing to the document. pugi::xml_document *getDocument() const { return mDoc; } + /// @brief Will return the root node, const version. + /// @return The root node. const TNodeType getRootNode() const { + static pugi::xml_node none; + if (nullptr == mDoc) { + return none; + } return mDoc->root(); } + /// @brief Will return the root node, non-const version. + /// @return The root node. TNodeType getRootNode() { + static pugi::xml_node none; + if (nullptr == mDoc) { + return none; + } return mDoc->root(); } + /// @brief Will check if a node with the given name is in. + /// @param node [in] The node to look in. + /// @param name [in] The name of the child-node. + /// @return true, if node was found, false if not. static inline bool hasNode(XmlNode &node, const char *name) { pugi::xml_node child = node.find_child(find_node_by_name_predicate(name)); return !child.empty(); } + /// @brief Will check if an attribute is part of the XmlNode. + /// @param xmlNode [in] The node to search in. + /// @param name [in} The attribute name to look for. + /// @return true, if the was found, false if not. static inline bool hasAttribute(XmlNode &xmlNode, const char *name) { pugi::xml_attribute attr = xmlNode.attribute(name); return !attr.empty(); } + /// @brief Will try to get an unsigned int attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The unsigned int value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is an unsigned int. static inline bool getUIntAttribute(XmlNode &xmlNode, const char *name, unsigned int &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -173,6 +238,11 @@ public: return true; } + /// @brief Will try to get an int attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The int value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is an int. static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val ) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -183,6 +253,11 @@ public: return true; } + /// @brief Will try to get a real attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The real value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a real. static inline bool getRealAttribute( XmlNode &xmlNode, const char *name, ai_real &val ) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -196,7 +271,12 @@ public: return true; } - static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val ) { + /// @brief Will try to get a float attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The float value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a float. + static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { return false; @@ -207,7 +287,12 @@ public: } - static inline bool getDoubleAttribute( XmlNode &xmlNode, const char *name, double &val ) { + /// @brief Will try to get a double attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The double value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a double. + static inline bool getDoubleAttribute(XmlNode &xmlNode, const char *name, double &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { return false; @@ -217,6 +302,11 @@ public: return true; } + /// @brief Will try to get a std::string attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The std::string value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a std::string. static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -227,6 +317,11 @@ public: return true; } + /// @brief Will try to get a bool attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The bool value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a bool. static inline bool getBoolAttribute( XmlNode &xmlNode, const char *name, bool &val ) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -238,8 +333,12 @@ public: } + /// @brief Will try to get the value of the node as a string. + /// @param node [in] The node to search in. + /// @param text [out] The value as a text. + /// @return true, if the value can be read out. static inline bool getValueAsString( XmlNode &node, std::string &text ) { - text = ""; + text = std::string(); if (node.empty()) { return false; } @@ -249,6 +348,10 @@ public: return true; } + /// @brief Will try to get the value of the node as a float. + /// @param node [in] The node to search in. + /// @param text [out] The value as a float. + /// @return true, if the value can be read out. static inline bool getValueAsFloat( XmlNode &node, ai_real &v ) { if (node.empty()) { return false; @@ -268,17 +371,36 @@ public: using XmlParser = TXmlParser; +/// @brief This class declares an iterator to loop through all children of the root node. class XmlNodeIterator { public: - XmlNodeIterator(XmlNode &parent) : + /// @brief The iteration mode. + enum IterationMode { + PreOrderMode, ///< Pre-ordering, get the values, continue the iteration. + PostOrderMode ///< Post-ordering, continue the iteration, get the values. + }; + /// @brief The class constructor + /// @param parent [in] The xml parent to to iterate through. + /// @param mode [in] The iteration mode. + explicit XmlNodeIterator(XmlNode &parent, IterationMode mode) : mParent(parent), mNodes(), mIndex(0) { + if (mode == PreOrderMode) { + collectChildrenPreOrder(parent); + } else { + collectChildrenPostOrder(parent); + } + } + + /// @brief The class destructor. + ~XmlNodeIterator() { // empty } + /// @brief Will iterate through all children in pre-order iteration. + /// @param node [in] The nod to iterate through. void collectChildrenPreOrder( XmlNode &node ) { - if (node != mParent && node.type() == pugi::node_element) { mNodes.push_back(node); } @@ -287,6 +409,8 @@ public: } } + /// @brief Will iterate through all children in post-order iteration. + /// @param node [in] The nod to iterate through. void collectChildrenPostOrder(XmlNode &node) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { collectChildrenPostOrder(currentNode); @@ -296,6 +420,9 @@ public: } } + /// @brief Will iterate through all collected nodes. + /// @param next The next node, if there is any. + /// @return true, if there is a node left. bool getNext(XmlNode &next) { if (mIndex == mNodes.size()) { return false; @@ -307,14 +434,19 @@ public: return true; } + /// @brief Will return the number of collected nodes. + /// @return The number of collected nodes. size_t size() const { return mNodes.size(); } + /// @brief Returns true, if the node is empty. + /// @return true, if the node is empty, false if not. bool isEmpty() const { return mNodes.empty(); } + /// @brief Will clear all collected nodes. void clear() { if (mNodes.empty()) { return; diff --git a/include/assimp/fast_atof.h b/include/assimp/fast_atof.h index 9ea49c85c..aea793f35 100644 --- a/include/assimp/fast_atof.h +++ b/include/assimp/fast_atof.h @@ -29,6 +29,7 @@ #include "StringComparison.h" #include #include +#include #ifdef _MSC_VER # include @@ -193,7 +194,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino if ( *in < '0' || *in > '9' ) { // The string is known to be bad, so don't risk printing the whole thing. - throw ExceptionType("The string \"", std::string(in).substr(0, 100), "\" cannot be converted into a value." ); + throw ExceptionType("The string \"", ai_str_toprintable(in, 30), "\" cannot be converted into a value." ); } for ( ;; ) { @@ -205,7 +206,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino // numeric overflow, we rely on you if ( new_value < value ) { - ASSIMP_LOG_WARN_F( "Converting the string \"", in, "\" into a value resulted in overflow." ); + ASSIMP_LOG_WARN( "Converting the string \"", in, "\" into a value resulted in overflow." ); return 0; } @@ -293,7 +294,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) if (!(c[0] >= '0' && c[0] <= '9') && !((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) { // The string is known to be bad, so don't risk printing the whole thing. - throw ExceptionType("Cannot parse string \"", std::string(c).substr(0, 100), + throw ExceptionType("Cannot parse string \"", ai_str_toprintable(c, 30), "\" as a real number: does not start with digit " "or decimal point followed by digit."); } diff --git a/port/PyAssimp/pyassimp/helper.py b/port/PyAssimp/pyassimp/helper.py index 5c1aca827..7a4b2bdcb 100644 --- a/port/PyAssimp/pyassimp/helper.py +++ b/port/PyAssimp/pyassimp/helper.py @@ -27,6 +27,7 @@ if os.name=='posix': additional_dirs.append('./') additional_dirs.append('/usr/lib/') additional_dirs.append('/usr/lib/x86_64-linux-gnu/') + additional_dirs.append('/usr/lib/aarch64-linux-gnu/') additional_dirs.append('/usr/local/lib/') if 'LD_LIBRARY_PATH' in os.environ: diff --git a/port/PyAssimp/pyassimp/structs.py b/port/PyAssimp/pyassimp/structs.py index 809afae54..e1fba1950 100644 --- a/port/PyAssimp/pyassimp/structs.py +++ b/port/PyAssimp/pyassimp/structs.py @@ -1,6 +1,6 @@ #-*- coding: utf-8 -*- -from ctypes import POINTER, c_void_p, c_uint, c_char, c_float, Structure, c_char_p, c_double, c_ubyte, c_size_t, c_uint32 +from ctypes import POINTER, c_void_p, c_uint, c_char, c_float, Structure, c_double, c_ubyte, c_size_t, c_uint32 class Vector2D(Structure): @@ -1121,7 +1121,7 @@ class Scene(Structure): ("mMetadata", POINTER(Metadata)), # Internal data, do not touch - ("mPrivate", c_char_p), + ("mPrivate", POINTER(c_char)), ] assimp_structs_as_tuple = (Matrix4x4, diff --git a/samples/SimpleTexturedDirectx11/SimpleTexturedDirectx11/ModelLoader.cpp b/samples/SimpleTexturedDirectx11/SimpleTexturedDirectx11/ModelLoader.cpp index 733d3d620..92760d691 100644 --- a/samples/SimpleTexturedDirectx11/SimpleTexturedDirectx11/ModelLoader.cpp +++ b/samples/SimpleTexturedDirectx11/SimpleTexturedDirectx11/ModelLoader.cpp @@ -42,22 +42,12 @@ void ModelLoader::Draw(ID3D11DeviceContext * devcon) { } } -std::string textype; - Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) { // Data to fill std::vector vertices; std::vector indices; std::vector textures; - if (mesh->mMaterialIndex >= 0) { - aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex]; - - if (textype.empty()) { - textype = determineTextureType(scene, mat); - } - } - // Walk through each of the mesh's vertices for (UINT i = 0; i < mesh->mNumVertices; i++) { VERTEX vertex; @@ -108,9 +98,10 @@ std::vector ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextu if (!skip) { // If texture hasn't been loaded already, load it HRESULT hr; Texture texture; - if (textype == "embedded compressed texture") { - int textureindex = getTextureIndex(&str); - texture.texture = getTextureFromModel(scene, textureindex); + + const aiTexture* embeddedTexture = scene->GetEmbeddedTexture(str.C_Str()); + if (embeddedTexture != nullptr) { + texture.texture = loadEmbeddedTexture(embeddedTexture); } else { std::string filename = std::string(str.C_Str()); filename = directory_ + '/' + filename; @@ -148,38 +139,46 @@ void ModelLoader::processNode(aiNode * node, const aiScene * scene) { } } -std::string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat) { - aiString textypeStr; - mat->GetTexture(aiTextureType_DIFFUSE, 0, &textypeStr); - std::string textypeteststr = textypeStr.C_Str(); - if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5") { - if (scene->mTextures[0]->mHeight == 0) { - return "embedded compressed texture"; - } else { - return "embedded non-compressed texture"; - } - } - if (textypeteststr.find('.') != std::string::npos) { - return "textures are on disk"; - } - - return "."; -} - -int ModelLoader::getTextureIndex(aiString * str) { - std::string tistr; - tistr = str->C_Str(); - tistr = tistr.substr(1); - return stoi(tistr); -} - -ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex) { +ID3D11ShaderResourceView * ModelLoader::loadEmbeddedTexture(const aiTexture* embeddedTexture) { HRESULT hr; - ID3D11ShaderResourceView *texture; + ID3D11ShaderResourceView *texture = nullptr; - int* size = reinterpret_cast(&scene->mTextures[textureindex]->mWidth); + if (embeddedTexture->mHeight != 0) { + // Load an uncompressed ARGB8888 embedded texture + D3D11_TEXTURE2D_DESC desc; + desc.Width = embeddedTexture->mWidth; + desc.Height = embeddedTexture->mHeight; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; - hr = CreateWICTextureFromMemory(dev_, devcon_, reinterpret_cast(scene->mTextures[textureindex]->pcData), *size, nullptr, &texture); + D3D11_SUBRESOURCE_DATA subresourceData; + subresourceData.pSysMem = embeddedTexture->pcData; + subresourceData.SysMemPitch = embeddedTexture->mWidth * 4; + subresourceData.SysMemSlicePitch = embeddedTexture->mWidth * embeddedTexture->mHeight * 4; + + ID3D11Texture2D *texture2D = nullptr; + hr = dev_->CreateTexture2D(&desc, &subresourceData, &texture2D); + if (FAILED(hr)) + MessageBox(hwnd_, "CreateTexture2D failed!", "Error!", MB_ICONERROR | MB_OK); + + hr = dev_->CreateShaderResourceView(texture2D, nullptr, &texture); + if (FAILED(hr)) + MessageBox(hwnd_, "CreateShaderResourceView failed!", "Error!", MB_ICONERROR | MB_OK); + + return texture; + } + + // mHeight is 0, so try to load a compressed texture of mWidth bytes + const size_t size = embeddedTexture->mWidth; + + hr = CreateWICTextureFromMemory(dev_, devcon_, reinterpret_cast(embeddedTexture->pcData), size, nullptr, &texture); if (FAILED(hr)) MessageBox(hwnd_, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK); diff --git a/samples/SimpleTexturedDirectx11/SimpleTexturedDirectx11/ModelLoader.h b/samples/SimpleTexturedDirectx11/SimpleTexturedDirectx11/ModelLoader.h index 9d3ed50b3..a04484f08 100644 --- a/samples/SimpleTexturedDirectx11/SimpleTexturedDirectx11/ModelLoader.h +++ b/samples/SimpleTexturedDirectx11/SimpleTexturedDirectx11/ModelLoader.h @@ -35,9 +35,7 @@ private: void processNode(aiNode* node, const aiScene* scene); Mesh processMesh(aiMesh* mesh, const aiScene* scene); std::vector loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName, const aiScene* scene); - std::string determineTextureType(const aiScene* scene, aiMaterial* mat); - int getTextureIndex(aiString* str); - ID3D11ShaderResourceView* getTextureFromModel(const aiScene* scene, int textureindex); + ID3D11ShaderResourceView* loadEmbeddedTexture(const aiTexture* embeddedTexture); }; #endif // !MODEL_LOADER_H diff --git a/test/test.3mf b/test/test.3mf new file mode 100644 index 000000000..eb1c49e1b Binary files /dev/null and b/test/test.3mf differ diff --git a/test/unit/Common/utXmlParser.cpp b/test/unit/Common/utXmlParser.cpp index c27669dd1..7e992f9df 100644 --- a/test/unit/Common/utXmlParser.cpp +++ b/test/unit/Common/utXmlParser.cpp @@ -73,9 +73,7 @@ TEST_F(utXmlParser, parse_xml_and_traverse_test) { EXPECT_TRUE(result); XmlNode root = parser.getRootNode(); - XmlNodeIterator nodeIt(root); - EXPECT_TRUE(nodeIt.isEmpty()); - nodeIt.collectChildrenPreOrder(root); + XmlNodeIterator nodeIt(root, XmlNodeIterator::PreOrderMode); const size_t numNodes = nodeIt.size(); bool empty = nodeIt.isEmpty(); EXPECT_FALSE(empty); diff --git a/test/unit/utImporter.cpp b/test/unit/utImporter.cpp index 65b7f99ee..9d3b971a3 100644 --- a/test/unit/utImporter.cpp +++ b/test/unit/utImporter.cpp @@ -280,104 +280,84 @@ TEST_F(ImporterTest, SearchFileHeaderForTokenTest) { // BaseImporter::SearchFileHeaderForToken( &ioSystem, assetPath, Token, 2 ) } +namespace { +// Description for an importer which fails in specific ways. +aiImporterDesc s_failingImporterDescription = { + "Failing importer", + "assimp team", + "", + "", + 0, + 1, + 0, + 1, + 0, + "fail" +}; -namespace -{ - // Description for an importer which fails in specific ways. - aiImporterDesc s_failingImporterDescription = { - "Failing importer", - "assimp team", - "", - "", - 0, - 1, - 0, - 1, - 0, - "fail" - }; +// This importer fails in specific ways. +class FailingImporter : public Assimp::BaseImporter { +public: + virtual ~FailingImporter() = default; + virtual bool CanRead(const std::string &, Assimp::IOSystem *, bool) const override { + return true; + } - // This importer fails in specific ways. - class FailingImporter : public Assimp::BaseImporter { - public: - virtual ~FailingImporter() = default; - virtual bool CanRead( const std::string&, Assimp::IOSystem*, bool ) const override - { - return true; +protected: + const aiImporterDesc *GetInfo() const override { + return &s_failingImporterDescription; + } + + void InternReadFile(const std::string &pFile, aiScene *, Assimp::IOSystem *) override { + if (pFile == "deadlyImportError.fail") { + throw DeadlyImportError("Deadly import error test. Details: ", 42, " More Details: ", "Failure"); + } else if (pFile == "stdException.fail") { + throw std::runtime_error("std::exception test"); + } else if (pFile == "unexpectedException.fail") { + throw 5; } + } +}; +} // namespace - protected: - virtual const aiImporterDesc* GetInfo() const override { return &s_failingImporterDescription; } - - virtual void InternReadFile( const std::string& pFile, aiScene*, Assimp::IOSystem* ) override - { - if (pFile == "deadlyImportError.fail") - { - throw DeadlyImportError("Deadly import error test. Details: ", 42, " More Details: ", "Failure"); - } - else if (pFile == "stdException.fail") - { - throw std::runtime_error("std::exception test"); - } - else if (pFile == "unexpectedException.fail") - { - throw 5; - } - } - }; -} - -TEST_F(ImporterTest, deadlyImportError) -{ +TEST_F(ImporterTest, deadlyImportError) { pImp->RegisterLoader(new FailingImporter); pImp->SetIOHandler(new TestIOSystem); - const aiScene* scene = pImp->ReadFile("deadlyImportError.fail", 0); + const aiScene *scene = pImp->ReadFile("deadlyImportError.fail", 0); EXPECT_EQ(scene, nullptr); EXPECT_STREQ(pImp->GetErrorString(), "Deadly import error test. Details: 42 More Details: Failure"); EXPECT_NE(pImp->GetException(), std::exception_ptr()); } -TEST_F(ImporterTest, stdException) -{ +TEST_F(ImporterTest, stdException) { pImp->RegisterLoader(new FailingImporter); pImp->SetIOHandler(new TestIOSystem); - const aiScene* scene = pImp->ReadFile("stdException.fail", 0); + const aiScene *scene = pImp->ReadFile("stdException.fail", 0); EXPECT_EQ(scene, nullptr); EXPECT_STREQ(pImp->GetErrorString(), "std::exception test"); EXPECT_NE(pImp->GetException(), std::exception_ptr()); - try - { + try { std::rethrow_exception(pImp->GetException()); - } - catch(const std::exception& e) - { + } catch (const std::exception &e) { EXPECT_STREQ(e.what(), "std::exception test"); - } - catch(...) - { + } catch (...) { EXPECT_TRUE(false); } } -TEST_F(ImporterTest, unexpectedException) -{ +TEST_F(ImporterTest, unexpectedException) { pImp->RegisterLoader(new FailingImporter); pImp->SetIOHandler(new TestIOSystem); - const aiScene* scene = pImp->ReadFile("unexpectedException.fail", 0); + const aiScene *scene = pImp->ReadFile("unexpectedException.fail", 0); EXPECT_EQ(scene, nullptr); EXPECT_STREQ(pImp->GetErrorString(), "Unknown exception"); ASSERT_NE(pImp->GetException(), std::exception_ptr()); - try - { + try { std::rethrow_exception(pImp->GetException()); - } - catch(int x) - { + } catch (int x) { EXPECT_EQ(x, 5); - } - catch(...) - { + } catch (...) { EXPECT_TRUE(false); } } diff --git a/test/unit/utStringUtils.cpp b/test/unit/utStringUtils.cpp index 6a10cba24..08be82e9a 100644 --- a/test/unit/utStringUtils.cpp +++ b/test/unit/utStringUtils.cpp @@ -42,9 +42,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include class utStringUtils : public ::testing::Test { + // empty }; -TEST_F( utStringUtils, to_string_Test ) { +TEST_F(utStringUtils, to_string_Test ) { std::string res = ai_to_string( 1 ); EXPECT_EQ( res, "1" ); @@ -52,7 +53,7 @@ TEST_F( utStringUtils, to_string_Test ) { EXPECT_EQ( res, "1" ); } -TEST_F( utStringUtils, ai_strtofTest ) { +TEST_F(utStringUtils, ai_strtofTest ) { float res = ai_strtof( nullptr, nullptr ); EXPECT_FLOAT_EQ( res, 0.0f ); @@ -66,3 +67,11 @@ TEST_F( utStringUtils, ai_strtofTest ) { res = ai_strtof( begin, end ); EXPECT_FLOAT_EQ( res, 200.0f ); } + +TEST_F(utStringUtils, ai_rgba2hexTest) { + std::string result; + result = ai_rgba2hex(255, 255, 255, 255, true); + EXPECT_EQ(result, "#ffffffff"); + result = ai_rgba2hex(0, 0, 0, 0, false); + EXPECT_EQ(result, "00000000"); +} diff --git a/tools/assimp_cmd/ImageExtractor.cpp b/tools/assimp_cmd/ImageExtractor.cpp index 58aa42fa8..105c4fe37 100644 --- a/tools/assimp_cmd/ImageExtractor.cpp +++ b/tools/assimp_cmd/ImageExtractor.cpp @@ -130,8 +130,9 @@ int SaveAsBMP(FILE *file, const aiTexel *data, unsigned int width, unsigned int s[0] = t->b; s[1] = t->g; s[2] = t->r; - if (4 == numc) + if (4 == numc) { s[3] = t->a; + } } } @@ -296,7 +297,7 @@ int Assimp_Extract(const char *const *params, unsigned int num) { // check whether the requested texture is existing if (texIdx >= scene->mNumTextures) { - ::printf("assimp extract: Texture %i requested, but there are just %i textures\n", + ::printf("assimp extract: Texture %u requested, but there are just %i textures\n", texIdx, scene->mNumTextures); return AssimpCmdExtractError::TextureIndexIsOutOfRange; } @@ -325,7 +326,7 @@ int Assimp_Extract(const char *const *params, unsigned int num) { // if the texture is a compressed one, we'll export // it to its native file format if (!tex->mHeight) { - printf("assimp extract: Texture %i is compressed (%s). Writing native file format.\n", + printf("assimp extract: Texture %u is compressed (%s). Writing native file format.\n", i, tex->achFormatHint); // modify file extension @@ -350,7 +351,7 @@ int Assimp_Extract(const char *const *params, unsigned int num) { } ::fclose(p); - printf("assimp extract: Wrote texture %i to %s\n", i, out_cpy.c_str()); + printf("assimp extract: Wrote texture %u to %s\n", i, out_cpy.c_str()); if (texIdx != 0xffffffff) { return m; } diff --git a/tools/assimp_view/Material.cpp b/tools/assimp_view/Material.cpp index 8141fb58c..bcc93011e 100644 --- a/tools/assimp_view/Material.cpp +++ b/tools/assimp_view/Material.cpp @@ -272,7 +272,7 @@ bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString) szExtFound - 1 - info.cFileName); for (unsigned int i = 0; i < iSizeFound;++i) - info.cFileName[i] = (CHAR)tolower(info.cFileName[i]); + info.cFileName[i] = (CHAR)tolower((unsigned char)info.cFileName[i]); if (0 == memcmp(info.cFileName,szFile2, std::min(iSizeFound,iSize))) { @@ -354,7 +354,7 @@ int CMaterialManager::FindValidPath(aiString* p_szString) for (unsigned int i = 0;;++i) { if ('\0' == szTemp[i])break; - szTemp[i] = (char)tolower(szTemp[i]); + szTemp[i] = (char)tolower((unsigned char)szTemp[i]); } if(TryLongerPath(szTemp,p_szString))return 1;