Przeglądaj źródła

Merge pull request #3558 from JLouis-B/3mf-improvements

3mf improvements
Kim Kulling 4 lat temu
rodzic
commit
ccc0a50d96

+ 3 - 0
code/AssetLib/3MF/3MFXmlTags.h

@@ -55,6 +55,8 @@ namespace XmlTag {
     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";
@@ -67,6 +69,7 @@ namespace XmlTag {
     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";

+ 14 - 29
code/AssetLib/3MF/D3MFExporter.cpp

@@ -137,7 +137,7 @@ bool D3MFExporter::exportContentTypes() {
     mContentOutput << std::endl;
     mContentOutput << "</Types>";
     mContentOutput << std::endl;
-    exportContentTyp(XmlTag::CONTENT_TYPES_ARCHIVE);
+    zipContentType(XmlTag::CONTENT_TYPES_ARCHIVE);
 
     return true;
 }
@@ -162,7 +162,7 @@ bool D3MFExporter::exportRelations() {
     mRelOutput << "</Relationships>";
     mRelOutput << std::endl;
 
-    writeRelInfoToFile("_rels", ".rels");
+    zipRelInfo("_rels", ".rels");
     mRelOutput.flush();
 
     return true;
@@ -196,7 +196,7 @@ bool D3MFExporter::export3DModel() {
     info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
     mRelations.push_back(info);
 
-    writeModelToArchive("3D", "3DModel.model");
+    zipModel("3D", "3DModel.model");
     mModelOutput.flush();
 
     return true;
@@ -357,42 +357,27 @@ void D3MFExporter::writeBuild() {
     mModelOutput << std::endl;
 }
 
-void D3MFExporter::exportContentTyp(const std::string &filename) {
-    if (nullptr == m_zipArchive) {
-        throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
-    }
-    const std::string entry = filename;
-    zip_entry_open(m_zipArchive, entry.c_str());
-
-    const std::string &exportTxt(mContentOutput.str());
-    zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
-
-    zip_entry_close(m_zipArchive);
+void D3MFExporter::zipContentType(const std::string &filename) {
+    addFileInZip(filename, mContentOutput.str());
 }
 
-void D3MFExporter::writeModelToArchive(const std::string &folder, const std::string &modelName) {
-    if (nullptr == m_zipArchive) {
-        throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
-    }
+void D3MFExporter::zipModel(const std::string &folder, const std::string &modelName) {
     const std::string entry = folder + "/" + modelName;
-    zip_entry_open(m_zipArchive, entry.c_str());
-
-    const std::string &exportTxt(mModelOutput.str());
-    zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
+    addFileInZip(entry, mModelOutput.str());
+}
 
-    zip_entry_close(m_zipArchive);
+void D3MFExporter::zipRelInfo(const std::string &folder, const std::string &relName) {
+    const std::string entry = folder + "/" + relName;
+    addFileInZip(entry, mRelOutput.str());
 }
 
-void D3MFExporter::writeRelInfoToFile(const std::string &folder, const std::string &relName) {
+void D3MFExporter::addFileInZip(const std::string& entry, const std::string& content) {
     if (nullptr == m_zipArchive) {
         throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
     }
-    const std::string entry = folder + "/" + relName;
-    zip_entry_open(m_zipArchive, entry.c_str());
-
-    const std::string &exportTxt(mRelOutput.str());
-    zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
 
+    zip_entry_open(m_zipArchive, entry.c_str());
+    zip_entry_write(m_zipArchive, content.c_str(), content.size());
     zip_entry_close(m_zipArchive);
 }
 

+ 6 - 3
code/AssetLib/3MF/D3MFExporter.h

@@ -82,9 +82,12 @@ protected:
     void writeVertex( const aiVector3D &pos );
     void writeFaces( aiMesh *mesh, unsigned int matIdx );
     void writeBuild();
-    void exportContentTyp( const std::string &filename );
-    void writeModelToArchive( const std::string &folder, const std::string &modelName );
-    void writeRelInfoToFile( const std::string &folder, const std::string &relName );
+
+    // Zip the data
+    void zipContentType( const std::string &filename );
+    void zipModel( const std::string &folder, const std::string &modelName );
+    void zipRelInfo( const std::string &folder, const std::string &relName );
+    void addFileInZip( const std::string &entry, const std::string &content );
 
 private:
     std::string mArchiveName;

+ 298 - 125
code/AssetLib/3MF/D3MFImporter.cpp

@@ -66,22 +66,79 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace D3MF {
 
+enum class ResourceType {
+    RT_Object,
+    RT_BaseMaterials,
+    RT_Unknown
+}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
+
+class Resource
+{
+public:
+    Resource(int id) :
+            mId(id) {}
+
+    virtual ~Resource() {}
+
+    int mId;
+
+    virtual ResourceType getType() {
+        return ResourceType::RT_Unknown;
+    }
+};
+
+class BaseMaterials : public Resource {
+public:
+    BaseMaterials(int id) :
+            Resource(id),
+            mMaterials(),
+            mMaterialIndex() {}
+
+    std::vector<aiMaterial *> mMaterials;
+    std::vector<unsigned int> mMaterialIndex;
+
+    virtual ResourceType getType() {
+        return ResourceType::RT_BaseMaterials;
+    }
+};
+
+struct Component {
+    int mObjectId;
+    aiMatrix4x4 mTransformation;
+};
+
+class Object : public Resource {
+public:
+    std::vector<aiMesh*> mMeshes;
+    std::vector<unsigned int> mMeshIndex;
+    std::vector<Component> mComponents;
+    std::string mName;
+
+    Object(int id) :
+            Resource(id),
+            mName (std::string("Object_") + to_string(id)){}
+
+    virtual ResourceType getType() {
+        return ResourceType::RT_Object;
+    }
+};
+
+
 class XmlSerializer {
 public:
-    using MatArray = std::vector<aiMaterial *>;
-    using MatId2MatArray = std::map<unsigned int, std::vector<unsigned int>>;
 
     XmlSerializer(XmlParser *xmlParser) :
-            mMeshes(),
-            mMatArray(),
-            mActiveMatGroup(99999999),
-            mMatId2MatArray(),
+            mResourcesDictionnary(),
+            mMaterialCount(0),
+            mMeshCount(0),
             mXmlParser(xmlParser) {
         // empty
     }
 
     ~XmlSerializer() {
-        // empty
+        for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
+            delete it->second;
+        }
     }
 
     void ImportXml(aiScene *scene) {
@@ -89,10 +146,8 @@ public:
             return;
         }
 
-        scene->mRootNode = new aiNode();
-        std::vector<aiNode *> children;
+        scene->mRootNode = new aiNode("3MF");
 
-        std::string nodeName;
         XmlNode node = mXmlParser->getRootNode().child("model");
         if (node.empty()) {
             return;
@@ -101,9 +156,7 @@ public:
         for (XmlNode currentNode = resNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
             const std::string &currentNodeName = currentNode.name();
             if (currentNodeName == D3MF::XmlTag::object) {
-                children.push_back(ReadObject(currentNode, scene));
-            } else if (currentNodeName == D3MF::XmlTag::build) {
-                //
+                ReadObject(currentNode);;
             } else if (currentNodeName == D3MF::XmlTag::basematerials) {
                 ReadBaseMaterials(currentNode);
             } else if (currentNodeName == D3MF::XmlTag::meta) {
@@ -111,10 +164,29 @@ public:
             }
         }
 
-        if (scene->mRootNode->mName.length == 0) {
-            scene->mRootNode->mName.Set("3MF");
+        XmlNode buildNode = node.child("build");
+        for (XmlNode currentNode = buildNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
+            const std::string &currentNodeName = currentNode.name();
+            if (currentNodeName == D3MF::XmlTag::item) {
+                int objectId = -1;
+                std::string transformationMatrixStr;
+                aiMatrix4x4 transformationMatrix;
+                getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
+                bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
+
+                auto it = mResourcesDictionnary.find(objectId);
+                if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
+                    Object *obj = static_cast<Object *>(it->second);
+                    if (hasTransform) {
+                        transformationMatrix = parseTransformMatrix(transformationMatrixStr);
+                    }
+
+                    addObjectToNode(scene->mRootNode, obj, transformationMatrix);
+                }
+            }
         }
 
+
         // import the metadata
         if (!mMetaData.empty()) {
             const size_t numMeta(mMetaData.size());
@@ -126,66 +198,177 @@ public:
         }
 
         // import the meshes
-        scene->mNumMeshes = static_cast<unsigned int>(mMeshes.size());
-        scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
-        std::copy(mMeshes.begin(), mMeshes.end(), scene->mMeshes);
+        scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
+        if (scene->mNumMeshes != 0) {
+            scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
+            for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
+                if (it->second->getType() == ResourceType::RT_Object) {
+                    Object *obj = static_cast<Object*>(it->second);
+                    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<unsigned int>(mMatArray.size());
-        if (0 != scene->mNumMaterials) {
+        scene->mNumMaterials = static_cast<unsigned int>(mMaterialCount);
+        if (scene->mNumMaterials != 0) {
             scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
-            std::copy(mMatArray.begin(), mMatArray.end(), scene->mMaterials);
+            for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
+                if (it->second->getType() == ResourceType::RT_BaseMaterials) {
+                    BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
+                    for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) {
+                        scene->mMaterials[baseMaterials->mMaterialIndex[i]] = baseMaterials->mMaterials[i];
+                    }
+                }
+            }
         }
-
-        // create the scene-graph
-        scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
-        scene->mRootNode->mChildren = new aiNode *[scene->mRootNode->mNumChildren]();
-        std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
     }
 
 private:
-    aiNode *ReadObject(XmlNode &node, aiScene *scene) {
-        std::unique_ptr<aiNode> nodePtr(new aiNode());
 
-        std::vector<unsigned long> meshIds;
+    void addObjectToNode(aiNode* parent, Object* obj, aiMatrix4x4 nodeTransform) {
+        aiNode *sceneNode = new aiNode(obj->mName);
+        sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
+        sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
+        std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
+
+        sceneNode->mTransformation = nodeTransform;
 
-        std::string name, type;
-        pugi::xml_attribute attr = node.attribute(D3MF::XmlTag::id.c_str());
-        if (!attr.empty()) {
-            name = attr.as_string();
+        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<Object*>(it->second), c.mTransformation);
+            }
+            
         }
-        attr = node.attribute(D3MF::XmlTag::type.c_str());
-        if (!attr.empty()) {
-            type = attr.as_string();
+    }
+
+    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;
+        }
+    }
+
+    bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
+        std::string strValue;
+        bool ret = getNodeAttribute(node, attribute, strValue);
+        if (ret) {
+            value = std::atoi(strValue.c_str());
+            return true;
+        } else {
+            return false;
         }
+    }
 
-        nodePtr->mParent = scene->mRootNode;
-        nodePtr->mName.Set(name);
+    aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
+        // split the string
+        std::vector<float> numbers;
+        std::string currentNumber;
+        for (size_t i = 0; i < matrixStr.size(); ++i) {
+            const char c = matrixStr[i];
+            if (c == ' ') {
+                if (currentNumber.size() > 0) {
+                    float f = std::stof(currentNumber);
+                    numbers.push_back(f);
+                    currentNumber.clear();
+                }
+            } else {
+                currentNumber.push_back(c);
+            }
+        }
+        if (currentNumber.size() > 0) {
+            float f = std::stof(currentNumber);
+            numbers.push_back(f);
+        }
+
+        aiMatrix4x4 transformMatrix;
+        transformMatrix.a1 = numbers[0];
+        transformMatrix.b1 = numbers[1];
+        transformMatrix.c1 = numbers[2];
+        transformMatrix.d1 = 0;
+
+        transformMatrix.a2 = numbers[3];
+        transformMatrix.b2 = numbers[4];
+        transformMatrix.c2 = numbers[5];
+        transformMatrix.d2 = 0;
+
+        transformMatrix.a3 = numbers[6];
+        transformMatrix.b3 = numbers[7];
+        transformMatrix.c3 = numbers[8];
+        transformMatrix.d3 = 0;
+
+        transformMatrix.a4 = numbers[9];
+        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 = to_string(id);
+
+        if (!hasId) {
+            return;
+        }
 
-        size_t meshIdx = mMeshes.size();
+        Object *obj = new Object(id);
 
         for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
             const std::string &currentName = currentNode.name();
             if (currentName == D3MF::XmlTag::mesh) {
                 auto mesh = ReadMesh(currentNode);
-                mesh->mName.Set(name);
-                mMeshes.push_back(mesh);
-                meshIds.push_back(static_cast<unsigned long>(meshIdx));
-                ++meshIdx;
+                mesh->mName.Set(idStr);
+
+                if (hasPid) {
+                    auto it = mResourcesDictionnary.find(pid);
+                    if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
+                        BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
+                        mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
+                    }
+                }
+
+                obj->mMeshes.push_back(mesh);
+                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) {
+                        int objectId = -1;
+                        std::string componentTransformStr;
+                        aiMatrix4x4 componentTransform;
+                        if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
+                            componentTransform = parseTransformMatrix(componentTransformStr);
+                        }
+
+                        if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId))
+                            obj->mComponents.push_back({ objectId, componentTransform });
+                    }
+                }
             }
         }
 
