Browse Source

Merge branch 'master' into jc3-cctype-fixes

Jason C 4 years ago
parent
commit
c08ad2e5c2

+ 33 - 26
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 <assimp/StringComparison.h>
 #include <assimp/StringUtils.h>
@@ -51,17 +53,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/IOSystem.hpp>
+#include <assimp/fast_atof.h>
+
 #include <cassert>
 #include <map>
 #include <memory>
 #include <string>
 #include <vector>
-
-#include "3MFXmlTags.h"
-#include "D3MFOpcPackage.h"
-#include <assimp/fast_atof.h>
-
 #include <iomanip>
+#include <string.h>
 
 namespace Assimp {
 namespace D3MF {
@@ -163,7 +163,7 @@ public:
         }
         XmlNode resNode = node.child(XmlTag::resources);
         for (auto &currentNode : resNode.children()) {
-            const std::string &currentNodeName = currentNode.name();
+            const std::string currentNodeName = currentNode.name();
             if (currentNodeName == XmlTag::object) {
                 ReadObject(currentNode);
             } else if (currentNodeName == XmlTag::basematerials) {
@@ -173,8 +173,9 @@ public:
             }
         }
 
-        for (auto &currentNode : resNode.children()) {
-            const std::string &currentNodeName = currentNode.name();
+        XmlNode buildNode = node.child(XmlTag::build);
+        for (auto &currentNode : buildNode.children()) {
+            const std::string currentNodeName = currentNode.name();
             if (currentNodeName == XmlTag::item) {
                 int objectId = -1;
                 std::string transformationMatrixStr;
@@ -196,7 +197,7 @@ 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<unsigned int>(numMeta));
             for (size_t i = 0; i < numMeta; ++i) {
                 aiString val(mMetaData[i].value);
@@ -211,6 +212,7 @@ public:
             for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
                 if (it->second->getType() == ResourceType::RT_Object) {
                     Object *obj = static_cast<Object *>(it->second);
+                    ai_assert(nullptr != obj);
                     for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
                         scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
                     }
@@ -352,7 +354,8 @@ private:
                 mMeshCount++;
             } else if (currentName == D3MF::XmlTag::components) {
                 for (XmlNode &currentSubNode : currentNode.children()) {
-                    if (currentSubNode.name() == D3MF::XmlTag::component) {
+                    const std::string subNodeName = currentSubNode.name();
+                    if (subNodeName == D3MF::XmlTag::component) {
                         int objectId = -1;
                         std::string componentTransformStr;
                         aiMatrix4x4 componentTransform;
@@ -360,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 });
+                        }
                     }
                 }
             }
@@ -374,7 +378,7 @@ private:
         aiMesh *mesh = new aiMesh();
 
         for (XmlNode &currentNode : node.children()) {
-            const std::string &currentName = currentNode.name();
+            const std::string currentName = currentNode.name();
             if (currentName == XmlTag::vertices) {
                 ImportVertices(currentNode, mesh);
             } else if (currentName == XmlTag::triangles) {
@@ -402,8 +406,8 @@ private:
     void ImportVertices(XmlNode &node, aiMesh *mesh) {
         std::vector<aiVector3D> vertices;
         for (XmlNode &currentNode : node.children()) {
-            const std::string &currentName = currentNode.name();
-            if (currentName == D3MF::XmlTag::vertex) {
+            const std::string currentName = currentNode.name();
+            if (currentName == XmlTag::vertex) {
                 vertices.push_back(ReadVertex(currentNode));
             }
         }
@@ -415,22 +419,22 @@ private:
 
     aiVector3D ReadVertex(XmlNode &node) {
         aiVector3D vertex;
-        vertex.x = ai_strtof(node.attribute(D3MF::XmlTag::x).as_string(), nullptr);
-        vertex.y = ai_strtof(node.attribute(D3MF::XmlTag::y).as_string(), nullptr);
-        vertex.z = ai_strtof(node.attribute(D3MF::XmlTag::z).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<aiFace> faces;
-        for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
-            const std::string &currentName = currentNode.name();
-            if (currentName == D3MF::XmlTag::triangle) {
+        for (XmlNode &currentNode : 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);
 
@@ -472,10 +476,11 @@ private:
             BaseMaterials *baseMaterials = new BaseMaterials(id);
 
             for (XmlNode &currentNode : node.children()) {
-                if (currentNode.name() == XmlTag::basematerials_base) {
+                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;
                 }
             }
 
@@ -564,6 +569,8 @@ private:
 
 } //namespace D3MF
 
+using namespace D3MF;
+
 static const aiImporterDesc desc = {
     "3mf Importer",
     "",
@@ -597,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();
     }
 
@@ -613,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);
     }
 }

+ 1 - 1
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;

+ 15 - 2
code/Common/ImporterRegistry.cpp

@@ -48,6 +48,7 @@ corresponding preprocessor flag to selectively disable formats.
 
 #include <assimp/BaseImporter.h>
 #include <vector>
+#include <cstdlib>
 
 // ------------------------------------------------------------------------------------------------
 // Importers
@@ -204,7 +205,17 @@ corresponding preprocessor flag to selectively disable formats.
 namespace Assimp {
 
 // ------------------------------------------------------------------------------------------------
-void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
+void GetImporterInstanceList(std::vector<BaseImporter *> &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<BaseImporter *> &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());

+ 3 - 3
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 <cstdlib>
 #include <locale>
 #include <sstream>
+#include <iomanip>
 
 #ifdef _MSC_VER
 #define AI_SIZEFMT "%Iu"
@@ -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,4 @@ AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) {
     return out;
 }
 
-#endif
+#endif // INCLUDED_AI_STRINGUTILS_H

BIN
test/test.3mf


+ 11 - 2
test/unit/utStringUtils.cpp

@@ -42,9 +42,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/StringUtils.h>
 
 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");
+}