Gorilux 9 rokov pred
rodič
commit
8f4f0047fb

+ 12 - 2
code/CMakeLists.txt

@@ -1,6 +1,6 @@
 # Open Asset Import Library (assimp)
 # ----------------------------------------------------------------------
-# 
+#
 # Copyright (c) 2006-2016, assimp team
 # All rights reserved.
 #
@@ -604,11 +604,21 @@ ADD_ASSIMP_IMPORTER(GLTF
 
   glTFImporter.cpp
   glTFImporter.h
-  
+
   glTFExporter.h
   glTFExporter.cpp
 )
 
+
+ADD_ASSIMP_IMPORTER(3MF
+    D3MFImporter.h
+    D3MFImporter.cpp
+    D3MFOpcPackage.h
+    D3MFOpcPackage.cpp
+
+)
+
+
 SET( Step_SRCS
   StepExporter.h
   StepExporter.cpp

+ 387 - 0
code/D3MFImporter.cpp

@@ -0,0 +1,387 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+#include "D3MFImporter.h"
+
+#include "../include/assimp/scene.h"
+#include "../contrib/unzip/unzip.h"
+#include "../include/assimp/IOStream.hpp"
+#include "../include/assimp/IOSystem.hpp"
+#include "../include/assimp/DefaultLogger.hpp"
+#include "irrXMLWrapper.h"
+#include "StringComparison.h"
+
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <memory>
+
+#include "../include/assimp/ai_assert.h"
+
+#include "D3MFOpcPackage.h"
+
+#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
+
+namespace Assimp {
+
+namespace D3MF {
+
+
+namespace XmlTag {
+
+    const std::string model     = "model";
+    const std::string metadata  = "metadata";
+    const std::string resources = "resources";
+    const std::string object    = "object";
+    const std::string mesh      = "mesh";
+    const std::string vertices  = "vertices";
+    const std::string vertex    = "vertex";
+    const std::string triangles = "triangles";
+    const std::string triangle  = "triangle";
+    const std::string x         = "x";
+    const std::string y         = "y";
+    const std::string z         = "z";
+    const std::string v1        = "v1";
+    const std::string v2        = "v2";
+    const std::string v3        = "v3";
+    const std::string id        = "id";
+    const std::string name      = "name";
+    const std::string type      = "type";
+    const std::string build     = "build";
+    const std::string item      = "item";
+    const std::string objectid  = "objectid";
+    const std::string transform = "transform";
+
+}
+
+
+class XmlSerializer
+{
+public:
+    XmlSerializer(XmlReader* xmlReader)
+        : xmlReader(xmlReader)
+    {
+
+    }
+
+    void ImportXml(aiScene* scene)
+    {
+
+        scene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
+
+        scene->mRootNode = new aiNode();
+        std::vector<aiNode*> children;
+
+        while(ReadToEndElement(D3MF::XmlTag::model))
+        {         
+
+            if(xmlReader->getNodeName() == D3MF::XmlTag::object)
+            {
+                children.push_back(ReadObject(scene));
+            }
+            else if(xmlReader->getNodeName() == D3MF::XmlTag::build)
+            {
+
+            }
+        }        
+
+        if(scene->mRootNode->mName.length == 0)
+            scene->mRootNode->mName.Set("3MF");
+
+
+        scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
+        scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
+
+        std::copy(meshes.begin(), meshes.end(), scene->mMeshes);
+
+        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(aiScene* scene)
+    {        
+        ScopeGuard<aiNode> node(new aiNode());
+
+        std::vector<unsigned long> meshIds;
+
+        int id = std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::id.c_str()));
+        std::string name(xmlReader->getAttributeValue(D3MF::XmlTag::name.c_str()));
+        std::string type(xmlReader->getAttributeValue(D3MF::XmlTag::type.c_str()));
+
+        node->mParent = scene->mRootNode;
+        node->mName.Set(name);        
+
+        unsigned long meshIdx = meshes.size();
+
+        while(ReadToEndElement(D3MF::XmlTag::object))
+        {
+            if(xmlReader->getNodeName() == D3MF::XmlTag::mesh)
+            {                
+                auto mesh = ReadMesh();
+
+                mesh->mName.Set(name);
+                meshes.push_back(mesh);
+                meshIds.push_back(meshIdx);
+                meshIdx++;
+
+            }
+        }
+
+        node->mNumMeshes = static_cast<unsigned int>(meshIds.size());
+
+        node->mMeshes = new unsigned int[node->mNumMeshes];
+
+        std::copy(meshIds.begin(), meshIds.end(), node->mMeshes);
+
+        return node.dismiss();
+
+    }
+
+    aiMesh* ReadMesh()
+    {
+        aiMesh* mesh = new aiMesh();
+
+        while(ReadToEndElement(D3MF::XmlTag::mesh))
+        {            
+            if(xmlReader->getNodeName() == D3MF::XmlTag::vertices)
+            {
+                ImportVertices(mesh);
+            }
+            else if(xmlReader->getNodeName() == D3MF::XmlTag::triangles)
+            {
+                ImportTriangles(mesh);
+            }
+
+        }
+
+
+        return mesh;
+    }
+
+    void ImportVertices(aiMesh* mesh)
+    {
+        std::vector<aiVector3D> vertices;        
+
+        while(ReadToEndElement(D3MF::XmlTag::vertices))
+        {                        
+            if(xmlReader->getNodeName() == D3MF::XmlTag::vertex)
+            {                
+                vertices.push_back(ReadVertex());
+            }
+        }
+        mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
+        mesh->mVertices = new aiVector3D[mesh->mNumVertices];
+
+        std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
+
+    }
+    aiVector3D ReadVertex()
+    {        
+        aiVector3D vertex;
+        vertex.x = std::strtof(xmlReader->getAttributeValue(D3MF::XmlTag::x.c_str()), nullptr);
+        vertex.y = std::strtof(xmlReader->getAttributeValue(D3MF::XmlTag::y.c_str()), nullptr);
+        vertex.z = std::strtof(xmlReader->getAttributeValue(D3MF::XmlTag::z.c_str()), nullptr);        
+
+        return vertex;
+    }
+
+    void ImportTriangles(aiMesh* mesh)
+    {
+         std::vector<aiFace> faces;         
+
+
+         while(ReadToEndElement(D3MF::XmlTag::triangles))
+         {
+             if(xmlReader->getNodeName() == D3MF::XmlTag::triangle)
+             {
+                 faces.push_back(ReadTriangle());
+             }
+         }
+
+        mesh->mNumFaces = static_cast<unsigned int>(faces.size());
+        mesh->mFaces = new aiFace[mesh->mNumFaces];
+        mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
+
+
+        std::copy(faces.begin(), faces.end(), mesh->mFaces);
+
+    }
+
+    aiFace ReadTriangle()
+    {
+        aiFace face;
+
+        face.mNumIndices = 3;
+        face.mIndices = new unsigned int[face.mNumIndices];
+        face.mIndices[0] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v1.c_str())));
+        face.mIndices[1] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v2.c_str())));
+        face.mIndices[2] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v3.c_str())));
+
+        return face;
+    }
+
+private:
+
+    bool ReadToStartElement(const std::string& startTag)
+    {
+        while(xmlReader->read())
+        {
+            if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && xmlReader->getNodeName() == startTag)
+            {
+                return true;
+            }
+            else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END &&
+                     xmlReader->getNodeName() == startTag)
+            {
+                return false;
+            }
+        }
+        //DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag");
+        return false;
+    }
+
+    bool ReadToEndElement(const std::string& closeTag)
+    {
+        while(xmlReader->read())
+        {
+            if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT) {
+                return true;
+            }
+            else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END
+                     && xmlReader->getNodeName() == closeTag)
+            {
+                return false;
+            }
+        }
+        DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag");
+        return false;
+    }
+
+
+private:
+    std::vector<aiMesh*> meshes;
+    XmlReader* xmlReader;
+
+
+};
+
+} //namespace D3MF
+
+
+static const aiImporterDesc desc = {
+    "3mf Importer",
+    "",
+    "",
+    "http://3mf.io/",
+    aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour,
+    0,
+    0,
+    0,
+    0,
+    "3mf"
+};
+
+
+D3MFImporter::D3MFImporter()
+{
+
+}
+
+D3MFImporter::~D3MFImporter()
+{
+
+}
+
+bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const
+{    
+    const std::string extension = GetExtension(pFile);
+
+    if(extension == "3mf")
+    {
+        return true;
+    }
+    else if(!extension.length() || checkSig)
+    {
+        if(!pIOHandler)
+            return true;
+    }
+
+    return false;
+}
+
+void D3MFImporter::SetupProperties(const Importer *pImp)
+{
+
+}
+
+const aiImporterDesc *D3MFImporter::GetInfo() const
+{
+    return &desc;
+}
+
+void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler)
+{
+
+
+    D3MF::D3MFOpcPackage opcPackage(pIOHandler, pFile);
+
+    std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream()));
+    std::unique_ptr<D3MF::XmlReader> xmlReader(irr::io::createIrrXMLReader(xmlStream.get()));
+
+    D3MF::XmlSerializer xmlSerializer(xmlReader.get());
+
+
+    xmlSerializer.ImportXml(pScene);
+
+
+}
+
+}
+
+#endif // ASSIMP_BUILD_NO_3MF_IMPORTER