-        nodePtr->mNumMeshes = static_cast<unsigned int>(meshIds.size());
-
-        nodePtr->mMeshes = new unsigned int[nodePtr->mNumMeshes];
-
-        std::copy(meshIds.begin(), meshIds.end(), nodePtr->mMeshes);
-
-        return nodePtr.release();
+        mResourcesDictionnary.insert(std::make_pair(id, obj));
     }
 
     aiMesh *ReadMesh(XmlNode &node) {
         aiMesh *mesh = new aiMesh();
+
         for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
             const std::string &currentName = currentNode.name();
             if (currentName == D3MF::XmlTag::vertices) {
@@ -241,11 +424,23 @@ private:
         for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
             const std::string &currentName = currentNode.name();
             if (currentName == D3MF::XmlTag::triangle) {
-                faces.push_back(ReadTriangle(currentNode));
-                const char *pidToken = currentNode.attribute(D3MF::XmlTag::p1.c_str()).as_string();
-                if (nullptr != pidToken) {
-                    int matIdx(std::atoi(pidToken));
-                    mesh->mMaterialIndex = matIdx;
+                aiFace face = ReadTriangle(currentNode);
+                faces.push_back(face);
+
+                int pid, p1;
+                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->second->getType() == ResourceType::RT_BaseMaterials) {
+                            BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
+                            mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
+                        }
+                        // TODO: manage the separation into several meshes if the triangles of the mesh do not all refer to the same material
+                    }
                 }
             }
         }
