From c22b4acd4731950efb80f2d94e647cefadfc9b74 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 20 Nov 2017 22:36:17 +0100 Subject: [PATCH] 3MF: Export initial commit. --- code/3DSExporter.cpp | 6 ++ code/3DSExporter.h | 17 ++-- code/3MFXmlTags.h | 73 ++++++++++++++++ code/CMakeLists.txt | 3 + code/D3MFExporter.cpp | 181 ++++++++++++++++++++++++++++++++++++++++ code/D3MFExporter.h | 83 ++++++++++++++++++ code/D3MFImporter.cpp | 78 ++++++----------- code/D3MFImporter.h | 12 ++- code/D3MFOpcPackage.cpp | 45 +++------- code/D3MFOpcPackage.h | 8 +- code/irrXMLWrapper.h | 4 +- 11 files changed, 397 insertions(+), 113 deletions(-) create mode 100644 code/3MFXmlTags.h create mode 100644 code/D3MFExporter.cpp create mode 100644 code/D3MFExporter.h diff --git a/code/3DSExporter.cpp b/code/3DSExporter.cpp index 7b937d878..91c241ef7 100644 --- a/code/3DSExporter.cpp +++ b/code/3DSExporter.cpp @@ -210,6 +210,12 @@ Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr outfile, con } } +// ------------------------------------------------------------------------------------------------ +Discreet3DSExporter::~Discreet3DSExporter() { + // empty +} + + // ------------------------------------------------------------------------------------------------ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level) { diff --git a/code/3DSExporter.h b/code/3DSExporter.h index dd3c4d427..fc02e2390 100644 --- a/code/3DSExporter.h +++ b/code/3DSExporter.h @@ -60,23 +60,21 @@ namespace Assimp { // ------------------------------------------------------------------------------------------------ -/** Helper class to export a given scene to a 3DS file. */ +/** + * @brief Helper class to export a given scene to a 3DS file. + */ // ------------------------------------------------------------------------------------------------ -class Discreet3DSExporter -{ +class Discreet3DSExporter { public: Discreet3DSExporter(std::shared_ptr outfile, const aiScene* pScene); + ~Discreet3DSExporter(); private: - void WriteMeshes(); void WriteMaterials(); void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags); - void WriteFaceMaterialChunk(const aiMesh& mesh); - int WriteHierarchy(const aiNode& node, int level, int sibling_level); - void WriteString(const std::string& s); void WriteString(const aiString& s); void WriteColor(const aiColor3D& color); @@ -84,7 +82,6 @@ private: void WritePercentChunk(double f); private: - const aiScene* const scene; StreamWriterLE writer; @@ -95,6 +92,6 @@ private: }; -} +} // Namespace Assimp -#endif +#endif // AI_3DSEXPORTER_H_INC diff --git a/code/3MFXmlTags.h b/code/3MFXmlTags.h new file mode 100644 index 000000000..73d151aa0 --- /dev/null +++ b/code/3MFXmlTags.h @@ -0,0 +1,73 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, 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. + +---------------------------------------------------------------------- +*/ +#pragma once + +namespace Assimp { +namespace D3MF { + +namespace XmlTag { + 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 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 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"; +} + +} +} diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 4890a3c9e..9b3b96618 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -677,8 +677,11 @@ ADD_ASSIMP_IMPORTER( GLTF ADD_ASSIMP_IMPORTER( 3MF D3MFImporter.h D3MFImporter.cpp + D3MFExporter.h + D3MFExporter.cpp D3MFOpcPackage.h D3MFOpcPackage.cpp + 3MFXmlTags.h ) ADD_ASSIMP_IMPORTER( MMD diff --git a/code/D3MFExporter.cpp b/code/D3MFExporter.cpp new file mode 100644 index 000000000..6705ed768 --- /dev/null +++ b/code/D3MFExporter.cpp @@ -0,0 +1,181 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, 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 "D3MFExporter.h" +#include +#include +#include +#include + +#include + +#include "Exceptional.h" +#include "3MFXmlTags.h" + +namespace Assimp { +namespace D3MF { + +void ExportScene3MF( const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/ ) { + std::shared_ptr outfile( pIOSystem->Open( pFile, "wb" ) ); + if ( !outfile ) { + throw DeadlyExportError( "Could not open output .3ds file: " + std::string( pFile ) ); + } + + D3MFExporter myExporter( outfile, pScene ); + if ( myExporter.validate() ) { + bool ok = myExporter.exportAsset(); + } +} + +D3MFExporter::D3MFExporter( std::shared_ptr outfile, const aiScene* pScene ) +: mStream( outfile.get() ) +, mScene( pScene ) +, mBuildItems() { + // empty +} + +D3MFExporter::~D3MFExporter() { + // empty +} + +bool D3MFExporter::validate() { + if ( nullptr == mStream ) { + return false; + } + + if ( nullptr == mScene ) { + return false; + } + + return true; +} + +bool D3MFExporter::exportAsset() { + writeHeader(); + mOutput << "<" << XmlTag::model << " " << XmlTag::model_unit << "=\"millimeter\"" + << "xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">" + << "\n"; + mOutput << "<" << XmlTag::resources << ">\n"; + + writeObjects(); + + mOutput << "\n"; + writeBuild(); + + mOutput << "\n"; +} + +void D3MFExporter::writeHeader() { + mOutput << "" << "\n"; +} + +void D3MFExporter::writeObjects() { + if ( nullptr == mScene->mRootNode ) { + return; + } + + aiNode *root = mScene->mRootNode; + for ( unsigned int i = 0; i < root->mNumChildren; ++i ) { + aiNode *currentNode( root->mChildren[ i ] ); + if ( nullptr == currentNode ) { + continue; + } + mOutput << "<" << XmlTag::object << " id=\"" << currentNode->mName.C_Str() << "\" type=\"model\">\n"; + for ( unsigned int j = 0; j < currentNode->mNumMeshes; ++j ) { + aiMesh *currentMesh = mScene->mMeshes[ currentNode->mMeshes[ j ] ]; + if ( nullptr == currentMesh ) { + continue; + } + writeMesh( currentMesh ); + } + mBuildItems.push_back( i ); + + mOutput << "\n"; + } +} + +void D3MFExporter::writeMesh( aiMesh *mesh ) { + if ( nullptr == mesh ) { + return; + } + + mOutput << "<" << XmlTag::mesh << ">\n"; + mOutput << "<" << XmlTag::vertices << ">\n"; + for ( unsigned int i = 0; i < mesh->mNumVertices; ++i ) { + writeVertex( mesh->mVertices[ i ] ); + } + mOutput << "\n"; + mOutput << "\n"; + + writeFaces( mesh ); +} + +void D3MFExporter::writeVertex( const aiVector3D &pos ) { + mOutput << "<" << XmlTag::vertex << " x=\"" << pos.x << "\" y=\"" << pos.y << "\" z=\"" << pos.z << "\">\n"; +} + +void D3MFExporter::writeFaces( aiMesh *mesh ) { + if ( nullptr == mesh ) { + return; + } + + if ( !mesh->HasFaces() ) { + return; + } + mOutput << "<" << XmlTag::triangles << ">\n"; + for ( unsigned int i = 0; i < mesh->mNumFaces; ++i ) { + aiFace ¤tFace = mesh->mFaces[ i ]; + mOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[ 0 ] << "\" v2=\"" + << currentFace.mIndices[ 1 ] << "\" v3=\"" << currentFace.mIndices[ 2 ] << "\"/>\n"; + } + mOutput << "\n"; +} + +void D3MFExporter::writeBuild() { + mOutput << "<" << XmlTag::build << ">\n"; + + for ( size_t i = 0; i < mBuildItems.size(); ++i ) { + mOutput << "<" << XmlTag::item << " objectid=\"" << i + 1 << "\"/>\n"; + } + mOutput << "\n"; +} + +} +} // Namespace Assimp diff --git a/code/D3MFExporter.h b/code/D3MFExporter.h new file mode 100644 index 000000000..3d3a633c9 --- /dev/null +++ b/code/D3MFExporter.h @@ -0,0 +1,83 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, 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. + +---------------------------------------------------------------------- +*/ +#pragma once + +#include +#include +#include +#include + +struct aiScene; +struct aiNode; +struct aiMaterial; +struct aiMesh; + +namespace Assimp { + +class IOStream; + +namespace D3MF { + +class D3MFExporter { +public: + D3MFExporter( std::shared_ptr outfile, const aiScene* pScene ); + ~D3MFExporter(); + bool validate(); + bool exportAsset(); + +protected: + void writeHeader(); + void writeObjects(); + void writeMesh( aiMesh *mesh ); + void writeVertex( const aiVector3D &pos ); + void writeFaces( aiMesh *mesh ); + void writeBuild(); + +private: + IOStream *mStream; + const aiScene *mScene; + std::ostringstream mOutput; + std::vector mBuildItems; +}; + +} +} // Namespace Assimp + diff --git a/code/D3MFImporter.cpp b/code/D3MFImporter.cpp index 6d61a0669..6f77706f9 100644 --- a/code/D3MFImporter.cpp +++ b/code/D3MFImporter.cpp @@ -59,45 +59,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "D3MFOpcPackage.h" #include #include "irrXMLWrapper.h" +#include "3MFXmlTags.h" namespace Assimp { namespace D3MF { -namespace XmlTag { - static const std::string model = "model"; - 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 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 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"; -} - - -class XmlSerializer -{ +class XmlSerializer { public: XmlSerializer(XmlReader* xmlReader) - : xmlReader(xmlReader) - { + : xmlReader(xmlReader) { // empty } + ~XmlSerializer() { + + } + void ImportXml(aiScene* scene) { scene->mRootNode = new aiNode(); std::vector children; @@ -115,8 +92,9 @@ public: } } - if(scene->mRootNode->mName.length == 0) - scene->mRootNode->mName.Set("3MF"); + if ( scene->mRootNode->mName.length == 0 ) { + scene->mRootNode->mName.Set( "3MF" ); + } scene->mNumMeshes = static_cast(meshes.size()); @@ -178,10 +156,8 @@ private: } - aiMesh* ReadMesh() - { + aiMesh* ReadMesh() { aiMesh* mesh = new aiMesh(); - while(ReadToEndElement(D3MF::XmlTag::mesh)) { if(xmlReader->getNodeName() == D3MF::XmlTag::vertices) @@ -192,10 +168,8 @@ private: { ImportTriangles(mesh); } - } - return mesh; } @@ -216,6 +190,7 @@ private: std::copy(vertices.begin(), vertices.end(), mesh->mVertices); } + aiVector3D ReadVertex() { aiVector3D vertex; @@ -261,7 +236,6 @@ private: } private: - bool ReadToStartElement(const std::string& startTag) { while(xmlReader->read()) @@ -305,6 +279,7 @@ private: } //namespace D3MF +static const std::string Extension = "3mf"; static const aiImporterDesc desc = { "3mf Importer", @@ -316,24 +291,22 @@ static const aiImporterDesc desc = { 0, 0, 0, - "3mf" + Extension.c_str() }; D3MFImporter::D3MFImporter() -{ - +: BaseImporter() { + // empty } -D3MFImporter::~D3MFImporter() -{ - +D3MFImporter::~D3MFImporter() { + // empty } -bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const -{ +bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { const std::string extension = GetExtension(pFile); - if(extension == "3mf") { + if(extension == Extension ) { return true; } else if ( !extension.length() || checkSig ) { if (nullptr == pIOHandler ) { @@ -344,18 +317,15 @@ bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool return false; } -void D3MFImporter::SetupProperties(const Importer */*pImp*/) -{ - +void D3MFImporter::SetupProperties(const Importer * /*pImp*/) { + // empty } -const aiImporterDesc *D3MFImporter::GetInfo() const -{ +const aiImporterDesc *D3MFImporter::GetInfo() const { return &desc; } -void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) -{ +void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { D3MF::D3MFOpcPackage opcPackage(pIOHandler, pFile); std::unique_ptr xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream())); diff --git a/code/D3MFImporter.h b/code/D3MFImporter.h index fb65d8606..604d73bd5 100644 --- a/code/D3MFImporter.h +++ b/code/D3MFImporter.h @@ -46,21 +46,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { -class D3MFImporter : public BaseImporter -{ +class D3MFImporter : public BaseImporter { public: + // BaseImporter interface D3MFImporter(); ~D3MFImporter(); - - // BaseImporter interface -public: bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const; void SetupProperties(const Importer *pImp); const aiImporterDesc *GetInfo() const; protected: void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); - }; -} + +} // Namespace Assimp + #endif // AI_D3MFLOADER_H_INCLUDED diff --git a/code/D3MFOpcPackage.cpp b/code/D3MFOpcPackage.cpp index 03c39a29d..42f58cb68 100644 --- a/code/D3MFOpcPackage.cpp +++ b/code/D3MFOpcPackage.cpp @@ -80,24 +80,15 @@ namespace XmlTag { } 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); +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) { @@ -257,43 +248,27 @@ void ZipFile::Flush() { } -class D3MFZipArchive : public IOSystem -{ +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 &rFileList); private: - bool mapArchive(); private: - unzFile m_ZipFileHandle; - std::map m_ArchiveMap; - }; - // ------------------------------------------------------------------------------------------------ // Constructor. D3MFZipArchive::D3MFZipArchive(IOSystem* pIOHandler, const std::string& rFile) diff --git a/code/D3MFOpcPackage.h b/code/D3MFOpcPackage.h index e46eb7636..9ac9ade58 100644 --- a/code/D3MFOpcPackage.h +++ b/code/D3MFOpcPackage.h @@ -56,15 +56,15 @@ typedef std::shared_ptr XmlReaderPtr; class D3MFZipArchive; -class D3MFOpcPackage -{ +class D3MFOpcPackage { public: D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile); ~D3MFOpcPackage(); - IOStream* RootStream() const; -private: + +protected: std::string ReadPackageRootRelationship(IOStream* stream); + private: IOStream* m_RootStream; std::unique_ptr zipArchive; diff --git a/code/irrXMLWrapper.h b/code/irrXMLWrapper.h index d7c76bf87..bbda7c0f0 100644 --- a/code/irrXMLWrapper.h +++ b/code/irrXMLWrapper.h @@ -70,9 +70,7 @@ namespace Assimp { * } * @endcode **/ -class CIrrXML_IOStreamReader - : public irr::io::IFileReadCallBack -{ +class CIrrXML_IOStreamReader : public irr::io::IFileReadCallBack { public: // ----------------------------------------------------------------------------------