+ 68 - 0
code/D3MFImporter.h

@@ -0,0 +1,68 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+#ifndef AI_D3MFLOADER_H_INCLUDED
+#define AI_D3MFLOADER_H_INCLUDED
+
+#include <vector>
+#include <cstdint>
+
+#include "BaseImporter.h"
+
+namespace Assimp {
+
+class D3MFImporter : public BaseImporter
+{
+public:
+    D3MFImporter();
+    ~D3MFImporter();
+
+    // BaseImporter interface
+public:
+    bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
+    void SetupProperties(const Importer *pImp) override;
+    const aiImporterDesc *GetInfo() const override;
+
+protected:
+    void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
+
+};
+}
+#endif // AI_D3MFLOADER_H_INCLUDED

+ 599 - 0
code/D3MFOpcPackage.cpp

@@ -0,0 +1,599 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+
+#include "D3MFOpcPackage.h"
+
+#include <memory>
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+
+
+#include "../contrib/unzip/unzip.h"
+#include "../include/assimp/IOStream.hpp"
+#include "../include/assimp/IOSystem.hpp"
+#include "../include/assimp/DefaultLogger.hpp"
+
+
+#include "../include/assimp/ai_assert.h"
+
+#include "Exceptional.h"
+
+
+
+#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
+
+namespace Assimp {
+
+namespace D3MF {
+
+
+
+namespace XmlTag {
+
+const std::string CONTENT_TYPES_ARCHIVE  = "[Content_Types].xml";
+const std::string ROOT_RELATIONSHIPS_ARCHIVE  = "_rels/.rels";
+const std::string SCHEMA_CONTENTTYPES         = "http://schemas.openxmlformats.org/package/2006/content-types";
+const std::string SCHEMA_RELATIONSHIPS        = "http://schemas.openxmlformats.org/package/2006/relationships";
+const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships";
+const std::string RELS_RELATIONSHIP_NODE      = "Relationship";
+const std::string RELS_ATTRIB_TARGET         = "Target";
+const std::string RELS_ATTRIB_TYPE            = "Type";
+const std::string RELS_ATTRIB_ID              = "Id";
+const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
+const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
+const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
+const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
+const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
+
+
+}
+
+class IOSystem2Unzip {
+
+    public:
+
+        static voidpf open(voidpf opaque, const char* filename, int mode);
+
+        static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size);
+
+        static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size);
+
+        static long tell(voidpf opaque, voidpf stream);
+
+        static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
+
+        static int close(voidpf opaque, voidpf stream);
+
+        static int testerror(voidpf opaque, voidpf stream);
+
+        static zlib_filefunc_def get(IOSystem* pIOHandler);
+};
+
+voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) {
+    IOSystem* io_system = reinterpret_cast<IOSystem*>(opaque);
+
+    const char* mode_fopen = NULL;
+    if((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) {
+        mode_fopen = "rb";
+    } else {
+        if(mode & ZLIB_FILEFUNC_MODE_EXISTING) {
+            mode_fopen = "r+b";
+        } else {
+            if(mode & ZLIB_FILEFUNC_MODE_CREATE) {
+                mode_fopen = "wb";
+            }
+        }
+    }
+
+
+    return (voidpf) io_system->Open(filename, mode_fopen);
+}
+
+uLong IOSystem2Unzip::read(voidpf /*opaque*/, voidpf stream, void* buf, uLong size) {
+    IOStream* io_stream = (IOStream*) stream;
+
+    return io_stream->Read(buf, 1, size);
+}
+
+uLong IOSystem2Unzip::write(voidpf /*opaque*/, voidpf stream, const void* buf, uLong size) {
+    IOStream* io_stream = (IOStream*) stream;
+
+    return io_stream->Write(buf, 1, size);
+}
+
+long IOSystem2Unzip::tell(voidpf /*opaque*/, voidpf stream) {
+    IOStream* io_stream = (IOStream*) stream;
+
+    return io_stream->Tell();
+}
+
+long IOSystem2Unzip::seek(voidpf /*opaque*/, voidpf stream, uLong offset, int origin) {
+    IOStream* io_stream = (IOStream*) stream;
+
+    aiOrigin assimp_origin;
+    switch (origin) {
+        default:
+        case ZLIB_FILEFUNC_SEEK_CUR:
+            assimp_origin = aiOrigin_CUR;
+            break;
+        case ZLIB_FILEFUNC_SEEK_END:
+            assimp_origin = aiOrigin_END;
+            break;
+        case ZLIB_FILEFUNC_SEEK_SET:
+            assimp_origin = aiOrigin_SET;
+            break;
+    }
+
+    return (io_stream->Seek(offset, assimp_origin) == aiReturn_SUCCESS ? 0 : -1);
+}
+
+int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
+    IOSystem* io_system = (IOSystem*) opaque;
+    IOStream* io_stream = (IOStream*) stream;
+
+    io_system->Close(io_stream);
+
+    return 0;
+}
+
+int IOSystem2Unzip::testerror(voidpf /*opaque*/, voidpf /*stream*/) {
+    return 0;
+}
+
+zlib_filefunc_def IOSystem2Unzip::get(IOSystem* pIOHandler) {
+    zlib_filefunc_def mapping;
+
+    mapping.zopen_file = open;
+    mapping.zread_file = read;
+    mapping.zwrite_file = write;
+    mapping.ztell_file = tell;
+    mapping.zseek_file = seek;
+    mapping.zclose_file = close;
+    mapping.zerror_file = testerror;
+    mapping.opaque = reinterpret_cast<voidpf>(pIOHandler);
+
+    return mapping;
+}
+
+
+class ZipFile : public IOStream
+{
+    friend class D3MFZipArchive;
+
+public:
+    explicit ZipFile(size_t size);
+
+    ~ZipFile();
+
+    size_t Read(void* pvBuffer, size_t pSize, size_t pCount );
+
+    size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/);
+
+    size_t FileSize() const;
+
+    aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/);
+
+    size_t Tell() const;
+
+    void Flush();
+
+private:
+
+    void* m_Buffer;
+
+    size_t m_Size;
+
+};
+
+ZipFile::ZipFile(size_t size) : m_Size(size) {
+    ai_assert(m_Size != 0);
+
+    m_Buffer = malloc(m_Size);
+}
+
+ZipFile::~ZipFile() {
+    free(m_Buffer);
+    m_Buffer = NULL;
+}
+
+size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) {
+    const size_t size = pSize * pCount;
+    assert(size <= m_Size);
+
+    std::memcpy(pvBuffer, m_Buffer, size);
+
+    return size;
+}
+
+size_t ZipFile::Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) {
+    return 0;
+}
+
+size_t ZipFile::FileSize() const {
+    return m_Size;
+}
+
+aiReturn ZipFile::Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) {
+    return aiReturn_FAILURE;
+}
+
+size_t ZipFile::Tell() const {
+    return 0;
+}
+
+void ZipFile::Flush() {
+    // empty
+}
+
+
+class D3MFZipArchive : public IOSystem
+{
+public:
+
+    static const unsigned int FileNameSize = 256;
+
+public:
+
+    D3MFZipArchive(IOSystem* pIOHandler, const std::string & rFile);
+
+    ~D3MFZipArchive();
+
+    bool Exists(const char* pFile) const;
+
+    char getOsSeparator() const;
+
+    IOStream* Open(const char* pFile, const char* pMode = "rb");
+
+    void Close(IOStream* pFile);
+
+    bool isOpen() const;
+
+    void getFileList(std::vector<std::string> &rFileList);
+
+private:
+
+    bool mapArchive();
+
+private:
+
+    unzFile m_ZipFileHandle;
+
+    std::map<std::string, ZipFile*> m_ArchiveMap;
+
+};
+
+
+// ------------------------------------------------------------------------------------------------
+//  Constructor.
+D3MFZipArchive::D3MFZipArchive(IOSystem* pIOHandler, const std::string& rFile)
+    : m_ZipFileHandle(NULL), m_ArchiveMap()
+{
+    if (! rFile.empty())
+    {                
+        zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);            
+
+        m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping);
+
+        if(m_ZipFileHandle != NULL) {            
+            mapArchive();
+        }
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+//  Destructor.
+D3MFZipArchive::~D3MFZipArchive() {
+    for( std::map<std::string, ZipFile*>::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it ) {
+        delete it->second;
+    }
+    m_ArchiveMap.clear();
+
+    if(m_ZipFileHandle != NULL) {
+        unzClose(m_ZipFileHandle);
+        m_ZipFileHandle = NULL;
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+//  Returns true, if the archive is already open.
+bool D3MFZipArchive::isOpen() const {
+    return (m_ZipFileHandle != NULL);
+}
+
+// ------------------------------------------------------------------------------------------------
+//  Returns true, if the filename is part of the archive.
+bool D3MFZipArchive::Exists(const char* pFile) const {
+    ai_assert(pFile != NULL);
+
+    bool exist = false;
+
+    if (pFile != NULL) {
+        std::string rFile(pFile);
+        std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile);
+
+        if(it != m_ArchiveMap.end()) {
+            exist = true;
+        }
+    }
+
+    return exist;
+}
+
+// ------------------------------------------------------------------------------------------------
+//  Returns the separator delimiter.
+char D3MFZipArchive::getOsSeparator() const {
+#ifndef _WIN32
+    return '/';
+#else
+    return '\\';
+#endif
+}
+
+// ------------------------------------------------------------------------------------------------
+//  Opens a file, which is part of the archive.
+IOStream *D3MFZipArchive::Open(const char* pFile, const char* /*pMode*/) {
+    ai_assert(pFile != NULL);
+
+    IOStream* result = NULL;
+
+    std::map<std::string, ZipFile*>::iterator it = m_ArchiveMap.find(pFile);
+
+    if(it != m_ArchiveMap.end()) {
+        result = static_cast<IOStream*>(it->second);
+    }
+
+    return result;
+}
+
+// ------------------------------------------------------------------------------------------------
+//  Close a filestream.
+void D3MFZipArchive::Close(IOStream *pFile) {
+    ai_assert(pFile != NULL);
+
+    // We don't do anything in case the file would be opened again in the future
+}
+// ------------------------------------------------------------------------------------------------
+//  Returns the file-list of the archive.
+void D3MFZipArchive::getFileList(std::vector<std::string> &rFileList) {
+    rFileList.clear();
+
+    for(std::map<std::string, ZipFile*>::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it) {
+        rFileList.push_back(it->first);
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+//  Maps the archive content.
+bool D3MFZipArchive::mapArchive() {
+    bool success = false;
+
+    if(m_ZipFileHandle != NULL) {
+        if(m_ArchiveMap.empty()) {
+            //  At first ensure file is already open
+            if(unzGoToFirstFile(m_ZipFileHandle) == UNZ_OK) {
+                // Loop over all files
+                do {
+                    char filename[FileNameSize];
+                    unz_file_info fileInfo;
+
+                    if(unzGetCurrentFileInfo(m_ZipFileHandle, &fileInfo, filename, FileNameSize, NULL, 0, NULL, 0) == UNZ_OK) {
+                        // The file has EXACTLY the size of uncompressed_size. In C
+                        // you need to mark the last character with '\0', so add
+                        // another character
+                        if(fileInfo.uncompressed_size != 0 && unzOpenCurrentFile(m_ZipFileHandle) == UNZ_OK) {
+                            std::pair<std::map<std::string, ZipFile*>::iterator, bool> result = m_ArchiveMap.insert(std::make_pair(filename, new ZipFile(fileInfo.uncompressed_size)));
+
+                            if(unzReadCurrentFile(m_ZipFileHandle, result.first->second->m_Buffer, fileInfo.uncompressed_size) == (long int) fileInfo.uncompressed_size) {
+                                if(unzCloseCurrentFile(m_ZipFileHandle) == UNZ_OK) {
+                                    // Nothing to do anymore...
+                                }
+                            }
+                        }
+                    }
+                } while(unzGoToNextFile(m_ZipFileHandle) != UNZ_END_OF_LIST_OF_FILE);
+            }
+        }
+
+        success = true;
+    }
+
+    return success;
+}
+
+// ------------------------------------------------------------------------------------------------
+
+struct OpcPackageRelationship
+{
+    std::string id;
+    std::string type;
+    std::string target;
+};
+
+typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
+
+class OpcPackageRelationshipReader
+{
+public:
+
+    OpcPackageRelationshipReader(XmlReader* xmlReader)
+    {        
+
+        while(xmlReader->read())
+        {
+            if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
+               xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER)
+            {
+                ParseRootNode(xmlReader);
+            }
+        }
+
+
+    }
+    void ParseRootNode(XmlReader* xmlReader)
+    {       
+        ParseAttributes(xmlReader);
+
+        while(xmlReader->read())
+        {
+            if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
+               xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE)
+            {
+                ParseChildNode(xmlReader);
+            }
+        }
+
+    }
+
+    void ParseAttributes(XmlReader*)
+    {
+
+    }
+    void ParseChildNode(XmlReader* xmlReader)
+    {
+
+        OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship
+        {
+            xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_ID.c_str()),
+            xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TYPE.c_str()),
+            xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TARGET.c_str())
+         });
+        m_relationShips.push_back(relPtr);
+    }
+    std::vector<OpcPackageRelationshipPtr> m_relationShips;
+
+};
+// ------------------------------------------------------------------------------------------------
+
+D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
+    : m_RootStream(nullptr)
+{    
+
+    zipArchive.reset(new D3MF::D3MFZipArchive( pIOHandler, rFile ));    
+    if(!zipArchive->isOpen())
+        throw DeadlyImportError("Failed to open file " + rFile+ ".");
+
+    std::vector<std::string> fileList;
+    zipArchive->getFileList(fileList);
+
+    for(auto& file: fileList){
+
+        if(file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE)
+        {
+
+            //PkgRelationshipReader pkgRelReader(file, archive);
+            ai_assert(zipArchive->Exists(file.c_str()));
+
+            IOStream *fileStream = zipArchive->Open(file.c_str());
+
+            ai_assert(fileStream != nullptr);
+
+            std::string rootFile = ReadPackageRootRelationship(fileStream);
+            if(rootFile.size() > 0 && rootFile[0] == '/')
+                rootFile = rootFile.substr(1);
+
+            DefaultLogger::get()->debug(rootFile);
+
+            m_RootStream = zipArchive->Open(rootFile.c_str());
+
+            ai_assert(m_RootStream != nullptr);
+
+
+
+
+        //    const size_t size = zipArchive->FileSize();
+        //    m_Data.resize( size );
+
+        //    const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
+        //    if ( readSize != size )
+        //    {
+        //        m_Data.clear();
+        //        return false;
+        //    }
+            zipArchive->Close( fileStream );
+
+        }
+        else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE)
+        {
+
+        }
+    }
+}
+
+D3MFOpcPackage::~D3MFOpcPackage()
+{
+
+}
+
+IOStream* D3MFOpcPackage::RootStream() const
+{
+    return m_RootStream;
+}
+
+
+std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream)
+{
+
+    std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
+    std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
+
+    OpcPackageRelationshipReader reader(xml.get());
+
+
+    auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr& rel){
+        return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
+    });
+
+
+
+    if(itr == reader.m_relationShips.end())
+        throw DeadlyImportError("Cannot find" + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
+
+    return (*itr)->target;
+}
+
+} //namespace D3MF
+
+}
+
+#endif //ASSIMP_BUILD_NO_3MF_IMPORTER