@@ -270,26 +465,21 @@ private:
     }
 
     void ReadBaseMaterials(XmlNode &node) {
-        std::vector<unsigned int> MatIdArray;
-        const char *baseMaterialId = node.attribute(D3MF::XmlTag::basematerials_id.c_str()).as_string();
-        if (nullptr != baseMaterialId) {
-            unsigned int id = std::atoi(baseMaterialId);
-            const size_t newMatIdx(mMatArray.size());
-            if (id != mActiveMatGroup) {
-                mActiveMatGroup = id;
-                MatId2MatArray::const_iterator it(mMatId2MatArray.find(id));
-                if (mMatId2MatArray.end() == it) {
-                    MatIdArray.clear();
-                    mMatId2MatArray[id] = MatIdArray;
-                } else {
-                    MatIdArray = it->second;
+        int id = -1;
+        if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
+            BaseMaterials* baseMaterials = new BaseMaterials(id);
+
+            for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling())
+            {
+                if (currentNode.name() == D3MF::XmlTag::basematerials_base) {
+                    baseMaterials->mMaterialIndex.push_back(mMaterialCount);
+                    baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
+                    mMaterialCount++;
                 }
             }
-            MatIdArray.push_back(static_cast<unsigned int>(newMatIdx));
-            mMatId2MatArray[mActiveMatGroup] = MatIdArray;
-        }
 
-        mMatArray.push_back(readMaterialDef(node));
+            mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
+        }
     }
 
     bool parseColor(const char *color, aiColor4D &diffuse) {
@@ -304,37 +494,24 @@ private:
         }
 
         const char *buf(color);
-        if ('#' != *buf) {
+        if ('#' != buf[0]) {
             return false;
         }
-        ++buf;
-        char comp[3] = { 0, 0, '\0' };
-
-        comp[0] = *buf;
-        ++buf;
-        comp[1] = *buf;
-        ++buf;
-        diffuse.r = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
-
-        comp[0] = *buf;
-        ++buf;
-        comp[1] = *buf;
-        ++buf;
-        diffuse.g = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
-
-        comp[0] = *buf;
-        ++buf;
-        comp[1] = *buf;
-        ++buf;
-        diffuse.b = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
+
+        char r[3] = { buf[1], buf[2], '\0' };
+        diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
+
+        char g[3] = { buf[3], buf[4], '\0' };
+        diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
+
+        char b[3] = { buf[5], buf[6], '\0' };
+        diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
 
         if (7 == len)
             return true;
-        comp[0] = *buf;
-        ++buf;
-        comp[1] = *buf;
-        ++buf;
-        diffuse.a = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
+
+        char a[3] = { buf[7], buf[8], '\0' };
+        diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
 
         return true;
     }
@@ -347,32 +524,30 @@ private:
         }
     }
 
-    aiMaterial *readMaterialDef(XmlNode &node) {
-        aiMaterial *mat(nullptr);
-        const char *name(nullptr);
-        const std::string nodeName = node.name();
-        if (nodeName == D3MF::XmlTag::basematerials_base) {
-            name = node.attribute(D3MF::XmlTag::basematerials_name.c_str()).as_string();
-            std::string stdMatName;
-            aiString matName;
-            std::string strId(to_string(mActiveMatGroup));
-            stdMatName += "id";
-            stdMatName += strId;
-            stdMatName += "_";
-            if (nullptr != name) {
-                stdMatName += std::string(name);
-            } else {
-                stdMatName += "basemat";
-            }
-            matName.Set(stdMatName);
+    aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
+        aiMaterial *material = new aiMaterial();
+        material->mNumProperties = 0;
+        std::string name;
+        bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
+
+        std::string stdMaterialName;
+        std::string strId(to_string(basematerialsId));
+        stdMaterialName += "id";
+        stdMaterialName += strId;
+        stdMaterialName += "_";
+        if (hasName) {
+            stdMaterialName += std::string(name);
+        } else {
+            stdMaterialName += "basemat_";
+            stdMaterialName += to_string(mMaterialCount - basematerialsId);
+        }
 
-            mat = new aiMaterial;
-            mat->AddProperty(&matName, AI_MATKEY_NAME);
+        aiString assimpMaterialName(stdMaterialName);
+        material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
 
-            assignDiffuseColor(node, mat);
-        }
+        assignDiffuseColor(node, material);
 
-        return mat;
+        return material;
     }
 
 private:
@@ -381,10 +556,8 @@ private:
         std::string value;
     };
     std::vector<MetaEntry> mMetaData;
-    std::vector<aiMesh *> mMeshes;
-    MatArray mMatArray;
-    unsigned int mActiveMatGroup;
-    MatId2MatArray mMatId2MatArray;
+    std::map<unsigned int, Resource*> mResourcesDictionnary;
+    unsigned int mMaterialCount, mMeshCount;
     XmlParser *mXmlParser;
 };
 

+ 3 - 4
include/assimp/XmlParser.h

@@ -121,7 +121,6 @@ public:
             return false;
         }
 
-        bool result = false;
         const size_t len = stream->FileSize();
         mData.resize(len + 1);
         memset(&mData[0], '\0', len + 1);
@@ -130,11 +129,11 @@ public:
         mDoc = new pugi::xml_document();
         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.");
-            result = true;
+            return false;
         }
-
-        return result;
     }
 
     pugi::xml_document *getDocument() const {