+ 76 - 0
code/D3MFOpcPackage.h

@@ -0,0 +1,76 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+#ifndef D3MFOPCPACKAGE_H
+#define D3MFOPCPACKAGE_H
+
+#include <string>
+#include <memory>
+
+#include "../include/assimp/IOSystem.hpp"
+#include "irrXMLWrapper.h"
+
+namespace Assimp {
+
+namespace D3MF {
+
+typedef irr::io::IrrXMLReader XmlReader;
+typedef std::shared_ptr<XmlReader> XmlReaderPtr;
+
+class D3MFZipArchive;
+
+class D3MFOpcPackage
+{
+public:
+    D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile);
+    ~D3MFOpcPackage();
+
+    IOStream* RootStream() const;
+private:
+    std::string ReadPackageRootRelationship(IOStream* stream);
+private:
+    IOStream* m_RootStream;
+    std::unique_ptr<D3MFZipArchive> zipArchive;
+};
+
+}
+}
+
+#endif // D3MFOPCPACKAGE_H

+ 6 - 0
code/ImporterRegistry.cpp

@@ -179,6 +179,9 @@ corresponding preprocessor flag to selectively disable formats.
 #ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
 #   include "C4DImporter.h"
 #endif
+#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
+#   include "D3MFImporter.h"
+#endif
 
 namespace Assimp {
 
@@ -319,6 +322,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
 #if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER )
     out.push_back( new C4DImporter() );
 #endif
+#if ( !defined ASSIMP_BUILD_NO_3MF_IMPORTER )
+    out.push_back(new D3MFImporter() );
+#endif
 }
 
 /** will delete all registered importers. */