From 8126dce94dc12f504964e74047386372c3f07ecc Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 27 Aug 2014 23:00:19 +0200 Subject: [PATCH 01/39] update: add sceleton for OpenGEX importer. Signed-off-by: Kim Kulling --- code/CMakeLists.txt | 9 +++- code/ImporterRegistry.cpp | 6 +++ code/OgreImporter.h | 100 +++++++++++++++++++------------------- code/OpenGEXImporter.cpp | 96 ++++++++++++++++++++++++++++++++++++ code/OpenGEXImporter.h | 80 ++++++++++++++++++++++++++++++ 5 files changed, 239 insertions(+), 52 deletions(-) create mode 100644 code/OpenGEXImporter.cpp create mode 100644 code/OpenGEXImporter.h diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 224ae7f57..527e72511 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -251,8 +251,6 @@ SET( LWS_SRCS ) SOURCE_GROUP( LWS FILES ${LWS_SRCS}) - - SET( MD2_SRCS MD2FileData.h MD2Loader.cpp @@ -346,6 +344,12 @@ SET( Ogre_SRCS ) SOURCE_GROUP( Ogre FILES ${Ogre_SRCS}) +SET( OpenGEX_SRCS + OpenGEXImporter.cpp + OpenGEXImporter.h +) +SOURCE_GROUP( OpenGEX FILES ${OpenGEX_SRCS}) + SET( Ply_SRCS PlyLoader.cpp PlyLoader.h @@ -675,6 +679,7 @@ SET( assimp_src ${OFFFormat_SRCS} ${Obj_SRCS} ${Ogre_SRCS} + ${OpenGEX_SRCS} ${Ply_SRCS} ${Q3D_SRCS} ${Q3BSP_SRCS} diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index dff195854..ec804d141 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -142,6 +142,9 @@ corresponding preprocessor flag to selectively disable formats. #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER # include "OgreImporter.h" #endif +#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER +# include "OpenGEXImporter.h" +#endif #ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER # include "MS3DLoader.h" #endif @@ -270,6 +273,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) #if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER) out.push_back( new Ogre::OgreImporter()); #endif +#if (!defined ASSIMP_BUILD_NO_OPEMGEX_IMPORTER ) + out.push_back( new OpenGEX::OpenGEXImporter() ); +#endif #if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER) out.push_back( new MS3DImporter()); #endif diff --git a/code/OgreImporter.h b/code/OgreImporter.h index 892696407..1185eeeb0 100644 --- a/code/OgreImporter.h +++ b/code/OgreImporter.h @@ -36,63 +36,63 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- -*/ - +*/ + #ifndef AI_OGREIMPORTER_H_INC #define AI_OGREIMPORTER_H_INC #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER - -#include "BaseImporter.h" - -#include "OgreStructs.h" -#include "OgreParsingUtils.h" - -namespace Assimp -{ -namespace Ogre -{ - + +#include "BaseImporter.h" + +#include "OgreStructs.h" +#include "OgreParsingUtils.h" + +namespace Assimp +{ +namespace Ogre +{ + /** Importer for Ogre mesh, skeleton and material formats. - @todo Support vertex colors. - @todo Support poses/animations from the mesh file. - Currently only skeleton file animations are supported. */ -class OgreImporter : public BaseImporter -{ -public: - /// BaseImporter override. - virtual bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const; - - /// BaseImporter override. + @todo Support vertex colors. + @todo Support poses/animations from the mesh file. + Currently only skeleton file animations are supported. */ +class OgreImporter : public BaseImporter +{ +public: + /// BaseImporter override. + virtual bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const; + + /// BaseImporter override. virtual void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); /// BaseImporter override. - virtual const aiImporterDesc *GetInfo() const; - - /// BaseImporter override. - virtual void SetupProperties(const Importer *pImp); - -private: - /// Read materials referenced by the @c mesh to @c pScene. - void ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, Mesh *mesh); - void ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, MeshXml *mesh); - void AssignMaterials(aiScene *pScene, std::vector &materials); - - /// Reads material - aiMaterial* ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string MaterialName); - - // These functions parse blocks from a material file from @c ss. Starting parsing from "{" and ending it to "}". - bool ReadTechnique(const std::string &techniqueName, std::stringstream &ss, aiMaterial *material); - bool ReadPass(const std::string &passName, std::stringstream &ss, aiMaterial *material); - bool ReadTextureUnit(const std::string &textureUnitName, std::stringstream &ss, aiMaterial *material); - - std::string m_userDefinedMaterialLibFile; - bool m_detectTextureTypeFromFilename; - - std::map m_textures; -}; -} // Ogre -} // Assimp - + virtual const aiImporterDesc *GetInfo() const; + + /// BaseImporter override. + virtual void SetupProperties(const Importer *pImp); + +private: + /// Read materials referenced by the @c mesh to @c pScene. + void ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, Mesh *mesh); + void ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, MeshXml *mesh); + void AssignMaterials(aiScene *pScene, std::vector &materials); + + /// Reads material + aiMaterial* ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string MaterialName); + + // These functions parse blocks from a material file from @c ss. Starting parsing from "{" and ending it to "}". + bool ReadTechnique(const std::string &techniqueName, std::stringstream &ss, aiMaterial *material); + bool ReadPass(const std::string &passName, std::stringstream &ss, aiMaterial *material); + bool ReadTextureUnit(const std::string &textureUnitName, std::stringstream &ss, aiMaterial *material); + + std::string m_userDefinedMaterialLibFile; + bool m_detectTextureTypeFromFilename; + + std::map m_textures; +}; +} // Ogre +} // Assimp + #endif // ASSIMP_BUILD_NO_OGRE_IMPORTER #endif // AI_OGREIMPORTER_H_INC diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp new file mode 100644 index 000000000..361ef4c4e --- /dev/null +++ b/code/OpenGEXImporter.cpp @@ -0,0 +1,96 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2014, 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 ASSIMP_BUILD_NO_OPEMGEX_IMPORTER + +#include "AssimpPCH.h" +#include "OpenGEXImporter.h" + +static const aiImporterDesc desc = { + "Open Game Engine Exchange", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "ogex" +}; + +namespace Assimp { +namespace OpenGEX { + +//------------------------------------------------------------------------------------------------ +OpenGEXImporter::OpenGEXImporter() { + +} + +//------------------------------------------------------------------------------------------------ +OpenGEXImporter::~OpenGEXImporter() { + +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const { + return false; +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::InternReadFile( const std::string &file, aiScene *pScene, IOSystem *pIOHandler ) { + +} + +//------------------------------------------------------------------------------------------------ +const aiImporterDesc *OpenGEXImporter::GetInfo() const { + return &desc; +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::SetupProperties( const Importer *pImp ) { + +} + +//------------------------------------------------------------------------------------------------ + +} // Namespace OpenGEX +} // Namespace Assimp + +#endif // ASSIMP_BUILD_NO_OPEMGEX_IMPORTER diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h new file mode 100644 index 000000000..3cf55ff01 --- /dev/null +++ b/code/OpenGEXImporter.h @@ -0,0 +1,80 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, 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_OPENGEX_IMPORTER_H +#define AI_OPENGEX_IMPORTER_H + +#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER + +#include "BaseImporter.h" + +namespace Assimp { +namespace OpenGEX { + +/** @brief This class is used to implement the OpenGEX importer + * + * See http://opengex.org/OpenGEX.pdf for spec. + */ +class OpenGEXImporter : public BaseImporter { +public: + /// The class constructor. + OpenGEXImporter(); + + /// The class destructor. + virtual ~OpenGEXImporter(); + + /// BaseImporter override. + virtual bool CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const; + + /// BaseImporter override. + virtual void InternReadFile( const std::string &file, aiScene *pScene, IOSystem *pIOHandler ); + + /// BaseImporter override. + virtual const aiImporterDesc *GetInfo() const; + + /// BaseImporter override. + virtual void SetupProperties( const Importer *pImp ); +}; + +} // Namespace OpenGEX +} // Namespace Assimp + +#endif // ASSIMP_BUILD_NO_OPEMGEX_IMPORTER + +#endif // AI_OPENGEX_IMPORTER_H From 7f45f5fc954322110862d1a720cafa8dfa61df23 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 27 Aug 2014 23:01:35 +0200 Subject: [PATCH 02/39] bugfix: fix license. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 3cf55ff01..f658c9fa1 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2014, assimp team All rights reserved. Redistribution and use of this software in source and binary forms, From ed9a466c30968aeb6ec6244ebfee2d073fc4e3c6 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 4 Sep 2014 19:41:14 +0200 Subject: [PATCH 03/39] update: - add OpenGEX parser sceleton - add base datatypes for OpenGEX support. --- code/CMakeLists.txt | 3 + code/OpenGEXParser.cpp | 59 +++++++ code/OpenGEXParser.h | 66 ++++++++ code/OpenGEXStructs.h | 262 +++++++++++++++++++++++++++++++ test/models/OpenGEX/Example.ogex | 95 +++++++++++ 5 files changed, 485 insertions(+) create mode 100644 code/OpenGEXParser.cpp create mode 100644 code/OpenGEXParser.h create mode 100644 code/OpenGEXStructs.h create mode 100644 test/models/OpenGEX/Example.ogex diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 527e72511..aad2c04a7 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -347,6 +347,9 @@ SOURCE_GROUP( Ogre FILES ${Ogre_SRCS}) SET( OpenGEX_SRCS OpenGEXImporter.cpp OpenGEXImporter.h + OpenGEXParser.cpp + OpenGEXParser.h + OpenGEXStructs.h ) SOURCE_GROUP( OpenGEX FILES ${OpenGEX_SRCS}) diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp new file mode 100644 index 000000000..96b19f048 --- /dev/null +++ b/code/OpenGEXParser.cpp @@ -0,0 +1,59 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2014, 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 "AssimpPCH.h" +#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER + +#include "OpenGEXParser.h" + +namespace Assimp { +namespace OpenGEX { + +OpenGEXParser::OpenGEXParser() { + +} + +OpenGEXParser::~OpenGEXParser() { + +} + +} // Namespace openGEX +} // Namespace Assimp + +#endif ASSIMP_BUILD_NO_OPEMGEX_IMPORTER \ No newline at end of file diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h new file mode 100644 index 000000000..34b48e561 --- /dev/null +++ b/code/OpenGEXParser.h @@ -0,0 +1,66 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2014, 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 ASSIMP_OPENGEX_OPENGEXPARSER_H_INC +#define ASSIMP_OPENGEX_OPENGEXPARSER_H_INC + +#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER + +namespace Assimp { +namespace OpenGEX { + +class OpenGEXParser { +public: + OpenGEXParser(); + ~OpenGEXParser(); + +private: + OpenGEXParser( const OpenGEXParser & ); + OpenGEXParser &operator = ( const OpenGEXParser & ); + +private: + +}; + +} // Namespace openGEX +} // Namespace Assimp + +#endif // ASSIMP_BUILD_NO_OPEMGEX_IMPORTER + +#endif // ASSIMP_OPENGEX_OPENGEXPARSER_H_INC diff --git a/code/OpenGEXStructs.h b/code/OpenGEXStructs.h new file mode 100644 index 000000000..5a0899710 --- /dev/null +++ b/code/OpenGEXStructs.h @@ -0,0 +1,262 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2014, 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_OPENGEXSTRUCTS_H_INC +#define AI_OPENGEXSTRUCTS_H_INC + +#include +#include + +namespace Assimp { +namespace OpenGEX { + +struct Skin; +struct Object; +struct LightObject; +struct CameraObject; +struct Material; +struct BoneNode; +struct BoneCountArray; +struct BoneIndexArray; +struct BoneWeightArray; + +struct Metric { + std::string metricKey; +}; + +struct VertexArray { + std::string arrayAttrib; + unsigned int morphIndex; +}; + +struct IndexArray { + unsigned int materialIndex; + unsigned int restartIndex; + std::string frontFace; +}; + +struct Mesh { + unsigned int meshLevel; + std::string meshPrimitive; + Skin *skinStructure; +}; + +struct Node { + std::string nodeName; +}; + +struct GeometryNode { + bool visibleFlag[ 2 ]; + bool shadowFlag[ 2 ]; + bool motionBlurFlag[ 2 ]; +}; + +struct LightNode { + bool shadowFlag[ 2 ]; + const LightObject *lightObjectStructure; +}; + +struct CameraNode { + const CameraObject *cameraObjectStructure; +}; + +struct GeometryObject { + Object *object; + bool visibleFlag; + bool shadowFlag; + bool motionBlurFlag; + std::map meshMap; +}; + +struct LightObject { + Object *object; + std::string typeString; + bool shadowFlag; +}; + + +struct CameraObject { + float focalLength; + float nearDepth; + float farDepth; +}; + +struct Matrix { + bool objectFlag; +}; + +struct Transform { + Matrix *matrix; + int transformCount; + const float *transformArray; +}; + +struct Translation { + std::string translationKind; +}; + +struct Rotation { + std::string rotationKind; +}; + +struct Scale { + std::string scaleKind; +}; + +struct Name { + std::string name; +}; + + +struct ObjectRef { + Object *targetStructure; +}; + +struct MaterialRef { + unsigned int materialIndex; + const Material *targetStructure; +}; + +struct BoneRefArray { + int boneCount; + const BoneNode **boneNodeArray; +}; + +struct BoneCount { + int vertexCount; + const unsigned short *boneCountArray; + unsigned short *arrayStorage; +}; + +struct BoneIndex { + int boneIndexCount; + const unsigned short *boneIndexArray; + unsigned short *arrayStorage; +}; + + +struct BoneWeight { + int boneWeightCount; + const float *boneWeightArray; +}; + +struct Skeleton { + const BoneRefArray *boneRefArrayStructure; + const Transform *transformStructure; +}; + +struct Skin { + const Skeleton *skeletonStructure; + const BoneCountArray *boneCountArrayStructure; + const BoneIndexArray *boneIndexArrayStructure; + const BoneWeightArray *boneWeightArrayStructure; +}; + +struct Material { + bool twoSidedFlag; + const char *materialName; +}; + +struct Attrib { + std::string attribString; +}; + +struct Param { + float param; +}; + +struct Color { + float color[ 4 ]; +}; + +struct Texture { + std::string textureName; + unsigned int texcoordIndex; +}; + +struct Atten { + std::string attenKind; + std::string curveType; + + float beginParam; + float endParam; + + float scaleParam; + float offsetParam; + + float constantParam; + float linearParam; + float quadraticParam; + + float powerParam; +}; + +struct Key { + std::string keyKind; + bool scalarFlag; +}; + +struct Curve { + std::string curveType; + const Key *keyValueStructure; + const Key *keyControlStructure[ 2 ]; + const Key *keyTensionStructure; + const Key *keyContinuityStructure; + const Key *keyBiasStructure; +}; + +struct Animation { + int clipIndex; + bool beginFlag; + bool endFlag; + float beginTime; + float endTime; +}; + +struct OpenGexDataDescription { + float distanceScale; + float angleScale; + float timeScale; + int upDirection; +}; + +} // Namespace OpenGEX +} // Namespace Assimp + +#endif // AI_OPENGEXSTRUCTS_H_INC diff --git a/test/models/OpenGEX/Example.ogex b/test/models/OpenGEX/Example.ogex new file mode 100644 index 000000000..8aa1f9f4f --- /dev/null +++ b/test/models/OpenGEX/Example.ogex @@ -0,0 +1,95 @@ +Metric (key = "distance") {float {1}} +Metric (key = "angle") {float {1}} +Metric (key = "time") {float {1}} +Metric (key = "up") {string {"z"}} + +GeometryNode $node1 +{ + Name {string {"Box001"}} + ObjectRef {ref {$geometry1}} + MaterialRef {ref {$material1}} + + Transform + { + float[16] + { + {0x3F800000, 0x00000000, 0x00000000, 0x00000000, // {1, 0, 0, 0 + 0x00000000, 0x3F800000, 0x00000000, 0x00000000, // 0, 1, 0, 0 + 0x00000000, 0x00000000, 0x3F800000, 0x00000000, // 0, 0, 1, 0 + 0xBEF33B00, 0x411804DE, 0x00000000, 0x3F800000} // -0.47506, 9.50119, 0, 1} + } + } +} + +GeometryNode $node2 +{ + Name {string {"Box002"}} + ObjectRef {ref {$geometry1}} + MaterialRef {ref {$material1}} + + Transform + { + float[16] + { + {0x3F800000, 0x00000000, 0x00000000, 0x00000000, // {1, 0, 0, 0 + 0x00000000, 0x3F800000, 0x00000000, 0x00000000, // 0, 1, 0, 0 + 0x00000000, 0x00000000, 0x3F800000, 0x00000000, // 0, 0, 1, 0 + 0x43041438, 0x411804DE, 0x00000000, 0x3F800000} // 132.079, 9.50119, 0, 1} + } + } +} + +GeometryObject $geometry1 // Box001, Box002 +{ + Mesh (primitive = "triangles") + { + VertexArray (attrib = "position") + { + float[3] // 24 + { + {0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928}, + {0xC2501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928}, + {0x42501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928} + } + } + + VertexArray (attrib = "normal") + { + float[3] // 24 + { + {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, + {0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x80000000, 0xBF800000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, + {0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x80000000, 0x3F800000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000} + } + } + + VertexArray (attrib = "texcoord") + { + float[2] // 24 + { + {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, + {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, + {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000} + } + } + + IndexArray + { + unsigned_int32[3] // 12 + { + {0, 1, 2}, {2, 3, 0}, {4, 5, 6}, {6, 7, 4}, {8, 9, 10}, {10, 11, 8}, {12, 13, 14}, {14, 15, 12}, {16, 17, 18}, {18, 19, 16}, {20, 21, 22}, {22, 23, 20} + } + } + } +} + +Material $material1 +{ + Name {string {"03 - Default"}} + + Color (attrib = "diffuse") {float[3] {{0.588235, 0.588235, 0.588235}}} + Texture (attrib = "diffuse") + { + string {"texture/Concrete.tga"} + } +} From c3b35f3933db2734fd3d0ab8dbb7323e656f4b0a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 6 Sep 2014 09:19:28 +0200 Subject: [PATCH 04/39] update: add endline. --- code/OpenGEXParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index 96b19f048..dd7006e1e 100644 --- a/code/OpenGEXParser.cpp +++ b/code/OpenGEXParser.cpp @@ -56,4 +56,4 @@ OpenGEXParser::~OpenGEXParser() { } // Namespace openGEX } // Namespace Assimp -#endif ASSIMP_BUILD_NO_OPEMGEX_IMPORTER \ No newline at end of file +#endif ASSIMP_BUILD_NO_OPEMGEX_IMPORTER From 75d3c8e9f22d7be44c3e3811bcaf110d482d0d96 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 12 Sep 2014 12:00:03 +0200 Subject: [PATCH 05/39] update: metric parsing ongoing. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 27 ++++- code/OpenGEXImporter.h | 5 + code/OpenGEXParser.cpp | 223 ++++++++++++++++++++++++++++++++++++++- code/OpenGEXParser.h | 21 +++- code/OpenGEXStructs.h | 5 +- 5 files changed, 274 insertions(+), 7 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 361ef4c4e..f385cc11d 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -41,6 +41,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" #include "OpenGEXImporter.h" +#include "OpenGEXParser.h" +#include "DefaultIOSystem.h" + +#include static const aiImporterDesc desc = { "Open Game Engine Exchange", @@ -70,12 +74,29 @@ OpenGEXImporter::~OpenGEXImporter() { //------------------------------------------------------------------------------------------------ bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const { - return false; + bool canRead( false ); + if( !checkSig ) { + canRead = SimpleExtensionCheck( file, "ogex" ); + } else { + static const char *token[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" }; + canRead = BaseImporter::SearchFileHeaderForToken( pIOHandler, file, token, 4 ); + } + + return canRead; } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::InternReadFile( const std::string &file, aiScene *pScene, IOSystem *pIOHandler ) { +void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pScene, IOSystem *pIOHandler ) { + // open source file + IOStream *file = pIOHandler->Open( filename, "rb" ); + if( !file ) { + throw DeadlyImportError( "Failed to open file " + filename ); + } + std::vector buffer; + TextFileToBuffer( file, buffer ); + OpenGEXParser myParser( buffer ); + myParser.parse(); } //------------------------------------------------------------------------------------------------ @@ -85,7 +106,7 @@ const aiImporterDesc *OpenGEXImporter::GetInfo() const { //------------------------------------------------------------------------------------------------ void OpenGEXImporter::SetupProperties( const Importer *pImp ) { - + } //------------------------------------------------------------------------------------------------ diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index f658c9fa1..821692c25 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -70,6 +70,11 @@ public: /// BaseImporter override. virtual void SetupProperties( const Importer *pImp ); + +protected: + void ParseMetric(); + void ParseGeoObject(); + void ParseMaterial(); }; } // Namespace OpenGEX diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index dd7006e1e..7e73520ac 100644 --- a/code/OpenGEXParser.cpp +++ b/code/OpenGEXParser.cpp @@ -41,18 +41,239 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER #include "OpenGEXParser.h" +#include "OpenGEXStructs.h" +#include "ParsingUtils.h" +#include "fast_atof.h" + +#include namespace Assimp { namespace OpenGEX { -OpenGEXParser::OpenGEXParser() { +//------------------------------------------------------------------------------------------------ +static const std::string Metric = "Metric"; +static const std::string GeometryNode = "GeometryNode"; +static const std::string GeometryObject = "GeometryObject"; +static const std::string Material = "Material"; +static const size_t NumObjects = 4; + +static const std::string RootNodes[ NumObjects ] = { + Metric, + GeometryNode, + GeometryObject, + Material +}; + +static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, size_t numNodes, + const std::string *tokenFound ) { + tokenFound = NULL; + if( 0 == numNodes ) { + return false; + } + + bool found( false ); + for( size_t i = 0; i < numNodes; ++i ) { + if( TokenMatch( bufferPtr, nodes[ i ].c_str(), nodes[ i ].size() ) ) { + tokenFound = &nodes[ i ]; + found = true; + break; + } + } + + return found; +} + +//------------------------------------------------------------------------------------------------ +OpenGEXParser::OpenGEXParser( const std::vector &buffer ) +: m_buffer( buffer ) +, m_index( 0 ) +, m_buffersize( buffer.size() ) { } +//------------------------------------------------------------------------------------------------ OpenGEXParser::~OpenGEXParser() { } +//------------------------------------------------------------------------------------------------ +void OpenGEXParser::parse() { + while( parseNextNode() ) { + + } +} + +//------------------------------------------------------------------------------------------------ +std::string OpenGEXParser::getNextToken() { + std::string token; + while( m_index < m_buffersize && IsSpace( m_buffer[ m_index ] ) ) { + ++m_index; + } + + while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) ) { + token += m_buffer[ m_index ]; + m_index++; + } + + if( token == "//" ) { + skipComments(); + token = getNextToken(); + } + + return token; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::skipComments() { + bool skipped( false ); + if( strncmp( &m_buffer[ m_index ], "//", 2 ) == 0) { + while( !IsLineEnd( m_buffer[ m_index ] ) ) { + ++m_index; + } + skipped = true; + } + + return skipped; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::parseNextNode() { + std::string token( getNextToken() ); + std::string rootNodeName; + if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, &rootNodeName ) ) { + if( !getNodeHeader( rootNodeName ) ) { + return false; + } + + if( !getNodeData() ) { + return false; + } + } + + return true; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::getNodeHeader( const std::string &name ) { + if( name == Metric ) { + std::string token( getNextToken() ); + + } + + return false; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::getBracketOpen() { + const std::string token( getNextToken() ); + if( "{" == token ) { + return true; + } + + return false; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::getBracketClose() { + const std::string token( getNextToken() ); + if( "}" == token ) { + return true; + } + + return false; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::getStringData( std::string &data ) { + if( !getBracketOpen() ) { + return false; + } + + if( !getBracketClose() ) { + return false; + } + return false; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::getFloatData( size_t num, float *data ) { + ai_assert( nullptr != data ); + + if( !getBracketOpen() ) { + return false; + } + + bool ok( true ); + size_t dataIdx( 0 ); + for( unsigned int i = 0; i < num; ++i ) { + data[ dataIdx ] = fast_atof( &m_buffer[ m_index ] ); + ++dataIdx; + std::string tk = getNextToken(); + if( tk == "," ) { + if( i >= ( num - 1 ) ) { + ok = false; + break; + } + } + } + + if( !getBracketClose() ) { + return false; + } + + return ok; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::getNodeData() { + if( !getBracketOpen() ) { + return false; + } + + if( !onMetricNode() ) { + return false; + } + + if( !getBracketClose() ) { + return false; + } + + return true; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::getMetricAttribute( std::string &attribName ) { + return false; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::onMetricNode() { + std::string attribName; + if( !getMetricAttribute( attribName ) ) { + return false; + } + + if( "distance" == attribName ) { + float distance( 0.0f ); + getFloatData( 1, &distance ); + } else if( "angle" == attribName ) { + float angle( 0.0f ); + getFloatData( 1, &angle ); + } else if( "time" == attribName ) { + float time( 0.0f ); + getFloatData( 1, &time ); + } else if( "up" == attribName ) { + std::string up; + getStringData( up ); + } else { + return false; + } + + return true; +} + +//------------------------------------------------------------------------------------------------ + } // Namespace openGEX } // Namespace Assimp diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h index 34b48e561..0bdb7909a 100644 --- a/code/OpenGEXParser.h +++ b/code/OpenGEXParser.h @@ -41,21 +41,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define ASSIMP_OPENGEX_OPENGEXPARSER_H_INC #ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER +#include namespace Assimp { namespace OpenGEX { class OpenGEXParser { public: - OpenGEXParser(); + OpenGEXParser( const std::vector &buffer ); ~OpenGEXParser(); + void parse(); + +protected: + std::string getNextToken(); + bool skipComments(); + bool parseNextNode(); + bool getNodeHeader( const std::string &name ); + bool getBracketOpen(); + bool getBracketClose(); + bool getStringData( std::string &data ); + bool getFloatData( size_t num, float *data ); + bool getNodeData(); + bool getMetricAttribute( std::string &attribName ); + bool onMetricNode(); private: OpenGEXParser( const OpenGEXParser & ); OpenGEXParser &operator = ( const OpenGEXParser & ); private: - + const std::vector &m_buffer; + size_t m_index; + size_t m_buffersize; }; } // Namespace openGEX diff --git a/code/OpenGEXStructs.h b/code/OpenGEXStructs.h index 5a0899710..d54bf32d1 100644 --- a/code/OpenGEXStructs.h +++ b/code/OpenGEXStructs.h @@ -57,7 +57,10 @@ struct BoneIndexArray; struct BoneWeightArray; struct Metric { - std::string metricKey; + float m_distance; + float m_angle; + float m_time; + float m_up; }; struct VertexArray { From db582ee024bfbd37af9ca6a53917e1345fa5f84c Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 12 Sep 2014 18:12:18 +0200 Subject: [PATCH 06/39] bugfix: replace nullptr with NULL: Signed-off-by: Kim Kulling --- code/OpenGEXParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index 7e73520ac..19fdcb990 100644 --- a/code/OpenGEXParser.cpp +++ b/code/OpenGEXParser.cpp @@ -197,7 +197,7 @@ bool OpenGEXParser::getStringData( std::string &data ) { //------------------------------------------------------------------------------------------------ bool OpenGEXParser::getFloatData( size_t num, float *data ) { - ai_assert( nullptr != data ); + ai_assert( NULL != data ); if( !getBracketOpen() ) { return false; From 6843c42da10c58ff1fe6dcb9d035be04eebe7b69 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 28 Oct 2014 21:45:09 +0100 Subject: [PATCH 07/39] update: - merge master into branch - fix metrix header parsing. Signed-off-by: Kim Kulling --- code/OpenGEXParser.cpp | 117 +++++++++++++++++++++++++++++------------ code/OpenGEXParser.h | 18 ++++++- 2 files changed, 98 insertions(+), 37 deletions(-) diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index 19fdcb990..efb1ff7b0 100644 --- a/code/OpenGEXParser.cpp +++ b/code/OpenGEXParser.cpp @@ -55,8 +55,7 @@ static const std::string Metric = "Metric"; static const std::string GeometryNode = "GeometryNode"; static const std::string GeometryObject = "GeometryObject"; static const std::string Material = "Material"; -static const size_t NumObjects = 4; - +static const size_t NumObjects = 4; static const std::string RootNodes[ NumObjects ] = { Metric, GeometryNode, @@ -64,9 +63,31 @@ static const std::string RootNodes[ NumObjects ] = { Material }; -static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, size_t numNodes, - const std::string *tokenFound ) { - tokenFound = NULL; +static const size_t NumSeparator = 4; +static const std::string Separator[ NumSeparator ] = { + "(", ")", "{", "}" +}; + + +static const size_t NumToken = 8; +static const std::string Token[ NumToken ] = { + RootNodes[ 0 ], + RootNodes[ 1 ], + RootNodes[ 2 ], + RootNodes[ 3 ], + Separator[ 0 ], + Separator[ 1 ], + Separator[ 2 ], + Separator[ 3 ] +}; + +static bool isSeparator( char in ) { + return ( in == '(' || in == ')' || in == '{' || in == '}' ); +} + +static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, + size_t numNodes, std::string &tokenFound ) { + tokenFound = ""; if( 0 == numNodes ) { return false; } @@ -74,7 +95,7 @@ static bool containsNode( const char *bufferPtr, size_t size, const std::string bool found( false ); for( size_t i = 0; i < numNodes; ++i ) { if( TokenMatch( bufferPtr, nodes[ i ].c_str(), nodes[ i ].size() ) ) { - tokenFound = &nodes[ i ]; + tokenFound = nodes[ i ]; found = true; break; } @@ -83,12 +104,27 @@ static bool containsNode( const char *bufferPtr, size_t size, const std::string return found; } +static OpenGEXParser::TokenType getTokenTypeByName( const char *in ) { + ai_assert( NULL != in ); + + OpenGEXParser::TokenType type( OpenGEXParser::None ); + for( size_t i = 0; i < NumToken; ++i ) { + if( TokenMatch( in, Token[ i ].c_str(), Token[ i ].size() ) ) { + type = static_cast( i+1 ); + break; + } + } + + return type; +} + //------------------------------------------------------------------------------------------------ OpenGEXParser::OpenGEXParser( const std::vector &buffer ) : m_buffer( buffer ) , m_index( 0 ) -, m_buffersize( buffer.size() ) { - +, m_buffersize( buffer.size() ) +, m_nodeTypeStack() { + // empty } //------------------------------------------------------------------------------------------------ @@ -107,10 +143,10 @@ void OpenGEXParser::parse() { std::string OpenGEXParser::getNextToken() { std::string token; while( m_index < m_buffersize && IsSpace( m_buffer[ m_index ] ) ) { - ++m_index; + m_index++; } - while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) ) { + while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) && !isSeparator( m_buffer[ m_index ] ) ) { token += m_buffer[ m_index ]; m_index++; } @@ -120,6 +156,13 @@ std::string OpenGEXParser::getNextToken() { token = getNextToken(); } + if( token.empty() ) { + if( isSeparator( m_buffer[ m_index ] ) ) { + token += m_buffer[ m_index ]; + m_index++; + } + } + return token; } @@ -140,7 +183,8 @@ bool OpenGEXParser::skipComments() { bool OpenGEXParser::parseNextNode() { std::string token( getNextToken() ); std::string rootNodeName; - if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, &rootNodeName ) ) { + if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, rootNodeName ) ) { + m_nodeTypeStack.push_back( getTokenTypeByName( rootNodeName.c_str() ) ); if( !getNodeHeader( rootNodeName ) ) { return false; } @@ -148,6 +192,8 @@ bool OpenGEXParser::parseNextNode() { if( !getNodeData() ) { return false; } + + m_nodeTypeStack.pop_back(); } return true; @@ -155,12 +201,15 @@ bool OpenGEXParser::parseNextNode() { //------------------------------------------------------------------------------------------------ bool OpenGEXParser::getNodeHeader( const std::string &name ) { - if( name == Metric ) { - std::string token( getNextToken() ); - + bool success( false ); + if( m_nodeTypeStack.back() == MetricNode ) { + std::string attribName, value; + if( getMetricAttributeKey( attribName, value ) ) { + success = true; + } } - return false; + return success; } //------------------------------------------------------------------------------------------------ @@ -226,33 +275,31 @@ bool OpenGEXParser::getFloatData( size_t num, float *data ) { //------------------------------------------------------------------------------------------------ bool OpenGEXParser::getNodeData() { - if( !getBracketOpen() ) { - return false; - } - - if( !onMetricNode() ) { - return false; - } - - if( !getBracketClose() ) { - return false; - } - return true; } //------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getMetricAttribute( std::string &attribName ) { - return false; +bool OpenGEXParser::getMetricAttributeKey( std::string &attribName, std::string &value ) { + bool ok( false ); + attribName = ""; + std::string token( getNextToken() ); + if( token[ 0 ] == '(' ) { + // get attribute + attribName = getNextToken(); + std::string equal = getNextToken(); + value = getNextToken(); + + token = getNextToken(); + if( token[ 0 ] == ')' ) { + ok = true; + } + } + + return ok; } //------------------------------------------------------------------------------------------------ -bool OpenGEXParser::onMetricNode() { - std::string attribName; - if( !getMetricAttribute( attribName ) ) { - return false; - } - +bool OpenGEXParser::onMetricNode( const std::string &attribName ) { if( "distance" == attribName ) { float distance( 0.0f ); getFloatData( 1, &distance ); diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h index 0bdb7909a..1733366f7 100644 --- a/code/OpenGEXParser.h +++ b/code/OpenGEXParser.h @@ -47,6 +47,19 @@ namespace Assimp { namespace OpenGEX { class OpenGEXParser { +public: + enum TokenType { + None = 0, + MetricNode, + GeometryNode, + GeometryObject, + Material, + BracketIn, + BracketOut, + CurlyBracketIn, + CurlyBracketOut, + }; + public: OpenGEXParser( const std::vector &buffer ); ~OpenGEXParser(); @@ -62,8 +75,8 @@ protected: bool getStringData( std::string &data ); bool getFloatData( size_t num, float *data ); bool getNodeData(); - bool getMetricAttribute( std::string &attribName ); - bool onMetricNode(); + bool getMetricAttributeKey( std::string &attribName, std::string &value ); + bool onMetricNode( const std::string &attribName ); private: OpenGEXParser( const OpenGEXParser & ); @@ -71,6 +84,7 @@ private: private: const std::vector &m_buffer; + std::vector m_nodeTypeStack; size_t m_index; size_t m_buffersize; }; From 1a5695ff485ec28f50db62f6376bab1fdf5d584e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 2 Nov 2014 19:01:04 +0100 Subject: [PATCH 08/39] update: add parsing of metric nodes. Signed-off-by: Kim Kulling --- code/OpenGEXParser.cpp | 84 ++++++++++++++++++++++++++++++------------ code/OpenGEXParser.h | 26 +++++++++++-- 2 files changed, 84 insertions(+), 26 deletions(-) diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index efb1ff7b0..0acf209a6 100644 --- a/code/OpenGEXParser.cpp +++ b/code/OpenGEXParser.cpp @@ -118,6 +118,16 @@ static OpenGEXParser::TokenType getTokenTypeByName( const char *in ) { return type; } +static void removeQuotes( std::string &attribName ) { + std::string tmp; + for( unsigned int i = 0; i < attribName.size(); ++i ) { + if( attribName[ i ] != '\"' ) { + tmp += attribName[ i ]; + } + } + attribName = tmp; +} + //------------------------------------------------------------------------------------------------ OpenGEXParser::OpenGEXParser( const std::vector &buffer ) : m_buffer( buffer ) @@ -182,14 +192,14 @@ bool OpenGEXParser::skipComments() { //------------------------------------------------------------------------------------------------ bool OpenGEXParser::parseNextNode() { std::string token( getNextToken() ); - std::string rootNodeName; + std::string rootNodeName, nodeType; if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, rootNodeName ) ) { m_nodeTypeStack.push_back( getTokenTypeByName( rootNodeName.c_str() ) ); - if( !getNodeHeader( rootNodeName ) ) { + if( !getNodeHeader( nodeType ) ) { return false; } - if( !getNodeData() ) { + if( !getNodeData( nodeType ) ) { return false; } @@ -200,11 +210,10 @@ bool OpenGEXParser::parseNextNode() { } //------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getNodeHeader( const std::string &name ) { +bool OpenGEXParser::getNodeHeader( std::string &name ) { bool success( false ); if( m_nodeTypeStack.back() == MetricNode ) { - std::string attribName, value; - if( getMetricAttributeKey( attribName, value ) ) { + if( getMetricAttributeKey( name ) ) { success = true; } } @@ -248,6 +257,9 @@ bool OpenGEXParser::getStringData( std::string &data ) { bool OpenGEXParser::getFloatData( size_t num, float *data ) { ai_assert( NULL != data ); + std::string tk; + tk = getNextToken(); + if( !getBracketOpen() ) { return false; } @@ -257,7 +269,7 @@ bool OpenGEXParser::getFloatData( size_t num, float *data ) { for( unsigned int i = 0; i < num; ++i ) { data[ dataIdx ] = fast_atof( &m_buffer[ m_index ] ); ++dataIdx; - std::string tk = getNextToken(); + tk = getNextToken(); if( tk == "," ) { if( i >= ( num - 1 ) ) { ok = false; @@ -274,24 +286,41 @@ bool OpenGEXParser::getFloatData( size_t num, float *data ) { } //------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getNodeData() { - return true; +bool OpenGEXParser::getNodeData( const std::string &nodeType ) { + bool success( false ); + + if( !getBracketOpen() ) { + return false; + } + + TokenType type( m_nodeTypeStack.back() ); + if( type == MetricNode ) { + success = onMetricNode( nodeType ); + } + + if( !getBracketClose() ) { + return false; + } + + return success; } //------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getMetricAttributeKey( std::string &attribName, std::string &value ) { +bool OpenGEXParser::getMetricAttributeKey( std::string &attribName ) { bool ok( false ); attribName = ""; std::string token( getNextToken() ); if( token[ 0 ] == '(' ) { // get attribute - attribName = getNextToken(); - std::string equal = getNextToken(); - value = getNextToken(); - token = getNextToken(); - if( token[ 0 ] == ')' ) { - ok = true; + if( "key" == token ) { + std::string equal = getNextToken(); + attribName = getNextToken(); + token = getNextToken(); + if( token[ 0 ] == ')' ) { + ok = true; + removeQuotes( attribName ); + } } } @@ -300,28 +329,37 @@ bool OpenGEXParser::getMetricAttributeKey( std::string &attribName, std::string //------------------------------------------------------------------------------------------------ bool OpenGEXParser::onMetricNode( const std::string &attribName ) { + bool success( true ); if( "distance" == attribName ) { float distance( 0.0f ); - getFloatData( 1, &distance ); + if( getFloatData( 1, &distance ) ) { + m_model.m_metrics.m_distance = distance; + } } else if( "angle" == attribName ) { float angle( 0.0f ); - getFloatData( 1, &angle ); + if( getFloatData( 1, &angle ) ) { + m_model.m_metrics.m_angle = angle; + } } else if( "time" == attribName ) { float time( 0.0f ); - getFloatData( 1, &time ); + if( getFloatData( 1, &time ) ) { + m_model.m_metrics.m_time = time; + } } else if( "up" == attribName ) { std::string up; - getStringData( up ); + if( getStringData( up ) ) { + m_model.m_metrics.m_up = up; + } } else { - return false; + success = false; } - return true; + return success; } //------------------------------------------------------------------------------------------------ -} // Namespace openGEX +} // Namespace OpenGEX } // Namespace Assimp #endif ASSIMP_BUILD_NO_OPEMGEX_IMPORTER diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h index 1733366f7..f6ef2df14 100644 --- a/code/OpenGEXParser.h +++ b/code/OpenGEXParser.h @@ -41,11 +41,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define ASSIMP_OPENGEX_OPENGEXPARSER_H_INC #ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER + #include +#include namespace Assimp { namespace OpenGEX { +struct OpenGEXModel { + struct Metrics { + float m_distance; + float m_angle; + float m_time; + std::string m_up; + + Metrics() + : m_distance( 0.0f ) + , m_angle( 0.0f ) + , m_time( 0.0f ) + , m_up() { + // empty + } + } m_metrics; +}; + class OpenGEXParser { public: enum TokenType { @@ -69,13 +88,13 @@ protected: std::string getNextToken(); bool skipComments(); bool parseNextNode(); - bool getNodeHeader( const std::string &name ); + bool getNodeHeader( std::string &name ); bool getBracketOpen(); bool getBracketClose(); bool getStringData( std::string &data ); bool getFloatData( size_t num, float *data ); - bool getNodeData(); - bool getMetricAttributeKey( std::string &attribName, std::string &value ); + bool getNodeData( const std::string &nodeType ); + bool getMetricAttributeKey( std::string &attribName ); bool onMetricNode( const std::string &attribName ); private: @@ -85,6 +104,7 @@ private: private: const std::vector &m_buffer; std::vector m_nodeTypeStack; + OpenGEXModel m_model; size_t m_index; size_t m_buffersize; }; From dbf95362133a5ae4ab377f547f33679c1a7c3c1b Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 2 Nov 2014 20:30:45 +0100 Subject: [PATCH 09/39] bugfix: add correct handling for metric line end for example file. Signed-off-by: Kim Kulling --- .gitignore | 1 + code/OpenGEXParser.cpp | 30 +++++++++++++++++++++--------- code/OpenGEXParser.h | 1 + 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index f4940f273..67299f752 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ test/gtest/src/gtest-stamp/gtest-build.cmake test/gtest/src/gtest-stamp/Debug/gtest-patch *.cache test/gtest/src/gtest-stamp/Debug/gtest-build +*.lib diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index 0acf209a6..03f222d1c 100644 --- a/code/OpenGEXParser.cpp +++ b/code/OpenGEXParser.cpp @@ -189,6 +189,17 @@ bool OpenGEXParser::skipComments() { return skipped; } +//------------------------------------------------------------------------------------------------ +void OpenGEXParser::readUntilEndOfLine() { + while( !IsLineEnd( m_buffer[ m_index ] ) ) { + ++m_index; + } + ++m_index; + if( IsLineEnd( m_buffer[ m_index ] ) ) { + ++m_index; + } +} + //------------------------------------------------------------------------------------------------ bool OpenGEXParser::parseNextNode() { std::string token( getNextToken() ); @@ -202,8 +213,11 @@ bool OpenGEXParser::parseNextNode() { if( !getNodeData( nodeType ) ) { return false; } + + readUntilEndOfLine(); m_nodeTypeStack.pop_back(); + } return true; @@ -329,21 +343,19 @@ bool OpenGEXParser::getMetricAttributeKey( std::string &attribName ) { //------------------------------------------------------------------------------------------------ bool OpenGEXParser::onMetricNode( const std::string &attribName ) { + float value( 0.0f ); bool success( true ); if( "distance" == attribName ) { - float distance( 0.0f ); - if( getFloatData( 1, &distance ) ) { - m_model.m_metrics.m_distance = distance; + if( getFloatData( 1, &value ) ) { + m_model.m_metrics.m_distance = value; } } else if( "angle" == attribName ) { - float angle( 0.0f ); - if( getFloatData( 1, &angle ) ) { - m_model.m_metrics.m_angle = angle; + if( getFloatData( 1, &value ) ) { + m_model.m_metrics.m_angle = value; } } else if( "time" == attribName ) { - float time( 0.0f ); - if( getFloatData( 1, &time ) ) { - m_model.m_metrics.m_time = time; + if( getFloatData( 1, &value ) ) { + m_model.m_metrics.m_time = value; } } else if( "up" == attribName ) { std::string up; diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h index f6ef2df14..82b30e4ae 100644 --- a/code/OpenGEXParser.h +++ b/code/OpenGEXParser.h @@ -87,6 +87,7 @@ public: protected: std::string getNextToken(); bool skipComments(); + void readUntilEndOfLine(); bool parseNextNode(); bool getNodeHeader( std::string &name ); bool getBracketOpen(); From 9f80a2a2a9e51a688e44baf75cc235a0e9895e2f Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 29 Nov 2014 11:33:49 +0100 Subject: [PATCH 10/39] update parser. Signed-off-by: Kim Kulling --- code/OpenGEXParser.cpp | 36 ++++++++++++++++++++++++++++++++++-- code/OpenGEXParser.h | 3 +++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index 03f222d1c..3dcc83e44 100644 --- a/code/OpenGEXParser.cpp +++ b/code/OpenGEXParser.cpp @@ -226,10 +226,19 @@ bool OpenGEXParser::parseNextNode() { //------------------------------------------------------------------------------------------------ bool OpenGEXParser::getNodeHeader( std::string &name ) { bool success( false ); - if( m_nodeTypeStack.back() == MetricNode ) { + TokenType tokenType( m_nodeTypeStack.back() ); + if( tokenType == MetricNode ) { if( getMetricAttributeKey( name ) ) { success = true; } + } else if( tokenType == GeometryNode ) { + + } else if( tokenType == GeometryObject ) { + + } else if( tokenType == Material ) { + + } else { + DefaultLogger::get()->warn( "Unknown token type in file." ); } return success; @@ -307,9 +316,17 @@ bool OpenGEXParser::getNodeData( const std::string &nodeType ) { return false; } - TokenType type( m_nodeTypeStack.back() ); + const TokenType type( m_nodeTypeStack.back() ); if( type == MetricNode ) { success = onMetricNode( nodeType ); + } else if( type == GeometryNode ) { + success = onGeometryNode(); + } else if( type == GeometryObject ) { + success = onGeometryObject(); + } else if( type == Material ) { + success = onMaterial(); + } else { + DefaultLogger::get()->warn( "Unknown token type in file." ); } if( !getBracketClose() ) { @@ -369,6 +386,21 @@ bool OpenGEXParser::onMetricNode( const std::string &attribName ) { return success; } +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::onGeometryNode() { + return true; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::onGeometryObject() { + return true; +} + +//------------------------------------------------------------------------------------------------ +bool OpenGEXParser::onMaterial() { + return true; +} + //------------------------------------------------------------------------------------------------ } // Namespace OpenGEX diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h index 82b30e4ae..64debe43c 100644 --- a/code/OpenGEXParser.h +++ b/code/OpenGEXParser.h @@ -97,6 +97,9 @@ protected: bool getNodeData( const std::string &nodeType ); bool getMetricAttributeKey( std::string &attribName ); bool onMetricNode( const std::string &attribName ); + bool onGeometryNode(); + bool onGeometryObject(); + bool onMaterial(); private: OpenGEXParser( const OpenGEXParser & ); From 1ee4c06e4bb06809e0ff374e40b8d7555d0d544a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 31 Jan 2015 11:07:48 +0100 Subject: [PATCH 11/39] add openddl-parser to contrib. Signed-off-by: Kim Kulling --- .gitignore | 2 +- CMakeLists.txt | 1 + code/CMakeLists.txt | 1 - contrib/openddlparser/CMakeLists.txt | 63 ++ contrib/openddlparser/README.md | 111 +++ contrib/openddlparser/code/DDLNode.cpp | 162 ++++ contrib/openddlparser/code/OpenDDLParser.cpp | 852 ++++++++++++++++++ contrib/openddlparser/code/Value.cpp | 243 +++++ .../include/openddlparser/DDLNode.h | 87 ++ .../include/openddlparser/OpenDDLCommon.h | 148 +++ .../openddlparser/OpenDDLParserUtils.h | 233 +++++ .../include/openddlparser/Value.h | 85 ++ 12 files changed, 1986 insertions(+), 2 deletions(-) create mode 100644 contrib/openddlparser/CMakeLists.txt create mode 100644 contrib/openddlparser/README.md create mode 100644 contrib/openddlparser/code/DDLNode.cpp create mode 100644 contrib/openddlparser/code/OpenDDLParser.cpp create mode 100644 contrib/openddlparser/code/Value.cpp create mode 100644 contrib/openddlparser/include/openddlparser/DDLNode.h create mode 100644 contrib/openddlparser/include/openddlparser/OpenDDLCommon.h create mode 100644 contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h create mode 100644 contrib/openddlparser/include/openddlparser/Value.h diff --git a/.gitignore b/.gitignore index 55995220d..cf0c2a94f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ build # Output bin/ lib/ -contrib/ + # Generated assimp.pc diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c8661f55..7c9468b95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,7 @@ else(NOT ZLIB_FOUND) endif(NOT ZLIB_FOUND) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) +add_subdirectory( contrib/openddlparser ) # Search for unzip if (PKG_CONFIG_FOUND) PKG_CHECK_MODULES(UNZIP minizip) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 1edaa8725..70034ed66 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -634,7 +634,6 @@ SET( unzip_SRCS ) SOURCE_GROUP( unzip FILES ${unzip_SRCS}) - # VC2010 fixes if(MSVC10) option( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF ) diff --git a/contrib/openddlparser/CMakeLists.txt b/contrib/openddlparser/CMakeLists.txt new file mode 100644 index 000000000..d551c9857 --- /dev/null +++ b/contrib/openddlparser/CMakeLists.txt @@ -0,0 +1,63 @@ +CMAKE_MINIMUM_REQUIRED( VERSION 2.6 ) +PROJECT( OpenDDL-Parser ) +SET ( OPENDDL_PARSER_VERSION_MAJOR 0 ) +SET ( OPENDDL_PARSER_VERSION_MINOR 1 ) +SET ( OPENDDL_PARSER_VERSION_PATCH 0 ) +SET ( OPENDDL_PARSER_VERSION ${CPPCORE_VERSION_MAJOR}.${CPPCORE_VERSION_MINOR}.${CPPCORE_VERSION_PATCH} ) +SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" ) + +if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + find_package(Threads) +else() + add_definitions( -D_CRT_SECURE_NO_WARNINGS ) +endif() + +add_definitions( -DOPENDDLPARSER_BUILD ) +add_definitions( -D_VARIADIC_MAX=10 ) + +INCLUDE_DIRECTORIES( + ./ + include/ + contrib/gtest-1.7.0/include + contrib/gtest-1.7.0/ +) + +link_directories( + ./ +) + +SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) +SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) +SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin ) + +if( WIN32 AND NOT CYGWIN ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc" ) # Force to always compile with W4 + if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" ) + string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" ) + else() + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" ) + endif() +elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + # Update if necessary + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++0x") +elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11") +endif() + +SET ( openddl_parser_src + code/OpenDDLParser.cpp + code/DDLNode.cpp + code/Value.cpp + include/openddlparser/OpenDDLParser.h + include/openddlparser/OpenDDLParserUtils.h + include/openddlparser/OpenDDLCommon.h + include/openddlparser/DDLNode.h + include/openddlparser/Value.h + README.md +) + +SOURCE_GROUP( code FILES ${openddl_parser_src} ) + +ADD_LIBRARY( openddl_parser SHARED + ${openddl_parser_src} +) diff --git a/contrib/openddlparser/README.md b/contrib/openddlparser/README.md new file mode 100644 index 000000000..195de6932 --- /dev/null +++ b/contrib/openddlparser/README.md @@ -0,0 +1,111 @@ +The OpenDDL-Parser +================== + +A simple and fast OpenDDL Parser +Current build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser) + +Get the source code +=================== +You can get the code from our git repository, which is located at GitHub. You can clone the repository like: + +> git clone https://github.com/kimkulling/openddl-parser.git + +Build from repo +=============== +To build the library you need to install cmake first ( see http://www.cmake.org/ for more information ). Make also sure that a compiler toolchain is installed on your machine. +After installing it you can open a console and type: + +> cmake CMakeLists.txt + +This command will generate a build environment for your installed build enrironment ( for Visual Studio the project files will be generated, for gcc the makefiles will be generated ). +When using an IDE open the IDE and run the build. When using GNU-make type in your console: + +> make + +and that's all. + +Use the library +=============== +To use the OpenDDL-parser you need to build the lib first. Now add the +> /include + +to your include-path and the + +> /lib + +to your lib-folder. Link the openddl.lib to your application. + +Here is a small example how to use the lib: + +```cpp + +#include +#include +#include + +USE_ODDLPARSER_NS; + +int main( int argc, char *argv[] ) { + if( argc < 3 ) { + return 1; + } + + char *filename( nullptr ); + if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) { + filename = argv[ 2 ]; + } + std::cout << "file to import: " << filename << std::endl; + if( nullptr == filename ) { + std::cerr << "Invalid filename." << std::endl; + return Error; + } + + FILE *fileStream = fopen( filename, "r+" ); + if( NULL == filename ) { + std::cerr << "Cannot open file " << filename << std::endl; + return 1; + } + + // obtain file size: + fseek( fileStream, 0, SEEK_END ); + const size_t size( ftell( fileStream ) ); + rewind( fileStream ); + if( size > 0 ) { + char *buffer = new char[ size ]; + const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) ); + assert( readSize == size ); + OpenDDLParser theParser; + theParser.setBuffer( buffer, size ); + const bool result( theParser.parse() ); + if( !result ) { + std::cerr << "Error while parsing file " << filename << "." << std::endl; + } + } + return 0; +} + +``` + +How to access the imported data +=============================== +The data is organized as a tree. You can get the root tree with the following code: + +``` +OpenDDLParser theParser; +theParser.setBuffer( buffer, size ); +const bool result( theParser.parse() ); +if ( result ) { + DDLNode *root = theParser.getRoot(); + + DDLNode::DllNodeList childs = root->getChildNodeList(); + for ( size_t i=0; igetProperty(); // to get properties + std:.string type = child->getType(); // to get the node type + Value *values = child->getValue(); // to get the data; + } +} + +``` + +The instance called root contains the data. diff --git a/contrib/openddlparser/code/DDLNode.cpp b/contrib/openddlparser/code/DDLNode.cpp new file mode 100644 index 000000000..30977ca2e --- /dev/null +++ b/contrib/openddlparser/code/DDLNode.cpp @@ -0,0 +1,162 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#include +#include + +#include + +BEGIN_ODDLPARSER_NS + +DDLNode::DllNodeList DDLNode::s_allocatedNodes; + +template +inline +static void releaseDataType( T *ptr ) { + if( nullptr == ptr ) { + return; + } + + T *current( nullptr ); + while( ptr ) { + current = ptr; + ptr = ptr->m_next; + delete current; + } +} + +DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent ) +: m_type( type ) +, m_name( name ) +, m_parent( parent ) +, m_children() +, m_properties( nullptr ) +, m_value( nullptr ) +, m_idx( idx ) +, m_dtArrayList( nullptr ) { + if( m_parent ) { + m_parent->m_children.push_back( this ); + } +} + +DDLNode::~DDLNode() { + releaseDataType( m_properties ); + releaseDataType( m_value ); + + delete m_dtArrayList; + m_dtArrayList = nullptr; + if( s_allocatedNodes[ m_idx ] == this ) { + s_allocatedNodes[ m_idx ] = nullptr; + } +} + +void DDLNode::attachParent( DDLNode *parent ) { + if( m_parent == parent ) { + return; + } + + m_parent = parent; + if( nullptr != m_parent ) { + m_parent->m_children.push_back( this ); + } +} + +void DDLNode::detachParent() { + if( m_parent ) { + std::vector::iterator it; + it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this ); + if( m_parent->m_children.end() != it ) { + m_parent->m_children.erase( it ); + } + m_parent = nullptr; + } +} + +DDLNode *DDLNode::getParent() const { + return m_parent; +} + +const DDLNode::DllNodeList &DDLNode::getChildNodeList() const { + return m_children; +} + +void DDLNode::setType( const std::string &type ) { + m_type = type; +} + +const std::string &DDLNode::getType() const { + return m_type; +} + + +void DDLNode::setName( const std::string &name ) { + m_name = name; +} + +const std::string &DDLNode::getName() const { + return m_name; +} + +void DDLNode::setProperties( Property *first ) { + m_properties = first; +} + +Property *DDLNode::getProperties() const { + return m_properties; +} + +void DDLNode::setValue( Value *val ) { + m_value = val; +} + +Value *DDLNode::getValue() const { + return m_value; +} + +void DDLNode::setDataArrayList( DataArrayList *dtArrayList ) { + m_dtArrayList = dtArrayList; +} + +DataArrayList *DDLNode::getDataArrayList() const { + return m_dtArrayList; +} + +DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) { + const size_t idx( s_allocatedNodes.size() ); + DDLNode *node = new DDLNode( type, name, idx, parent ); + s_allocatedNodes.push_back( node ); + + return node; +} + +void DDLNode::releaseNodes() { + if( s_allocatedNodes.size() > 0 ) { + for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) { + if( *it ) { + delete *it; + } + } + s_allocatedNodes.clear(); + } +} + +END_ODDLPARSER_NS diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp new file mode 100644 index 000000000..675d58511 --- /dev/null +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -0,0 +1,852 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#include + +#include +#include +#include +#include + +#ifdef _WIN32 +# include +#endif // _WIN32 + +#define DEBUG_HEADER_NAME + +BEGIN_ODDLPARSER_NS + +static const char *Version = "0.1.0"; + +static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = { + "bool", + "int8", + "int16", + "int32", + "int64", + "unsigned_int8", + "unsigned_int16", + "unsigned_int32", + "unsigned_int64", + "half", + "float", + "double", + "string", + "ref" +}; + +static const char *BoolTrue = "true"; +static const char *BoolFalse = "false"; +static const char *RefToken = "ref"; + +static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallback callback ) { + std::stringstream stream; + stream << "Invalid token " << *in << ", " << exp << " expected." << std::endl; + callback( ddl_error_msg, stream.str() ); +} + +static bool isIntegerType( Value::ValueType integerType ) { + if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) { + return false; + } + + return true; +} + +static DDLNode *createDDLNode( Identifier *id, Property *first, OpenDDLParser *parser ) { + if( nullptr == id || nullptr == parser ) { + return nullptr; + } + + const std::string type( id->m_buffer ); + DDLNode *parent( parser->top() ); + DDLNode *node = DDLNode::create( type, "", parent ); + if( nullptr != first ) { + node->setProperties( first ); + } + + return node; +} + +static void logMessage( LogSeverity severity, const std::string &msg ) { + std::string log; + if( ddl_debug_msg == severity ) { + log += "Debug:"; + } else if( ddl_info_msg == severity ) { + log += "Info :"; + } else if( ddl_warn_msg == severity ) { + log += "Warn :"; + } else if( ddl_error_msg == severity ) { + log += "Error:"; + } else { + log += "None :"; + } + + log += msg; + std::cout << log; +} + +OpenDDLParser::OpenDDLParser() +: m_logCallback( logMessage ) +, m_ownsBuffer( false ) +,m_buffer( nullptr ) +, m_len( 0 ) +, m_stack() +, m_context( nullptr ) { + // empty +} + +OpenDDLParser::OpenDDLParser( char *buffer, size_t len, bool ownsIt ) +: m_logCallback( &logMessage ) +, m_ownsBuffer( false ) +, m_buffer( nullptr ) +, m_len( 0 ) +, m_context( nullptr ) { + if( 0 != m_len ) { + setBuffer( buffer, len, ownsIt ); + } +} + +OpenDDLParser::~OpenDDLParser() { + clear(); +} + +void OpenDDLParser::setLogCallback( logCallback callback ) { + if( nullptr != callback ) { + // install user-specific log callback + m_logCallback = callback; + } else { + // install default log callback + m_logCallback = &logMessage; + } +} + +OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const { + return m_logCallback; +} + +void OpenDDLParser::setBuffer( char *buffer, size_t len, bool ownsIt ) { + if( m_buffer && m_ownsBuffer ) { + delete[] m_buffer; + m_buffer = nullptr; + m_len = 0; + } + + m_ownsBuffer = ownsIt; + if( m_ownsBuffer ) { + // when we are owning the buffer we will do a deep copy + m_buffer = new char[ len ]; + m_len = len; + ::memcpy( m_buffer, buffer, len ); + } else { + // when we are not owning the buffer, we just do a shallow copy + m_buffer = buffer; + m_len = len; + } +} + +char *OpenDDLParser::getBuffer() const { + return m_buffer; +} + +size_t OpenDDLParser::getBufferSize() const { + return m_len; +} + +void OpenDDLParser::clear() { + if( m_ownsBuffer ) { + delete [] m_buffer; + } + m_buffer = nullptr; + m_len = 0; + + if( m_context ) { + m_context->m_root = nullptr; + } + + DDLNode::releaseNodes(); +} + +bool OpenDDLParser::parse() { + if( 0 == m_len ) { + return false; + } + + normalizeBuffer( m_buffer, m_len ); + + m_context = new Context; + m_context->m_root = DDLNode::create( "root", "", nullptr ); + pushNode( m_context->m_root ); + + // do the main parsing + char *current( &m_buffer[ 0 ] ); + char *end( &m_buffer[ m_len - 1 ] + 1 ); + while( current != end ) { + current = parseNextNode( current, end ); + } + return true; +} + +char *OpenDDLParser::parseNextNode( char *in, char *end ) { + in = parseHeader( in, end ); + in = parseStructure( in, end ); + + return in; +} + +char *OpenDDLParser::parseHeader( char *in, char *end ) { + if( nullptr == in || in == end ) { + return in; + } + + Identifier *id( nullptr ); + in = OpenDDLParser::parseIdentifier( in, end, &id ); + +#ifdef DEBUG_HEADER_NAME + if( id ) { + std::cout << id->m_buffer << std::endl; + } +#endif // DEBUG_HEADER_NAME + + in = getNextToken( in, end ); + Property *first( nullptr ); + if( nullptr != id ) { + if( *in == '(' ) { + in++; + Property *prop( nullptr ), *prev( nullptr ); + while( *in != ')' && in != end ) { + in = parseProperty( in, end, &prop ); + in = getNextToken( in, end ); + + if( *in != ',' && *in != ')' ) { + logInvalidTokenError( in, ")", m_logCallback ); + return in; + } + if( nullptr != prop && *in != ',' ) { + if( nullptr == first ) { + first = prop; + } + if( nullptr != prev ) { + prev->m_next = prop; + } + prev = prop; + } + } + in++; + } + + // store the node + DDLNode *node( createDDLNode( id, first, this ) ); + if( nullptr != node ) { + pushNode( node ); + } else { + std::cerr << "nullptr returned by creating DDLNode." << std::endl; + } + + Name *name( nullptr ); + in = OpenDDLParser::parseName( in, end, &name ); + if( nullptr != name ) { + const std::string nodeName( name->m_id->m_buffer ); + node->setName( nodeName ); + } + } + + return in; +} + +char *OpenDDLParser::parseStructure( char *in, char *end ) { + if( nullptr == in || in == end ) { + return in; + } + + in = getNextToken( in, end ); + if( *in == '{' ) { + in++; + in = getNextToken( in, end ); + Value::ValueType type( Value::ddl_none ); + size_t arrayLen( 0 ); + in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen ); + if( Value::ddl_none != type ) { + in = getNextToken( in, end ); + if( *in == '{' ) { + DataArrayList *dtArrayList( nullptr ); + Value *values( nullptr ); + if( 1 == arrayLen ) { + in = parseDataList( in, end, &values ); + if( nullptr != values ){ + DDLNode *currentNode( top() ); + if( nullptr != currentNode ) { + currentNode->setValue( values ); + } + } + } else if( arrayLen > 1 ) { + in = parseDataArrayList( in, end, &dtArrayList ); + if( nullptr != dtArrayList ) { + DDLNode *currentNode( top() ); + if( nullptr != currentNode ) { + currentNode->setDataArrayList( dtArrayList ); + } + } + } else { + std::cerr << "0 for array is invalid." << std::endl; + } + } + + in = getNextToken( in, end ); + if( *in != '}' ) { + logInvalidTokenError( in, "}", m_logCallback ); + } + } else { + in = parseHeader( in, end ); + in = parseStructure( in, end ); + } + } else { + in++; + logInvalidTokenError( in, "{", m_logCallback ); + return in; + + } + + in++; + + return in; +} + +void OpenDDLParser::pushNode( DDLNode *node ) { + if( nullptr == node ) { + return; + } + + m_stack.push_back( node ); +} + +DDLNode *OpenDDLParser::popNode() { + if( m_stack.empty() ) { + return nullptr; + } + + DDLNode *topNode( top() ); + m_stack.pop_back(); + + return topNode; +} + +DDLNode *OpenDDLParser::top() { + if( m_stack.empty() ) { + return nullptr; + } + + DDLNode *top( m_stack.back() ); + return top; +} + +DDLNode *OpenDDLParser::getRoot() const { + if( nullptr == m_context ) { + return nullptr; + } + + return m_context->m_root; +} + +Context *OpenDDLParser::getContext() const { + return m_context; +} + +void OpenDDLParser::normalizeBuffer( char *buffer, size_t len ) { + if( nullptr == buffer || 0 == len ) { + return; + } + + size_t writeIdx( 0 ); + char *end( &buffer[ len ] + 1 ); + for( size_t readIdx = 0; readIdx( c, end ) ) { + buffer[ writeIdx ] = buffer[ readIdx ]; + writeIdx++; + } else { + readIdx++; + // skip the comment and the rest of the line + while( !isEndofLine( buffer[ readIdx ] ) ) { + readIdx++; + } + buffer[writeIdx] = '\n'; + writeIdx++; + } + } + + if( writeIdx < len ) { + buffer[ writeIdx ] = '\0'; + } +} + +char *OpenDDLParser::parseName( char *in, char *end, Name **name ) { + *name = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + // ignore blanks + in = getNextToken( in, end ); + if( *in != '$' && *in != '%' ) { + return in; + } + + NameType ntype( GlobalName ); + if( *in == '%' ) { + ntype = LocalName; + } + + Name *currentName( nullptr ); + Identifier *id( nullptr ); + in = parseIdentifier( in, end, &id ); + if( id ) { + currentName = new Name( ntype, id ); + if( currentName ) { + *name = currentName; + } + } + + return in; +} + +char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) { + *id = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + // ignore blanks + in = getNextToken( in, end ); + + // staring with a number is forbidden + if( isNumeric( *in ) ) { + return in; + } + + // get size of id + size_t idLen( 0 ); + char *start( in ); + while( !isSeparator( *in ) && ( in != end ) && *in != '(' && *in != ')' ) { + in++; + idLen++; + } + + const size_t len( idLen + 1 ); + Identifier *newId = new Identifier( len, new char[ len ] ); + ::strncpy( newId->m_buffer, start, newId->m_len-1 ); + newId->m_buffer[ newId->m_len - 1 ] = '\0'; + *id = newId; + + return in; +} + +char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) { + type = Value::ddl_none; + len = 0; + if( nullptr == in || in == end ) { + return in; + } + + for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) { + const size_t prim_len( strlen( PrimitiveTypeToken[ i ] ) ); + if( 0 == strncmp( in, PrimitiveTypeToken[ i ], prim_len ) ) { + type = ( Value::ValueType ) i; + break; + } + } + + if( Value::ddl_none == type ) { + in = getNextToken( in, end ); + return in; + } else { + in += strlen( PrimitiveTypeToken[ type ] ); + } + + bool ok( true ); + if( *in == '[' ) { + ok = false; + in++; + char *start( in ); + while ( in != end ) { + in++; + if( *in == ']' ) { + len = atoi( start ); + ok = true; + in++; + break; + } + } + } else { + len = 1; + } + if( !ok ) { + type = Value::ddl_none; + } + + return in; +} + +char *OpenDDLParser::parseReference( char *in, char *end, std::vector &names ) { + if( nullptr == in || in == end ) { + return in; + } + + if( 0 != strncmp( in, RefToken, strlen( RefToken ) ) ) { + return false; + } else { + const size_t refTokenLen( strlen( RefToken ) ); + in += refTokenLen; + } + + in = getNextToken( in, end ); + if( '{' != *in ) { + return in; + } else { + in++; + } + + in = getNextToken( in, end ); + Name *nextName( nullptr ); + in = parseName( in, end, &nextName ); + if( nextName ) { + names.push_back( nextName ); + } + while( '}' != *in ) { + in = getNextSeparator( in, end ); + if( ',' == *in ) { + in = parseName( in, end, &nextName ); + if( nextName ) { + names.push_back( nextName ); + } + } else { + break; + } + } + + return in; +} + +char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) { + *boolean = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + in = getNextToken( in, end ); + char *start( in ); + size_t len( 0 ); + while( !isSeparator( *in ) && in != end ) { + in++; + len++; + } + len++; + int res = ::strncmp( BoolTrue, start, strlen( BoolTrue ) ); + if( 0 != res ) { + res = ::strncmp( BoolFalse, start, strlen( BoolFalse ) ); + if( 0 != res ) { + *boolean = nullptr; + return in; + } + *boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); + (*boolean)->setBool( false ); + } else { + *boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); + (*boolean)->setBool( true ); + } + + return in; +} + +char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) { + *integer = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + if( !isIntegerType( integerType ) ) { + return in; + } + + in = getNextToken( in, end ); + char *start( in ); + while( !isSeparator( *in ) && in != end ) { + in++; + } + + if( isNumeric( *start ) ) { + const int value( atoi( start ) ); + *integer = ValueAllocator::allocPrimData( integerType ); + switch( integerType ) { + case Value::ddl_int8: + ( *integer )->setInt8( (int8) value ); + break; + case Value::ddl_int16: + ( *integer )->setInt16( ( int16 ) value ); + break; + case Value::ddl_int32: + ( *integer )->setInt32( ( int32 ) value ); + break; + case Value::ddl_int64: + ( *integer )->setInt64( ( int64 ) value ); + break; + default: + break; + } + } + + return in; +} + +char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating ) { + *floating = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + in = getNextToken( in, end ); + char *start( in ); + while( !isSeparator( *in ) && in != end ) { + in++; + } + + // parse the float value + bool ok( false ); + if( isNumeric( *start ) ) { + ok = true; + } else { + if( *start == '-' ) { + if( isNumeric( *(start+1) ) ) { + ok = true; + } + } + } + + if( ok ) { + const float value( ( float ) atof( start ) ); + *floating = ValueAllocator::allocPrimData( Value::ddl_float ); + ( *floating )->setFloat( value ); + } + + return in; +} + +char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) { + *stringData = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + in = getNextToken( in, end ); + size_t len( 0 ); + char *start( in ); + if( *start == '\"' ) { + start++; + in++; + while( *in != '\"' && in != end ) { + in++; + len++; + } + + *stringData = ValueAllocator::allocPrimData( Value::ddl_string, len + 1 ); + ::strncpy( ( char* ) ( *stringData )->m_data, start, len ); + ( *stringData )->m_data[len] = '\0'; + in++; + } + + return in; +} + +static void createPropertyWithData( Identifier *id, Value *primData, Property **prop ) { + if( nullptr != primData ) { + ( *prop ) = new Property( id ); + ( *prop )->m_primData = primData; + } +} + +char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) { + *data = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + in = getNextToken( in, end ); + if( *in != '0' ) { + return in; + } + + in++; + if( *in != 'x' && *in != 'X' ) { + return in; + } + + in++; + bool ok( true ); + char *start( in ); + int pos( 0 ); + while( !isSeparator( *in ) && in != end ) { + if( ( *in < '0' && *in > '9' ) || ( *in < 'a' && *in > 'f' ) || ( *in < 'A' && *in > 'F' ) ) { + ok = false; + break; + } + pos++; + in++; + } + + if( !ok ) { + return in; + } + + int value( 0 ); + while( pos > 0 ) { + pos--; + value += hex2Decimal( *start ) * static_cast( pow( 16.0, pos ) ); + start++; + } + + *data = ValueAllocator::allocPrimData( Value::ddl_int32 ); + (*data)->setInt32( value ); + + return in; +} + +char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { + *prop = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + in = getNextToken( in, end ); + Identifier *id( nullptr ); + in = parseIdentifier( in, end, &id ); + if( nullptr != id ) { + in = getNextToken( in, end ); + if( *in == '=' ) { + in++; + in = getNextToken( in, end ); + Value *primData( nullptr ); + if( isInteger( in, end ) ) { + in = parseIntegerLiteral( in, end, &primData ); + createPropertyWithData( id, primData, prop ); + } else if( isFloat( in, end ) ) { + in = parseFloatingLiteral( in, end, &primData ); + createPropertyWithData( id, primData, prop ); + } else if( isStringLiteral( *in ) ) { // string data + in = parseStringLiteral( in, end, &primData ); + createPropertyWithData( id, primData, prop ); + } else { // reference data + std::vector names; + in = parseReference( in, end, names ); + if( !names.empty() ) { + Reference *ref = new Reference( names.size(), &names[ 0 ] ); + ( *prop ) = new Property( id ); + ( *prop )->m_ref = ref; + } + } + } + } + + return in; +} + +char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) { + *data = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + in = getNextToken( in, end ); + if( *in == '{' ) { + in++; + Value *current( nullptr ), *prev( nullptr ); + while( '}' != *in ) { + current = nullptr; + in = getNextToken( in, end ); + if( isInteger( in, end ) ) { + in = parseIntegerLiteral( in, end, ¤t ); + } else if( isFloat( in, end ) ) { + in = parseFloatingLiteral( in, end, ¤t ); + } else if( isStringLiteral( *in ) ) { + in = parseStringLiteral( in, end, ¤t ); + } else if( isHexLiteral( in, end ) ) { + in = parseHexaLiteral( in, end, ¤t ); + } + + if( nullptr != current ) { + if( nullptr == *data ) { + *data = current; + prev = current; + } else { + prev->setNext( current ); + prev = current; + } + } + + in = getNextSeparator( in, end ); + if( ',' != *in && '}' != *in && !isSpace( *in ) ) { + break; + } + } + in++; + } + + return in; +} + +char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) { + *dataList = nullptr; + if( nullptr == in || in == end ) { + return in; + } + + in = getNextToken( in, end ); + if( *in == '{' ) { + in++; + Value *current( nullptr ); + DataArrayList *prev( nullptr ), *currentDataList( nullptr ); + do { + in = parseDataList( in, end, ¤t ); + if( nullptr != current ) { + if( nullptr == prev ) { + *dataList = new DataArrayList; + (*dataList)->m_dataList = current; + prev = *dataList; + } else { + currentDataList = new DataArrayList; + if( nullptr != prev ) { + prev->m_next = currentDataList; + prev = currentDataList; + } + } + } + } while( ',' == *in && in != end ); + } + + return in; +} + +const char *OpenDDLParser::getVersion() { + return Version; +} + +END_ODDLPARSER_NS diff --git a/contrib/openddlparser/code/Value.cpp b/contrib/openddlparser/code/Value.cpp new file mode 100644 index 000000000..71e97a566 --- /dev/null +++ b/contrib/openddlparser/code/Value.cpp @@ -0,0 +1,243 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#include +#include +#include + +BEGIN_ODDLPARSER_NS + +Value::Value() +: m_type( ddl_none ) +, m_size( 0 ) +, m_data( nullptr ) +, m_next( nullptr ) { + // empty +} + +Value::~Value() { + // empty +} + +void Value::setBool( bool value ) { + assert( ddl_bool == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +bool Value::getBool() { + assert( ddl_bool == m_type ); + return ( bool ) ( *m_data ); +} + +void Value::setInt8( int8 value ) { + assert( ddl_int8 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +int8 Value::getInt8() { + assert( ddl_int8 == m_type ); + return ( int8 ) ( *m_data ); +} + +void Value::setInt16( int16 value ) { + assert( ddl_int16 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +int16 Value::getInt16() { + assert( ddl_int16 == m_type ); + return ( int16 ) ( *m_data ); +} + +void Value::setInt32( int32 value ) { + assert( ddl_int32 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +int32 Value::getInt32() { + assert( ddl_int32 == m_type ); + return ( int32 ) ( *m_data ); +} + +void Value::setInt64( int64 value ) { + assert( ddl_int32 == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +int64 Value::getInt64() { + return ( int64 ) ( *m_data ); +} + +void Value::setFloat( float value ) { + assert( ddl_float == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +float Value::getFloat() const { + float v; + ::memcpy( &v, m_data, m_size ); + return v; +} + +void Value::setDouble( double value ) { + assert( ddl_double == m_type ); + ::memcpy( m_data, &value, m_size ); +} + +double Value::getDouble() const { + double v; + ::memcpy( &v, m_data, m_size ); + return v; +} + +void Value::dump() { + switch( m_type ) { + case ddl_none: + std::cout << "None" << std::endl; + break; + case ddl_bool: + std::cout << getBool() << std::endl; + break; + case ddl_int8: + std::cout << getInt8() << std::endl; + break; + case ddl_int16: + std::cout << getInt16() << std::endl; + break; + case ddl_int32: + std::cout << getInt32() << std::endl; + break; + case ddl_int64: + std::cout << getInt64() << std::endl; + break; + case ddl_unsigned_int8: + std::cout << "Not supported" << std::endl; + break; + case ddl_unsigned_int16: + std::cout << "Not supported" << std::endl; + break; + case ddl_unsigned_int32: + std::cout << "Not supported" << std::endl; + break; + case ddl_unsigned_int64: + std::cout << "Not supported" << std::endl; + break; + case ddl_half: + std::cout << "Not supported" << std::endl; + break; + case ddl_float: + std::cout << getFloat() << std::endl; + break; + case ddl_double: + std::cout << getDouble() << std::endl; + break; + case ddl_string: + std::cout << "Not supported" << std::endl; + break; + case ddl_ref: + std::cout << "Not supported" << std::endl; + break; + default: + break; + } +} + +void Value::setNext( Value *next ) { + m_next = next; +} + +Value *Value::getNext() const { + return m_next; +} + +Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) { + if( type == Value::ddl_none || Value::ddl_types_max == type ) { + return nullptr; + } + + Value *data = new Value; + data->m_type = type; + switch( type ) { + case Value::ddl_bool: + data->m_size = sizeof( bool ); + break; + case Value::ddl_int8: + data->m_size = sizeof( char ); + break; + case Value::ddl_int16: + data->m_size = sizeof( short ); + break; + case Value::ddl_int32: + data->m_size = sizeof( int ); + break; + case Value::ddl_int64: + data->m_size = sizeof( long ); + break; + case Value::ddl_unsigned_int8: + data->m_size = sizeof( unsigned char ); + break; + case Value::ddl_unsigned_int32: + data->m_size = sizeof( unsigned int ); + break; + case Value::ddl_unsigned_int64: + data->m_size = sizeof( unsigned long ); + break; + case Value::ddl_half: + data->m_size = sizeof( short ); + break; + case Value::ddl_float: + data->m_size = sizeof( float ); + break; + case Value::ddl_double: + data->m_size = sizeof( double ); + break; + case Value::ddl_string: + data->m_size = sizeof( char ); + break; + case Value::ddl_ref: + data->m_size = sizeof( char ); + break; + case Value::ddl_none: + case Value::ddl_types_max: + default: + break; + } + + if( data->m_size ) { + data->m_size *= len; + data->m_data = new unsigned char[ data->m_size ]; + } + + return data; +} + +void ValueAllocator::releasePrimData( Value **data ) { + if( !data ) { + return; + } + + delete *data; + *data = nullptr; +} + + +END_ODDLPARSER_NS diff --git a/contrib/openddlparser/include/openddlparser/DDLNode.h b/contrib/openddlparser/include/openddlparser/DDLNode.h new file mode 100644 index 000000000..ceaff3d5e --- /dev/null +++ b/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -0,0 +1,87 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#pragma once +#ifndef OPENDDLPARSER_DDLNODE_H_INC +#define OPENDDLPARSER_DDLNODE_H_INC + +#include + +#include +#include + +BEGIN_ODDLPARSER_NS + +class Value; +class OpenDDLParser; + +struct Identifier; +struct Reference; +struct Property; +struct DataArrayList; + +class DLL_ODDLPARSER_EXPORT DDLNode { +public: + friend class OpenDDLParser; + + typedef std::vector DllNodeList; + +public: + ~DDLNode(); + void attachParent( DDLNode *parent ); + void detachParent(); + DDLNode *getParent() const; + const DllNodeList &getChildNodeList() const; + void setType( const std::string &name ); + const std::string &getType() const; + void setName( const std::string &name ); + const std::string &getName() const; + void setProperties( Property *first ); + Property *getProperties() const; + void setValue( Value *val ); + Value *getValue() const; + void setDataArrayList( DataArrayList *dtArrayList ); + DataArrayList *getDataArrayList() const; + static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = nullptr ); + +private: + DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = nullptr ); + DDLNode(); + DDLNode( const DDLNode & ); + DDLNode &operator = ( const DDLNode & ); + static void releaseNodes(); + +private: + std::string m_type; + std::string m_name; + DDLNode *m_parent; + std::vector m_children; + Property *m_properties; + Value *m_value; + DataArrayList *m_dtArrayList; + size_t m_idx; + static DllNodeList s_allocatedNodes; +}; + +END_ODDLPARSER_NS + +#endif // OPENDDLPARSER_DDLNODE_H_INC diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h new file mode 100644 index 000000000..490ea46ac --- /dev/null +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -0,0 +1,148 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#pragma once +#ifndef OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC +#define OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC + +#include +#include + +#ifdef _WIN32 +# define TAG_DLL_EXPORT __declspec(dllexport) +# define TAG_DLL_IMPORT __declspec(dllimport ) +# ifdef OPENDDLPARSER_BUILD +# define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT +# else +# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT +# endif // OPENDDLPARSER_BUILD +# pragma warning( disable : 4251 ) +#else +# define DLL_ODDLPARSER_EXPORT +#endif // _WIN32 + +#define BEGIN_ODDLPARSER_NS namespace ODDLParser { +#define END_ODDLPARSER_NS } +#define USE_ODDLPARSER_NS using namespace ODDLParser; + +BEGIN_ODDLPARSER_NS + +class DDLNode; +class Value; + +struct Name; +struct Identifier; +struct Reference; +struct Property; +struct DataArrayList; + +typedef char int8; +typedef short int16; +typedef int int32; +typedef long int64; + +enum NameType { + GlobalName, + LocalName +}; + +struct Name { + NameType m_type; + Identifier *m_id; + + Name( NameType type, Identifier *id ) + : m_type( type ) + , m_id( id ) { + // empty + } +}; + +struct Reference { + size_t m_numRefs; + Name **m_referencedName; + + Reference( size_t numrefs, Name **names ) + : m_numRefs( numrefs ) + , m_referencedName( names ) { + // empty + } +}; + +struct Identifier { + size_t m_len; + char *m_buffer; + + Identifier( size_t len, char *buffer ) + : m_len( len ) + , m_buffer( buffer ) { + // empty + } +}; + +struct Property { + Identifier *m_id; + Value *m_primData; + Reference *m_ref; + Property *m_next; + + Property( Identifier *id ) + : m_id( id ) + , m_primData( nullptr ) + , m_ref( nullptr ) + , m_next( nullptr ) { + // empty + } +}; + +struct DataArrayList { + size_t m_numItems; + Value *m_dataList; + DataArrayList *m_next; + + DataArrayList() + : m_numItems( 0 ) + , m_dataList( nullptr ) + , m_next( nullptr ) { + // empty + } +}; + +struct Context { + Property *m_properties; + DDLNode *m_root; + + Context() + : m_properties( nullptr ) + , m_root( nullptr ) { + // empty + } +}; + +END_ODDLPARSER_NS + +#define ODDL_NO_COPYING( classname ) \ +private: \ + classname( const classname & ); \ + classname &operator = ( const classname & ); + +#endif // OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC + diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h new file mode 100644 index 000000000..9e978ade2 --- /dev/null +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -0,0 +1,233 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#pragma once +#ifndef OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC +#define OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC + +#include + +BEGIN_ODDLPARSER_NS + +template +inline +bool isComment( T *in, T *end ) { + if( *in == '/' ) { + if( in + 1 != end ) { + if( *( in + 1 ) == '/' ) { + return true; + } + } + } + return false; +} + +template +inline +bool isUpperCase( T in ) { + return ( in >= 'A' && in <= 'Z' ); +} + +template +inline +bool isLowerCase( T in ) { + return ( in >= 'a' && in <= 'z' ); +} + +template +inline +bool isSpace( const T in ) { + return ( ' ' == in || '\t' == in ); +} + +template +inline +bool isNewLine( const T in ) { + return ( '\n' == in ); +} + +template +inline +bool isSeparator( T in ) { + if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in ) { + return true; + } + return false; +} + +static const unsigned char chartype_table[ 256 ] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 48-63 + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-95 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 112-127 + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // > 127 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +template +inline +bool isNumeric( const T in ) { + return ( in >= '0' && in <= '9' ); + //return ( chartype_table[in] ); + /*if (in >= '0' && in <= '9' ) + return true; + + return false;*/ +} + +template +inline +bool isInteger( T *in, T *end ) { + if( in != end ) { + if( *in == '-' ) { + in++; + } + } + + bool result( false ); + while( '}' != *in && ',' != *in && !isSpace( *in ) && in != end ) { + result = isNumeric( *in ); + if( !result ) { + break; + } + in++; + } + + return result; +} + +template +inline +bool isFloat( T *in, T *end ) { + if( in != end ) { + if( *in == '-' ) { + in++; + } + } + + // check for <1>.0f + bool result( false ); + while( !isSpace( *in ) && in != end ) { + if( *in == '.' ) { + result = true; + break; + } + result = isNumeric( *in ); + if( !result ) { + return false; + } + in++; + } + + // check for 1<.>0f + if( *in == '.' ) { + in++; + } else { + return false; + } + + // check for 1.<0>f + while( !isSpace( *in ) && in != end && *in != ',' ) { + result = isNumeric( *in ); + if( !result ) { + return false; + } + in++; + } + + return result; +} + +template +inline +bool isCharacter( const T in ) { + return ( in >= 'a' && in <= 'z' || in >= 'A' && in <= 'Z' ); +} + +template +inline +bool isStringLiteral( const T in ) { + return ( in == '\"' ); +} + +template +inline +bool isHexLiteral( T *in, T *end ) { + if( *in == '0' ) { + if( in + 1 != end ) { + if( *( in + 1 ) == 'x' || *( in + 1 ) == 'X' ) { + return true; + } + } + } + + return false; +} + +template +inline +bool isEndofLine( const T in ) { + return ( '\n' == in ); +} + +template +inline +static T *getNextSeparator( T *in, T *end ) { + while( !isSeparator( *in ) || in == end ) { + in++; + } + return in; +} + +static const int ErrorHex2Decimal = 9999; + +inline +int hex2Decimal( char in ) { + if( isNumeric( in ) ) { + return (int) in-48; + } + char hexCodeLower( 'a' ), hexCodeUpper( 'A' ); + for( int i = 0; i<16; i++ ) { + if( in == hexCodeLower + i || in == hexCodeUpper + i ) { + return i+10; + } + } + + return ErrorHex2Decimal; +} + +END_ODDLPARSER_NS + +#endif // OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC diff --git a/contrib/openddlparser/include/openddlparser/Value.h b/contrib/openddlparser/include/openddlparser/Value.h new file mode 100644 index 000000000..665c407ed --- /dev/null +++ b/contrib/openddlparser/include/openddlparser/Value.h @@ -0,0 +1,85 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#pragma once +#ifndef OPENDDLPARSER_VALUE_H_INC +#define OPENDDLPARSER_VALUE_H_INC + +#include + +BEGIN_ODDLPARSER_NS + +class DLL_ODDLPARSER_EXPORT Value { +public: + enum ValueType { + ddl_none = -1, + ddl_bool = 0, + ddl_int8, + ddl_int16, + ddl_int32, + ddl_int64, + ddl_unsigned_int8, + ddl_unsigned_int16, + ddl_unsigned_int32, + ddl_unsigned_int64, + ddl_half, + ddl_float, + ddl_double, + ddl_string, + ddl_ref, + ddl_types_max + }; + + Value(); + ~Value(); + void setBool( bool value ); + bool getBool(); + void setInt8( int8 value ); + int8 getInt8(); + void setInt16( int16 value ); + int16 getInt16(); + void setInt32( int32 value ); + int32 getInt32(); + void setInt64( int64 value ); + int64 getInt64(); + void setFloat( float value ); + float getFloat() const; + void setDouble( double value ); + double getDouble() const; + void dump(); + void setNext( Value *next ); + Value *getNext() const; + + ValueType m_type; + size_t m_size; + unsigned char *m_data; + Value *m_next; +}; + +struct DLL_ODDLPARSER_EXPORT ValueAllocator { + static Value *allocPrimData( Value::ValueType type, size_t len = 1 ); + static void releasePrimData( Value **data ); +}; + +END_ODDLPARSER_NS + +#endif // OPENDDLPARSER_VALUE_H_INC From 8e87613bb3f19d312e801381a6b0576797fcc0ed Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 31 Jan 2015 11:31:39 +0100 Subject: [PATCH 12/39] add mmissing header. Signed-off-by: Kim Kulling --- .../include/openddlparser/OpenDDLParser.h | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 contrib/openddlparser/include/openddlparser/OpenDDLParser.h diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h new file mode 100644 index 000000000..76c5ca7ef --- /dev/null +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h @@ -0,0 +1,117 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#pragma once +#ifndef OPENDDLPARSER_OPENDDLPARSER_H_INC +#define OPENDDLPARSER_OPENDDLPARSER_H_INC + +#include +#include +#include +#include + +#include +#include + +BEGIN_ODDLPARSER_NS + +class DDLNode; +class Value; + +struct Identifier; +struct Reference; +struct Property; + +template +inline +T *getNextToken( T *in, T *end ) { + while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) { + in++; + } + return in; +} + +enum LogSeverity { + ddl_debug_msg = 0, + ddl_info_msg, + ddl_warn_msg, + ddl_error_msg, +}; + +class DLL_ODDLPARSER_EXPORT OpenDDLParser { +public: + typedef void( *logCallback )( LogSeverity severity, const std::string &msg ); + +public: + OpenDDLParser(); + OpenDDLParser( char *buffer, size_t len, bool ownsIt = false ); + ~OpenDDLParser(); + void setLogCallback( logCallback callback ); + logCallback getLogCallback() const; + void setBuffer( char *buffer, size_t len, bool ownsIt = false ); + char *getBuffer() const; + size_t getBufferSize() const; + void clear(); + bool parse(); + char *parseNextNode( char *current, char *end ); + char *parseHeader( char *in, char *end ); + char *parseStructure( char *in, char *end ); + void pushNode( DDLNode *node ); + DDLNode *popNode(); + DDLNode *top(); + DDLNode *getRoot() const; + Context *getContext() const; + +public: // static parser helpers + static void normalizeBuffer( char *buffer, size_t len ); + static char *parseName( char *in, char *end, Name **name ); + static char *parseIdentifier( char *in, char *end, Identifier **id ); + static char *parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ); + static char *parseReference( char *in, char *end, std::vector &names ); + static char *parseBooleanLiteral( char *in, char *end, Value **boolean ); + static char *parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType = Value::ddl_int32 ); + static char *parseFloatingLiteral( char *in, char *end, Value **floating ); + static char *parseStringLiteral( char *in, char *end, Value **stringData ); + static char *parseHexaLiteral( char *in, char *end, Value **data ); + static char *parseProperty( char *in, char *end, Property **prop ); + static char *parseDataList( char *in, char *end, Value **data ); + static char *parseDataArrayList( char *in, char *end, DataArrayList **dataList ); + static const char *getVersion(); + +private: + OpenDDLParser( const OpenDDLParser & ); + OpenDDLParser &operator = ( const OpenDDLParser & ); + +private: + logCallback m_logCallback; + bool m_ownsBuffer; + char *m_buffer; + size_t m_len; + //DDLNode *m_root; + typedef std::vector DDLNodeStack; + DDLNodeStack m_stack; + Context *m_context; +}; + +END_ODDLPARSER_NS + +#endif // OPENDDLPARSER_OPENDDLPARSER_H_INC From e1c6a16b8527147f7ec9ae134b9ae5334da18707 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 31 Jan 2015 11:46:13 +0100 Subject: [PATCH 13/39] support of openddlparser lib without x++11. Signed-off-by: Kim Kulling --- contrib/openddlparser/CMakeLists.txt | 1 + contrib/openddlparser/code/DDLNode.cpp | 18 +-- contrib/openddlparser/code/OpenDDLParser.cpp | 130 +++++++++--------- contrib/openddlparser/code/Value.cpp | 9 +- .../include/openddlparser/OpenDDLCommon.h | 20 ++- .../include/openddlparser/OpenDDLParser.h | 1 - 6 files changed, 92 insertions(+), 87 deletions(-) diff --git a/contrib/openddlparser/CMakeLists.txt b/contrib/openddlparser/CMakeLists.txt index d551c9857..a39d0219f 100644 --- a/contrib/openddlparser/CMakeLists.txt +++ b/contrib/openddlparser/CMakeLists.txt @@ -13,6 +13,7 @@ else() endif() add_definitions( -DOPENDDLPARSER_BUILD ) +add_definitions( -DOPENDDL_NO_USE_CPP11 ) add_definitions( -D_VARIADIC_MAX=10 ) INCLUDE_DIRECTORIES( diff --git a/contrib/openddlparser/code/DDLNode.cpp b/contrib/openddlparser/code/DDLNode.cpp index 30977ca2e..94e8eb4d7 100644 --- a/contrib/openddlparser/code/DDLNode.cpp +++ b/contrib/openddlparser/code/DDLNode.cpp @@ -32,11 +32,11 @@ DDLNode::DllNodeList DDLNode::s_allocatedNodes; template inline static void releaseDataType( T *ptr ) { - if( nullptr == ptr ) { + if( ddl_nullptr == ptr ) { return; } - T *current( nullptr ); + T *current( ddl_nullptr ); while( ptr ) { current = ptr; ptr = ptr->m_next; @@ -49,10 +49,10 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, , m_name( name ) , m_parent( parent ) , m_children() -, m_properties( nullptr ) -, m_value( nullptr ) +, m_properties( ddl_nullptr ) +, m_value( ddl_nullptr ) , m_idx( idx ) -, m_dtArrayList( nullptr ) { +, m_dtArrayList( ddl_nullptr ) { if( m_parent ) { m_parent->m_children.push_back( this ); } @@ -63,9 +63,9 @@ DDLNode::~DDLNode() { releaseDataType( m_value ); delete m_dtArrayList; - m_dtArrayList = nullptr; + m_dtArrayList = ddl_nullptr; if( s_allocatedNodes[ m_idx ] == this ) { - s_allocatedNodes[ m_idx ] = nullptr; + s_allocatedNodes[ m_idx ] = ddl_nullptr; } } @@ -75,7 +75,7 @@ void DDLNode::attachParent( DDLNode *parent ) { } m_parent = parent; - if( nullptr != m_parent ) { + if( ddl_nullptr != m_parent ) { m_parent->m_children.push_back( this ); } } @@ -87,7 +87,7 @@ void DDLNode::detachParent() { if( m_parent->m_children.end() != it ) { m_parent->m_children.erase( it ); } - m_parent = nullptr; + m_parent = ddl_nullptr; } } diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 675d58511..3ae26fdf2 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -73,14 +73,14 @@ static bool isIntegerType( Value::ValueType integerType ) { } static DDLNode *createDDLNode( Identifier *id, Property *first, OpenDDLParser *parser ) { - if( nullptr == id || nullptr == parser ) { - return nullptr; + if( nullptr == id || ddl_nullptr == parser ) { + return ddl_nullptr; } const std::string type( id->m_buffer ); DDLNode *parent( parser->top() ); DDLNode *node = DDLNode::create( type, "", parent ); - if( nullptr != first ) { + if( ddl_nullptr != first ) { node->setProperties( first ); } @@ -108,19 +108,19 @@ static void logMessage( LogSeverity severity, const std::string &msg ) { OpenDDLParser::OpenDDLParser() : m_logCallback( logMessage ) , m_ownsBuffer( false ) -,m_buffer( nullptr ) +, m_buffer( ddl_nullptr ) , m_len( 0 ) , m_stack() -, m_context( nullptr ) { +, m_context( ddl_nullptr ) { // empty } OpenDDLParser::OpenDDLParser( char *buffer, size_t len, bool ownsIt ) : m_logCallback( &logMessage ) , m_ownsBuffer( false ) -, m_buffer( nullptr ) +, m_buffer( ddl_nullptr ) , m_len( 0 ) -, m_context( nullptr ) { +, m_context( ddl_nullptr ) { if( 0 != m_len ) { setBuffer( buffer, len, ownsIt ); } @@ -147,7 +147,7 @@ OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const { void OpenDDLParser::setBuffer( char *buffer, size_t len, bool ownsIt ) { if( m_buffer && m_ownsBuffer ) { delete[] m_buffer; - m_buffer = nullptr; + m_buffer = ddl_nullptr; m_len = 0; } @@ -176,11 +176,11 @@ void OpenDDLParser::clear() { if( m_ownsBuffer ) { delete [] m_buffer; } - m_buffer = nullptr; + m_buffer = ddl_nullptr; m_len = 0; if( m_context ) { - m_context->m_root = nullptr; + m_context->m_root = ddl_nullptr; } DDLNode::releaseNodes(); @@ -194,7 +194,7 @@ bool OpenDDLParser::parse() { normalizeBuffer( m_buffer, m_len ); m_context = new Context; - m_context->m_root = DDLNode::create( "root", "", nullptr ); + m_context->m_root = DDLNode::create( "root", "", ddl_nullptr ); pushNode( m_context->m_root ); // do the main parsing @@ -218,7 +218,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { return in; } - Identifier *id( nullptr ); + Identifier *id( ddl_nullptr ); in = OpenDDLParser::parseIdentifier( in, end, &id ); #ifdef DEBUG_HEADER_NAME @@ -228,11 +228,11 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { #endif // DEBUG_HEADER_NAME in = getNextToken( in, end ); - Property *first( nullptr ); - if( nullptr != id ) { + Property *first( ddl_nullptr ); + if( ddl_nullptr != id ) { if( *in == '(' ) { in++; - Property *prop( nullptr ), *prev( nullptr ); + Property *prop( ddl_nullptr ), *prev( ddl_nullptr ); while( *in != ')' && in != end ) { in = parseProperty( in, end, &prop ); in = getNextToken( in, end ); @@ -241,11 +241,11 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { logInvalidTokenError( in, ")", m_logCallback ); return in; } - if( nullptr != prop && *in != ',' ) { - if( nullptr == first ) { + if( ddl_nullptr != prop && *in != ',' ) { + if( ddl_nullptr == first ) { first = prop; } - if( nullptr != prev ) { + if( ddl_nullptr != prev ) { prev->m_next = prop; } prev = prop; @@ -262,9 +262,9 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { std::cerr << "nullptr returned by creating DDLNode." << std::endl; } - Name *name( nullptr ); + Name *name( ddl_nullptr ); in = OpenDDLParser::parseName( in, end, &name ); - if( nullptr != name ) { + if( ddl_nullptr != name ) { const std::string nodeName( name->m_id->m_buffer ); node->setName( nodeName ); } @@ -288,21 +288,21 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { if( Value::ddl_none != type ) { in = getNextToken( in, end ); if( *in == '{' ) { - DataArrayList *dtArrayList( nullptr ); - Value *values( nullptr ); + DataArrayList *dtArrayList( ddl_nullptr ); + Value *values( ddl_nullptr ); if( 1 == arrayLen ) { in = parseDataList( in, end, &values ); - if( nullptr != values ){ + if( ddl_nullptr != values ){ DDLNode *currentNode( top() ); - if( nullptr != currentNode ) { + if( ddl_nullptr != currentNode ) { currentNode->setValue( values ); } } } else if( arrayLen > 1 ) { in = parseDataArrayList( in, end, &dtArrayList ); - if( nullptr != dtArrayList ) { + if( ddl_nullptr != dtArrayList ) { DDLNode *currentNode( top() ); - if( nullptr != currentNode ) { + if( ddl_nullptr != currentNode ) { currentNode->setDataArrayList( dtArrayList ); } } @@ -341,7 +341,7 @@ void OpenDDLParser::pushNode( DDLNode *node ) { DDLNode *OpenDDLParser::popNode() { if( m_stack.empty() ) { - return nullptr; + return ddl_nullptr; } DDLNode *topNode( top() ); @@ -352,7 +352,7 @@ DDLNode *OpenDDLParser::popNode() { DDLNode *OpenDDLParser::top() { if( m_stack.empty() ) { - return nullptr; + return ddl_nullptr; } DDLNode *top( m_stack.back() ); @@ -361,7 +361,7 @@ DDLNode *OpenDDLParser::top() { DDLNode *OpenDDLParser::getRoot() const { if( nullptr == m_context ) { - return nullptr; + return ddl_nullptr; } return m_context->m_root; @@ -401,8 +401,8 @@ void OpenDDLParser::normalizeBuffer( char *buffer, size_t len ) { } char *OpenDDLParser::parseName( char *in, char *end, Name **name ) { - *name = nullptr; - if( nullptr == in || in == end ) { + *name = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } @@ -417,8 +417,8 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) { ntype = LocalName; } - Name *currentName( nullptr ); - Identifier *id( nullptr ); + Name *currentName( ddl_nullptr ); + Identifier *id( ddl_nullptr ); in = parseIdentifier( in, end, &id ); if( id ) { currentName = new Name( ntype, id ); @@ -431,8 +431,8 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) { } char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) { - *id = nullptr; - if( nullptr == in || in == end ) { + *id = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } @@ -464,7 +464,7 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) { char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) { type = Value::ddl_none; len = 0; - if( nullptr == in || in == end ) { + if( ddl_nullptr == in || in == end ) { return in; } @@ -508,7 +508,7 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy } char *OpenDDLParser::parseReference( char *in, char *end, std::vector &names ) { - if( nullptr == in || in == end ) { + if( ddl_nullptr == in || in == end ) { return in; } @@ -527,7 +527,7 @@ char *OpenDDLParser::parseReference( char *in, char *end, std::vector &na } in = getNextToken( in, end ); - Name *nextName( nullptr ); + Name *nextName( ddl_nullptr ); in = parseName( in, end, &nextName ); if( nextName ) { names.push_back( nextName ); @@ -548,8 +548,8 @@ char *OpenDDLParser::parseReference( char *in, char *end, std::vector &na } char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) { - *boolean = nullptr; - if( nullptr == in || in == end ) { + *boolean = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } @@ -565,7 +565,7 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) if( 0 != res ) { res = ::strncmp( BoolFalse, start, strlen( BoolFalse ) ); if( 0 != res ) { - *boolean = nullptr; + *boolean = ddl_nullptr; return in; } *boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); @@ -579,7 +579,7 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) } char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) { - *integer = nullptr; + *integer = ddl_nullptr; if( nullptr == in || in == end ) { return in; } @@ -619,8 +619,8 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, } char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating ) { - *floating = nullptr; - if( nullptr == in || in == end ) { + *floating = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } @@ -652,8 +652,8 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating } char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) { - *stringData = nullptr; - if( nullptr == in || in == end ) { + *stringData = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } @@ -685,8 +685,8 @@ static void createPropertyWithData( Identifier *id, Value *primData, Property ** } char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) { - *data = nullptr; - if( nullptr == in || in == end ) { + *data = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } @@ -731,20 +731,20 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) { } char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { - *prop = nullptr; - if( nullptr == in || in == end ) { + *prop = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } in = getNextToken( in, end ); - Identifier *id( nullptr ); + Identifier *id( ddl_nullptr ); in = parseIdentifier( in, end, &id ); if( nullptr != id ) { in = getNextToken( in, end ); if( *in == '=' ) { in++; in = getNextToken( in, end ); - Value *primData( nullptr ); + Value *primData( ddl_nullptr ); if( isInteger( in, end ) ) { in = parseIntegerLiteral( in, end, &primData ); createPropertyWithData( id, primData, prop ); @@ -770,17 +770,17 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { } char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) { - *data = nullptr; - if( nullptr == in || in == end ) { + *data = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } in = getNextToken( in, end ); if( *in == '{' ) { in++; - Value *current( nullptr ), *prev( nullptr ); + Value *current( ddl_nullptr ), *prev( ddl_nullptr ); while( '}' != *in ) { - current = nullptr; + current = ddl_nullptr; in = getNextToken( in, end ); if( isInteger( in, end ) ) { in = parseIntegerLiteral( in, end, ¤t ); @@ -792,8 +792,8 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) { in = parseHexaLiteral( in, end, ¤t ); } - if( nullptr != current ) { - if( nullptr == *data ) { + if( ddl_nullptr != current ) { + if( ddl_nullptr == *data ) { *data = current; prev = current; } else { @@ -814,26 +814,26 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) { } char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) { - *dataList = nullptr; - if( nullptr == in || in == end ) { + *dataList = ddl_nullptr; + if( ddl_nullptr == in || in == end ) { return in; } in = getNextToken( in, end ); if( *in == '{' ) { in++; - Value *current( nullptr ); - DataArrayList *prev( nullptr ), *currentDataList( nullptr ); + Value *current( ddl_nullptr ); + DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); do { in = parseDataList( in, end, ¤t ); - if( nullptr != current ) { - if( nullptr == prev ) { + if( ddl_nullptr != current ) { + if( ddl_nullptr == prev ) { *dataList = new DataArrayList; (*dataList)->m_dataList = current; prev = *dataList; } else { currentDataList = new DataArrayList; - if( nullptr != prev ) { + if( ddl_nullptr != prev ) { prev->m_next = currentDataList; prev = currentDataList; } diff --git a/contrib/openddlparser/code/Value.cpp b/contrib/openddlparser/code/Value.cpp index 71e97a566..802e8dd61 100644 --- a/contrib/openddlparser/code/Value.cpp +++ b/contrib/openddlparser/code/Value.cpp @@ -29,8 +29,8 @@ BEGIN_ODDLPARSER_NS Value::Value() : m_type( ddl_none ) , m_size( 0 ) -, m_data( nullptr ) -, m_next( nullptr ) { +, m_data( ddl_nullptr ) +, m_next( ddl_nullptr ) { // empty } @@ -171,7 +171,7 @@ Value *Value::getNext() const { Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) { if( type == Value::ddl_none || Value::ddl_types_max == type ) { - return nullptr; + return ddl_nullptr; } Value *data = new Value; @@ -236,8 +236,7 @@ void ValueAllocator::releasePrimData( Value **data ) { } delete *data; - *data = nullptr; + *data = ddl_nullptr; } - END_ODDLPARSER_NS diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index 490ea46ac..4a3c16782 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -46,6 +46,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. BEGIN_ODDLPARSER_NS +#ifndef OPENDDL_NO_USE_CPP11 +# define ddl_nullptr nullptr +#else +# define ddl_nullptr NULL +#endif + class DDLNode; class Value; @@ -106,9 +112,9 @@ struct Property { Property( Identifier *id ) : m_id( id ) - , m_primData( nullptr ) - , m_ref( nullptr ) - , m_next( nullptr ) { + , m_primData( ddl_nullptr ) + , m_ref( ddl_nullptr ) + , m_next( ddl_nullptr ) { // empty } }; @@ -120,8 +126,8 @@ struct DataArrayList { DataArrayList() : m_numItems( 0 ) - , m_dataList( nullptr ) - , m_next( nullptr ) { + , m_dataList( ddl_nullptr ) + , m_next( ddl_nullptr ) { // empty } }; @@ -131,8 +137,8 @@ struct Context { DDLNode *m_root; Context() - : m_properties( nullptr ) - , m_root( nullptr ) { + : m_properties( ddl_nullptr ) + , m_root( ddl_nullptr ) { // empty } }; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h index 76c5ca7ef..6457e8b74 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h @@ -106,7 +106,6 @@ private: bool m_ownsBuffer; char *m_buffer; size_t m_len; - //DDLNode *m_root; typedef std::vector DDLNodeStack; DDLNodeStack m_stack; Context *m_context; From 0e579bfb06debfec01b68c6a32ea40618500a121 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 31 Jan 2015 12:01:18 +0100 Subject: [PATCH 14/39] openddl-parser: latest greatest. Signed-off-by: Kim Kulling --- contrib/openddlparser/code/OpenDDLParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 3ae26fdf2..0acd9dd39 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -513,7 +513,7 @@ char *OpenDDLParser::parseReference( char *in, char *end, std::vector &na } if( 0 != strncmp( in, RefToken, strlen( RefToken ) ) ) { - return false; + return in; } else { const size_t refTokenLen( strlen( RefToken ) ); in += refTokenLen; From e9dcad418183e0786613a97d424e3ad607401d22 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 31 Jan 2015 21:23:50 +0100 Subject: [PATCH 15/39] openddl-parser: latest greatest. Signed-off-by: Kim Kulling --- contrib/openddlparser/code/DDLNode.cpp | 8 -------- contrib/openddlparser/code/OpenDDLParser.cpp | 12 +++++++----- .../openddlparser/include/openddlparser/DDLNode.h | 2 -- .../include/openddlparser/OpenDDLCommon.h | 14 ++++++++++++++ 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/contrib/openddlparser/code/DDLNode.cpp b/contrib/openddlparser/code/DDLNode.cpp index 94e8eb4d7..d7c034ba1 100644 --- a/contrib/openddlparser/code/DDLNode.cpp +++ b/contrib/openddlparser/code/DDLNode.cpp @@ -116,14 +116,6 @@ const std::string &DDLNode::getName() const { return m_name; } -void DDLNode::setProperties( Property *first ) { - m_properties = first; -} - -Property *DDLNode::getProperties() const { - return m_properties; -} - void DDLNode::setValue( Value *val ) { m_value = val; } diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 0acd9dd39..66f55f057 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -72,7 +72,7 @@ static bool isIntegerType( Value::ValueType integerType ) { return true; } -static DDLNode *createDDLNode( Identifier *id, Property *first, OpenDDLParser *parser ) { +static DDLNode *createDDLNode( Identifier *id, OpenDDLParser *parser ) { if( nullptr == id || ddl_nullptr == parser ) { return ddl_nullptr; } @@ -80,9 +80,6 @@ static DDLNode *createDDLNode( Identifier *id, Property *first, OpenDDLParser *p const std::string type( id->m_buffer ); DDLNode *parent( parser->top() ); DDLNode *node = DDLNode::create( type, "", parent ); - if( ddl_nullptr != first ) { - node->setProperties( first ); - } return node; } @@ -254,8 +251,13 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { in++; } + // set the properties + if( ddl_nullptr != first ) { + m_context->setProperties( first ); + } + // store the node - DDLNode *node( createDDLNode( id, first, this ) ); + DDLNode *node( createDDLNode( id, this ) ); if( nullptr != node ) { pushNode( node ); } else { diff --git a/contrib/openddlparser/include/openddlparser/DDLNode.h b/contrib/openddlparser/include/openddlparser/DDLNode.h index ceaff3d5e..85b542b5e 100644 --- a/contrib/openddlparser/include/openddlparser/DDLNode.h +++ b/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -55,8 +55,6 @@ public: const std::string &getType() const; void setName( const std::string &name ); const std::string &getName() const; - void setProperties( Property *first ); - Property *getProperties() const; void setValue( Value *val ); Value *getValue() const; void setDataArrayList( DataArrayList *dtArrayList ); diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index 4a3c16782..65530c866 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -141,8 +141,22 @@ struct Context { , m_root( ddl_nullptr ) { // empty } + + void setProperties( Property *first ); + Property *getProperties() const; }; + +inline +void Context::setProperties( Property *first ) { + m_properties = first; +} + +inline +Property *Context::getProperties() const { + return m_properties; +} + END_ODDLPARSER_NS #define ODDL_NO_COPYING( classname ) \ From 20b3ce6a40fc02c845c48c3919c1c5180bef3b8e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 7 Feb 2015 12:47:53 +0100 Subject: [PATCH 16/39] replace opengexparser by using openddl-parser. Signed-off-by: Kim Kulling --- CMakeLists.txt | 3 + code/CMakeLists.txt | 4 +- code/ImporterRegistry.cpp | 88 ++-- code/OpenGEXImporter.cpp | 37 +- code/OpenGEXImporter.h | 7 +- code/OpenGEXParser.cpp | 409 ------------------ code/OpenGEXParser.h | 121 ------ contrib/openddlparser/code/DDLNode.cpp | 8 + contrib/openddlparser/code/OpenDDLParser.cpp | 101 +++-- .../include/openddlparser/DDLNode.h | 2 + .../include/openddlparser/OpenDDLCommon.h | 27 +- .../include/openddlparser/OpenDDLParser.h | 23 +- .../include/openddlparser/Value.h | 30 +- 13 files changed, 190 insertions(+), 670 deletions(-) delete mode 100644 code/OpenGEXParser.cpp delete mode 100644 code/OpenGEXParser.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 618f46a54..267f471c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,9 @@ endif(NOT ZLIB_FOUND) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) add_subdirectory( contrib/openddlparser ) +INCLUDE_DIRECTORIES( contrib/openddlparser/include ) +SET( OPENDDL_PARSER_LIBRARIES openddl_parser ) + # Search for unzip if (PKG_CONFIG_FOUND) PKG_CHECK_MODULES(UNZIP minizip) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 162e9a2ef..40ddb1215 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -353,8 +353,6 @@ SOURCE_GROUP( Ogre FILES ${Ogre_SRCS}) SET( OpenGEX_SRCS OpenGEXImporter.cpp OpenGEXImporter.h - OpenGEXParser.cpp - OpenGEXParser.h OpenGEXStructs.h ) SOURCE_GROUP( OpenGEX FILES ${OpenGEX_SRCS}) @@ -729,7 +727,7 @@ SET( assimp_src ADD_LIBRARY( assimp ${assimp_src} ) -TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES}) +TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} ) if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM) set(ASSIMP_ANDROID_JNIIOSYSTEM_PATH port/AndroidJNI) diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index ec804d141..ea9e7526c 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -178,130 +178,130 @@ namespace Assimp { // ------------------------------------------------------------------------------------------------ void GetImporterInstanceList(std::vector< BaseImporter* >& out) { - // ---------------------------------------------------------------------------- - // Add an instance of each worker class here - // (register_new_importers_here) - // ---------------------------------------------------------------------------- - out.reserve(64); + // ---------------------------------------------------------------------------- + // Add an instance of each worker class here + // (register_new_importers_here) + // ---------------------------------------------------------------------------- + out.reserve(64); #if (!defined ASSIMP_BUILD_NO_X_IMPORTER) - out.push_back( new XFileImporter()); + out.push_back( new XFileImporter()); #endif #if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER) - out.push_back( new ObjFileImporter()); + out.push_back( new ObjFileImporter()); #endif #if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER) - out.push_back( new Discreet3DSImporter()); + out.push_back( new Discreet3DSImporter()); #endif #if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER) - out.push_back( new MD3Importer()); + out.push_back( new MD3Importer()); #endif #if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER) - out.push_back( new MD2Importer()); + out.push_back( new MD2Importer()); #endif #if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER) - out.push_back( new PLYImporter()); + out.push_back( new PLYImporter()); #endif #if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER) - out.push_back( new MDLImporter()); + out.push_back( new MDLImporter()); #endif #if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER) - out.push_back( new ASEImporter()); + out.push_back( new ASEImporter()); #endif #if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER) - out.push_back( new HMPImporter()); + out.push_back( new HMPImporter()); #endif #if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER) - out.push_back( new SMDImporter()); + out.push_back( new SMDImporter()); #endif #if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER) - out.push_back( new MDCImporter()); + out.push_back( new MDCImporter()); #endif #if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER) - out.push_back( new MD5Importer()); + out.push_back( new MD5Importer()); #endif #if (!defined ASSIMP_BUILD_NO_STL_IMPORTER) - out.push_back( new STLImporter()); + out.push_back( new STLImporter()); #endif #if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER) - out.push_back( new LWOImporter()); + out.push_back( new LWOImporter()); #endif #if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER) - out.push_back( new DXFImporter()); + out.push_back( new DXFImporter()); #endif #if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER) - out.push_back( new NFFImporter()); + out.push_back( new NFFImporter()); #endif #if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER) - out.push_back( new RAWImporter()); + out.push_back( new RAWImporter()); #endif #if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER) - out.push_back( new OFFImporter()); + out.push_back( new OFFImporter()); #endif #if (!defined ASSIMP_BUILD_NO_AC_IMPORTER) - out.push_back( new AC3DImporter()); + out.push_back( new AC3DImporter()); #endif #if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER) - out.push_back( new BVHLoader()); + out.push_back( new BVHLoader()); #endif #if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER) - out.push_back( new IRRMeshImporter()); + out.push_back( new IRRMeshImporter()); #endif #if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER) - out.push_back( new IRRImporter()); + out.push_back( new IRRImporter()); #endif #if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER) - out.push_back( new Q3DImporter()); + out.push_back( new Q3DImporter()); #endif #if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER) - out.push_back( new B3DImporter()); + out.push_back( new B3DImporter()); #endif #if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER) - out.push_back( new ColladaLoader()); + out.push_back( new ColladaLoader()); #endif #if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER) - out.push_back( new TerragenImporter()); + out.push_back( new TerragenImporter()); #endif #if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER) - out.push_back( new CSMImporter()); + out.push_back( new CSMImporter()); #endif #if (!defined ASSIMP_BUILD_NO_3D_IMPORTER) - out.push_back( new UnrealImporter()); + out.push_back( new UnrealImporter()); #endif #if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER) - out.push_back( new LWSImporter()); + out.push_back( new LWSImporter()); #endif #if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER) - out.push_back( new Ogre::OgreImporter()); + out.push_back( new Ogre::OgreImporter()); #endif #if (!defined ASSIMP_BUILD_NO_OPEMGEX_IMPORTER ) out.push_back( new OpenGEX::OpenGEXImporter() ); #endif #if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER) - out.push_back( new MS3DImporter()); + out.push_back( new MS3DImporter()); #endif #if (!defined ASSIMP_BUILD_NO_COB_IMPORTER) - out.push_back( new COBImporter()); + out.push_back( new COBImporter()); #endif #if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER) - out.push_back( new BlenderImporter()); + out.push_back( new BlenderImporter()); #endif #if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER) - out.push_back( new Q3BSPFileImporter() ); + out.push_back( new Q3BSPFileImporter() ); #endif #if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER) - out.push_back( new NDOImporter() ); + out.push_back( new NDOImporter() ); #endif #if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER) - out.push_back( new IFCImporter() ); + out.push_back( new IFCImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_XGL_IMPORTER ) - out.push_back( new XGLImporter() ); + out.push_back( new XGLImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER ) - out.push_back( new FBXImporter() ); + out.push_back( new FBXImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER ) - out.push_back( new AssbinImporter() ); + out.push_back( new AssbinImporter() ); #endif } diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index f385cc11d..7de3eaaea 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -41,9 +41,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" #include "OpenGEXImporter.h" -#include "OpenGEXParser.h" #include "DefaultIOSystem.h" +#include + #include static const aiImporterDesc desc = { @@ -62,6 +63,8 @@ static const aiImporterDesc desc = { namespace Assimp { namespace OpenGEX { + USE_ODDLPARSER_NS + //------------------------------------------------------------------------------------------------ OpenGEXImporter::OpenGEXImporter() { @@ -95,8 +98,14 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce std::vector buffer; TextFileToBuffer( file, buffer ); - OpenGEXParser myParser( buffer ); - myParser.parse(); + + OpenDDLParser myParser; + myParser.setBuffer( &buffer[ 0 ], buffer.size() ); + bool success( myParser.parse() ); + if( success ) { + Context *ctx = myParser.getContext(); + importMetric( ctx ); + } } //------------------------------------------------------------------------------------------------ @@ -109,6 +118,28 @@ void OpenGEXImporter::SetupProperties( const Importer *pImp ) { } +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::importMetric( Context *ctx ) { + if( NULL == ctx || NULL == ctx->getProperties() ) { + return; + } + + Property *prop = ctx->getProperties(); + while( NULL != prop ) { + prop = prop->m_next; + } +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::ParseGeoObject() { + +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::ParseMaterial() { + +} + //------------------------------------------------------------------------------------------------ } // Namespace OpenGEX diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 821692c25..601721704 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -44,6 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BaseImporter.h" + +namespace ODDLParser { + struct Context; +} + namespace Assimp { namespace OpenGEX { @@ -72,7 +77,7 @@ public: virtual void SetupProperties( const Importer *pImp ); protected: - void ParseMetric(); + void importMetric( ODDLParser::Context *ctx ); void ParseGeoObject(); void ParseMaterial(); }; diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp deleted file mode 100644 index 3dcc83e44..000000000 --- a/code/OpenGEXParser.cpp +++ /dev/null @@ -1,409 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2014, 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 "AssimpPCH.h" -#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER - -#include "OpenGEXParser.h" -#include "OpenGEXStructs.h" -#include "ParsingUtils.h" -#include "fast_atof.h" - -#include - -namespace Assimp { -namespace OpenGEX { - -//------------------------------------------------------------------------------------------------ -static const std::string Metric = "Metric"; -static const std::string GeometryNode = "GeometryNode"; -static const std::string GeometryObject = "GeometryObject"; -static const std::string Material = "Material"; -static const size_t NumObjects = 4; -static const std::string RootNodes[ NumObjects ] = { - Metric, - GeometryNode, - GeometryObject, - Material -}; - -static const size_t NumSeparator = 4; -static const std::string Separator[ NumSeparator ] = { - "(", ")", "{", "}" -}; - - -static const size_t NumToken = 8; -static const std::string Token[ NumToken ] = { - RootNodes[ 0 ], - RootNodes[ 1 ], - RootNodes[ 2 ], - RootNodes[ 3 ], - Separator[ 0 ], - Separator[ 1 ], - Separator[ 2 ], - Separator[ 3 ] -}; - -static bool isSeparator( char in ) { - return ( in == '(' || in == ')' || in == '{' || in == '}' ); -} - -static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, - size_t numNodes, std::string &tokenFound ) { - tokenFound = ""; - if( 0 == numNodes ) { - return false; - } - - bool found( false ); - for( size_t i = 0; i < numNodes; ++i ) { - if( TokenMatch( bufferPtr, nodes[ i ].c_str(), nodes[ i ].size() ) ) { - tokenFound = nodes[ i ]; - found = true; - break; - } - } - - return found; -} - -static OpenGEXParser::TokenType getTokenTypeByName( const char *in ) { - ai_assert( NULL != in ); - - OpenGEXParser::TokenType type( OpenGEXParser::None ); - for( size_t i = 0; i < NumToken; ++i ) { - if( TokenMatch( in, Token[ i ].c_str(), Token[ i ].size() ) ) { - type = static_cast( i+1 ); - break; - } - } - - return type; -} - -static void removeQuotes( std::string &attribName ) { - std::string tmp; - for( unsigned int i = 0; i < attribName.size(); ++i ) { - if( attribName[ i ] != '\"' ) { - tmp += attribName[ i ]; - } - } - attribName = tmp; -} - -//------------------------------------------------------------------------------------------------ -OpenGEXParser::OpenGEXParser( const std::vector &buffer ) -: m_buffer( buffer ) -, m_index( 0 ) -, m_buffersize( buffer.size() ) -, m_nodeTypeStack() { - // empty -} - -//------------------------------------------------------------------------------------------------ -OpenGEXParser::~OpenGEXParser() { - -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXParser::parse() { - while( parseNextNode() ) { - - } -} - -//------------------------------------------------------------------------------------------------ -std::string OpenGEXParser::getNextToken() { - std::string token; - while( m_index < m_buffersize && IsSpace( m_buffer[ m_index ] ) ) { - m_index++; - } - - while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) && !isSeparator( m_buffer[ m_index ] ) ) { - token += m_buffer[ m_index ]; - m_index++; - } - - if( token == "//" ) { - skipComments(); - token = getNextToken(); - } - - if( token.empty() ) { - if( isSeparator( m_buffer[ m_index ] ) ) { - token += m_buffer[ m_index ]; - m_index++; - } - } - - return token; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::skipComments() { - bool skipped( false ); - if( strncmp( &m_buffer[ m_index ], "//", 2 ) == 0) { - while( !IsLineEnd( m_buffer[ m_index ] ) ) { - ++m_index; - } - skipped = true; - } - - return skipped; -} - -//------------------------------------------------------------------------------------------------ -void OpenGEXParser::readUntilEndOfLine() { - while( !IsLineEnd( m_buffer[ m_index ] ) ) { - ++m_index; - } - ++m_index; - if( IsLineEnd( m_buffer[ m_index ] ) ) { - ++m_index; - } -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::parseNextNode() { - std::string token( getNextToken() ); - std::string rootNodeName, nodeType; - if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, rootNodeName ) ) { - m_nodeTypeStack.push_back( getTokenTypeByName( rootNodeName.c_str() ) ); - if( !getNodeHeader( nodeType ) ) { - return false; - } - - if( !getNodeData( nodeType ) ) { - return false; - } - - readUntilEndOfLine(); - - m_nodeTypeStack.pop_back(); - - } - - return true; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getNodeHeader( std::string &name ) { - bool success( false ); - TokenType tokenType( m_nodeTypeStack.back() ); - if( tokenType == MetricNode ) { - if( getMetricAttributeKey( name ) ) { - success = true; - } - } else if( tokenType == GeometryNode ) { - - } else if( tokenType == GeometryObject ) { - - } else if( tokenType == Material ) { - - } else { - DefaultLogger::get()->warn( "Unknown token type in file." ); - } - - return success; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getBracketOpen() { - const std::string token( getNextToken() ); - if( "{" == token ) { - return true; - } - - return false; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getBracketClose() { - const std::string token( getNextToken() ); - if( "}" == token ) { - return true; - } - - return false; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getStringData( std::string &data ) { - if( !getBracketOpen() ) { - return false; - } - - if( !getBracketClose() ) { - return false; - } - return false; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getFloatData( size_t num, float *data ) { - ai_assert( NULL != data ); - - std::string tk; - tk = getNextToken(); - - if( !getBracketOpen() ) { - return false; - } - - bool ok( true ); - size_t dataIdx( 0 ); - for( unsigned int i = 0; i < num; ++i ) { - data[ dataIdx ] = fast_atof( &m_buffer[ m_index ] ); - ++dataIdx; - tk = getNextToken(); - if( tk == "," ) { - if( i >= ( num - 1 ) ) { - ok = false; - break; - } - } - } - - if( !getBracketClose() ) { - return false; - } - - return ok; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getNodeData( const std::string &nodeType ) { - bool success( false ); - - if( !getBracketOpen() ) { - return false; - } - - const TokenType type( m_nodeTypeStack.back() ); - if( type == MetricNode ) { - success = onMetricNode( nodeType ); - } else if( type == GeometryNode ) { - success = onGeometryNode(); - } else if( type == GeometryObject ) { - success = onGeometryObject(); - } else if( type == Material ) { - success = onMaterial(); - } else { - DefaultLogger::get()->warn( "Unknown token type in file." ); - } - - if( !getBracketClose() ) { - return false; - } - - return success; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::getMetricAttributeKey( std::string &attribName ) { - bool ok( false ); - attribName = ""; - std::string token( getNextToken() ); - if( token[ 0 ] == '(' ) { - // get attribute - token = getNextToken(); - if( "key" == token ) { - std::string equal = getNextToken(); - attribName = getNextToken(); - token = getNextToken(); - if( token[ 0 ] == ')' ) { - ok = true; - removeQuotes( attribName ); - } - } - } - - return ok; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::onMetricNode( const std::string &attribName ) { - float value( 0.0f ); - bool success( true ); - if( "distance" == attribName ) { - if( getFloatData( 1, &value ) ) { - m_model.m_metrics.m_distance = value; - } - } else if( "angle" == attribName ) { - if( getFloatData( 1, &value ) ) { - m_model.m_metrics.m_angle = value; - } - } else if( "time" == attribName ) { - if( getFloatData( 1, &value ) ) { - m_model.m_metrics.m_time = value; - } - } else if( "up" == attribName ) { - std::string up; - if( getStringData( up ) ) { - m_model.m_metrics.m_up = up; - } - } else { - success = false; - } - - return success; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::onGeometryNode() { - return true; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::onGeometryObject() { - return true; -} - -//------------------------------------------------------------------------------------------------ -bool OpenGEXParser::onMaterial() { - return true; -} - -//------------------------------------------------------------------------------------------------ - -} // Namespace OpenGEX -} // Namespace Assimp - -#endif ASSIMP_BUILD_NO_OPEMGEX_IMPORTER diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h deleted file mode 100644 index 64debe43c..000000000 --- a/code/OpenGEXParser.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2014, 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 ASSIMP_OPENGEX_OPENGEXPARSER_H_INC -#define ASSIMP_OPENGEX_OPENGEXPARSER_H_INC - -#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER - -#include -#include - -namespace Assimp { -namespace OpenGEX { - -struct OpenGEXModel { - struct Metrics { - float m_distance; - float m_angle; - float m_time; - std::string m_up; - - Metrics() - : m_distance( 0.0f ) - , m_angle( 0.0f ) - , m_time( 0.0f ) - , m_up() { - // empty - } - } m_metrics; -}; - -class OpenGEXParser { -public: - enum TokenType { - None = 0, - MetricNode, - GeometryNode, - GeometryObject, - Material, - BracketIn, - BracketOut, - CurlyBracketIn, - CurlyBracketOut, - }; - -public: - OpenGEXParser( const std::vector &buffer ); - ~OpenGEXParser(); - void parse(); - -protected: - std::string getNextToken(); - bool skipComments(); - void readUntilEndOfLine(); - bool parseNextNode(); - bool getNodeHeader( std::string &name ); - bool getBracketOpen(); - bool getBracketClose(); - bool getStringData( std::string &data ); - bool getFloatData( size_t num, float *data ); - bool getNodeData( const std::string &nodeType ); - bool getMetricAttributeKey( std::string &attribName ); - bool onMetricNode( const std::string &attribName ); - bool onGeometryNode(); - bool onGeometryObject(); - bool onMaterial(); - -private: - OpenGEXParser( const OpenGEXParser & ); - OpenGEXParser &operator = ( const OpenGEXParser & ); - -private: - const std::vector &m_buffer; - std::vector m_nodeTypeStack; - OpenGEXModel m_model; - size_t m_index; - size_t m_buffersize; -}; - -} // Namespace openGEX -} // Namespace Assimp - -#endif // ASSIMP_BUILD_NO_OPEMGEX_IMPORTER - -#endif // ASSIMP_OPENGEX_OPENGEXPARSER_H_INC diff --git a/contrib/openddlparser/code/DDLNode.cpp b/contrib/openddlparser/code/DDLNode.cpp index d7c034ba1..aba11d8ae 100644 --- a/contrib/openddlparser/code/DDLNode.cpp +++ b/contrib/openddlparser/code/DDLNode.cpp @@ -116,6 +116,14 @@ const std::string &DDLNode::getName() const { return m_name; } +void DDLNode::setProperties( Property *prop ) { + m_properties = prop; +} + +Property *DDLNode::getProperties() const { + return m_properties; +} + void DDLNode::setValue( Value *val ) { m_value = val; } diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 66f55f057..684eb20b7 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -104,22 +104,18 @@ static void logMessage( LogSeverity severity, const std::string &msg ) { OpenDDLParser::OpenDDLParser() : m_logCallback( logMessage ) -, m_ownsBuffer( false ) -, m_buffer( ddl_nullptr ) -, m_len( 0 ) +, m_buffer() , m_stack() , m_context( ddl_nullptr ) { // empty } -OpenDDLParser::OpenDDLParser( char *buffer, size_t len, bool ownsIt ) +OpenDDLParser::OpenDDLParser( char *buffer, size_t len ) : m_logCallback( &logMessage ) -, m_ownsBuffer( false ) -, m_buffer( ddl_nullptr ) -, m_len( 0 ) +, m_buffer() , m_context( ddl_nullptr ) { - if( 0 != m_len ) { - setBuffer( buffer, len, ownsIt ); + if( 0 != len ) { + setBuffer( buffer, len ); } } @@ -141,41 +137,36 @@ OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const { return m_logCallback; } -void OpenDDLParser::setBuffer( char *buffer, size_t len, bool ownsIt ) { - if( m_buffer && m_ownsBuffer ) { - delete[] m_buffer; - m_buffer = ddl_nullptr; - m_len = 0; +void OpenDDLParser::setBuffer( char *buffer, size_t len ) { + clear(); + if( 0 == len ) { + return; } - m_ownsBuffer = ownsIt; - if( m_ownsBuffer ) { - // when we are owning the buffer we will do a deep copy - m_buffer = new char[ len ]; - m_len = len; - ::memcpy( m_buffer, buffer, len ); - } else { - // when we are not owning the buffer, we just do a shallow copy - m_buffer = buffer; - m_len = len; - } + m_buffer.resize( len ); + ::memcpy(&m_buffer[ 0 ], buffer, len ); } -char *OpenDDLParser::getBuffer() const { - return m_buffer; +void OpenDDLParser::setBuffer( const std::vector &buffer ) { + clear(); + m_buffer.resize( buffer.size() ); + std::copy( buffer.begin(), buffer.end(), m_buffer.begin() ); +} + +const char *OpenDDLParser::getBuffer() const { + if( m_buffer.empty() ) { + return ddl_nullptr; + } + + return &m_buffer[ 0 ]; } size_t OpenDDLParser::getBufferSize() const { - return m_len; + return m_buffer.size(); } void OpenDDLParser::clear() { - if( m_ownsBuffer ) { - delete [] m_buffer; - } - m_buffer = ddl_nullptr; - m_len = 0; - + m_buffer.resize( 0 ); if( m_context ) { m_context->m_root = ddl_nullptr; } @@ -184,11 +175,11 @@ void OpenDDLParser::clear() { } bool OpenDDLParser::parse() { - if( 0 == m_len ) { + if( m_buffer.empty() ) { return false; } - normalizeBuffer( m_buffer, m_len ); + normalizeBuffer( m_buffer ); m_context = new Context; m_context->m_root = DDLNode::create( "root", "", ddl_nullptr ); @@ -196,9 +187,11 @@ bool OpenDDLParser::parse() { // do the main parsing char *current( &m_buffer[ 0 ] ); - char *end( &m_buffer[ m_len - 1 ] + 1 ); - while( current != end ) { + char *end( &m_buffer[ m_buffer.size() - 1 ] + 1 ); + size_t pos( current - &m_buffer[ 0 ] ); + while( pos < m_buffer.size() ) { current = parseNextNode( current, end ); + pos = current - &m_buffer[ 0 ]; } return true; } @@ -219,7 +212,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { in = OpenDDLParser::parseIdentifier( in, end, &id ); #ifdef DEBUG_HEADER_NAME - if( id ) { + if( ddl_nullptr != id ) { std::cout << id->m_buffer << std::endl; } #endif // DEBUG_HEADER_NAME @@ -253,7 +246,11 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { // set the properties if( ddl_nullptr != first ) { - m_context->setProperties( first ); + std::cout << id->m_buffer << std::endl; + DDLNode *current( top() ); + if( current ) { + current->setProperties( first ); + } } // store the node @@ -317,6 +314,9 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { if( *in != '}' ) { logInvalidTokenError( in, "}", m_logCallback ); } + else { + in++; + } } else { in = parseHeader( in, end ); in = parseStructure( in, end ); @@ -327,6 +327,7 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { return in; } + in = getNextToken( in, end ); in++; @@ -373,33 +374,29 @@ Context *OpenDDLParser::getContext() const { return m_context; } -void OpenDDLParser::normalizeBuffer( char *buffer, size_t len ) { - if( nullptr == buffer || 0 == len ) { +void OpenDDLParser::normalizeBuffer( std::vector &buffer) { + if( buffer.empty() ) { return; } - size_t writeIdx( 0 ); - char *end( &buffer[ len ] + 1 ); + std::vector newBuffer; + const size_t len( buffer.size() ); + char *end( &buffer[ len-1 ] + 1 ); for( size_t readIdx = 0; readIdx( c, end ) ) { - buffer[ writeIdx ] = buffer[ readIdx ]; - writeIdx++; + newBuffer.push_back( buffer[ readIdx ] ); } else { readIdx++; // skip the comment and the rest of the line while( !isEndofLine( buffer[ readIdx ] ) ) { readIdx++; } - buffer[writeIdx] = '\n'; - writeIdx++; + newBuffer.push_back( '\n' ); } } - - if( writeIdx < len ) { - buffer[ writeIdx ] = '\0'; - } + buffer = newBuffer; } char *OpenDDLParser::parseName( char *in, char *end, Name **name ) { diff --git a/contrib/openddlparser/include/openddlparser/DDLNode.h b/contrib/openddlparser/include/openddlparser/DDLNode.h index 85b542b5e..d5b4a56c9 100644 --- a/contrib/openddlparser/include/openddlparser/DDLNode.h +++ b/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -55,6 +55,8 @@ public: const std::string &getType() const; void setName( const std::string &name ); const std::string &getName() const; + void setProperties( Property *prop ); + Property *getProperties() const; void setValue( Value *val ); Value *getValue() const; void setDataArrayList( DataArrayList *dtArrayList ); diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index 65530c866..789bc15ad 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -25,6 +25,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC #include +#include + #include #ifdef _WIN32 @@ -133,29 +135,24 @@ struct DataArrayList { }; struct Context { - Property *m_properties; DDLNode *m_root; Context() - : m_properties( ddl_nullptr ) - , m_root( ddl_nullptr ) { + : m_root( ddl_nullptr ) { // empty } - - void setProperties( Property *first ); - Property *getProperties() const; }; +struct BufferIt { + std::vector m_buffer; + size_t m_idx; -inline -void Context::setProperties( Property *first ) { - m_properties = first; -} - -inline -Property *Context::getProperties() const { - return m_properties; -} + BufferIt( const std::vector &buffer ) + : m_buffer( buffer ) + , m_idx( 0 ) { + // empty + } +}; END_ODDLPARSER_NS diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h index 6457e8b74..4f003a0e4 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h @@ -50,11 +50,12 @@ T *getNextToken( T *in, T *end ) { return in; } +/// @brief Defines the log severity. enum LogSeverity { - ddl_debug_msg = 0, - ddl_info_msg, - ddl_warn_msg, - ddl_error_msg, + ddl_debug_msg = 0, ///< Debug message, for debugging + ddl_info_msg, ///< Info messages, normal mode + ddl_warn_msg, ///< Parser warnings + ddl_error_msg ///< Parser errors }; class DLL_ODDLPARSER_EXPORT OpenDDLParser { @@ -63,12 +64,13 @@ public: public: OpenDDLParser(); - OpenDDLParser( char *buffer, size_t len, bool ownsIt = false ); + OpenDDLParser( char *buffer, size_t len ); ~OpenDDLParser(); void setLogCallback( logCallback callback ); logCallback getLogCallback() const; - void setBuffer( char *buffer, size_t len, bool ownsIt = false ); - char *getBuffer() const; + void setBuffer( char *buffer, size_t len ); + void setBuffer( const std::vector &buffer ); + const char *getBuffer() const; size_t getBufferSize() const; void clear(); bool parse(); @@ -82,7 +84,7 @@ public: Context *getContext() const; public: // static parser helpers - static void normalizeBuffer( char *buffer, size_t len ); + static void normalizeBuffer( std::vector &buffer ); static char *parseName( char *in, char *end, Name **name ); static char *parseIdentifier( char *in, char *end, Identifier **id ); static char *parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ); @@ -103,9 +105,8 @@ private: private: logCallback m_logCallback; - bool m_ownsBuffer; - char *m_buffer; - size_t m_len; + std::vector m_buffer; + typedef std::vector DDLNodeStack; DDLNodeStack m_stack; Context *m_context; diff --git a/contrib/openddlparser/include/openddlparser/Value.h b/contrib/openddlparser/include/openddlparser/Value.h index 665c407ed..0d719f994 100644 --- a/contrib/openddlparser/include/openddlparser/Value.h +++ b/contrib/openddlparser/include/openddlparser/Value.h @@ -28,20 +28,28 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. BEGIN_ODDLPARSER_NS +///------------------------------------------------------------------------------------------------ +/// @brief This class implements a value. +/// +/// Values are used to store data types like boolean, integer, floats, double and many mode. To get +/// an overview please check the enum VylueType ( @see Value::ValueType ). +/// Values can be single items or lists of items. They are implemented as linked lists. +///------------------------------------------------------------------------------------------------ class DLL_ODDLPARSER_EXPORT Value { public: + /// @brief This enum describes the data type stored in the value. enum ValueType { - ddl_none = -1, - ddl_bool = 0, - ddl_int8, - ddl_int16, - ddl_int32, - ddl_int64, - ddl_unsigned_int8, - ddl_unsigned_int16, - ddl_unsigned_int32, - ddl_unsigned_int64, - ddl_half, + ddl_none = -1, ///< Nothing specified + ddl_bool = 0, ///< A boolean type + ddl_int8, ///< Integer type, 8 bytes + ddl_int16, ///< Integer type, 16 bytes + ddl_int32, ///< Integer type, 32 bytes + ddl_int64, ///< Integer type, 64 bytes + ddl_unsigned_int8, ///< Unsigned integer type, 8 bytes + ddl_unsigned_int16, ///< Unsigned integer type, 16 bytes + ddl_unsigned_int32, ///< Unsigned integer type, 32 bytes + ddl_unsigned_int64, ///< Unsigned integer type, 64 bytes + ddl_half, ddl_float, ddl_double, ddl_string, From 303a6893fc6805e260bea6df816ae7b8fbb65781 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 7 Feb 2015 13:23:32 +0100 Subject: [PATCH 17/39] fix the build. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 7de3eaaea..673deb6f8 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -120,14 +120,9 @@ void OpenGEXImporter::SetupProperties( const Importer *pImp ) { //------------------------------------------------------------------------------------------------ void OpenGEXImporter::importMetric( Context *ctx ) { - if( NULL == ctx || NULL == ctx->getProperties() ) { + if( NULL == ctx ) { return; } - - Property *prop = ctx->getProperties(); - while( NULL != prop ) { - prop = prop->m_next; - } } //------------------------------------------------------------------------------------------------ From 065ad7173aa464bc42d4d6459a89dca8d659c84d Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 7 Feb 2015 18:26:57 +0100 Subject: [PATCH 18/39] fix build: no c++11 support Signed-off-by: Kim Kulling --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 267f471c5..023263739 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,8 @@ set (PROJECT_VERSION "${ASSIMP_VERSION}") set(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources") +add_definitions( -DOPENDDL_NO_USE_CPP11 ) + # Get the current working branch execute_process( COMMAND git rev-parse --abbrev-ref HEAD From 124f40897627f34334fe1fd286a0ea174cd6de31 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 7 Feb 2015 19:52:06 +0100 Subject: [PATCH 19/39] add property parsing. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 55 +++++++++++++++++++++++++++++++++++++--- code/OpenGEXImporter.h | 4 ++- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 673deb6f8..af9b550b5 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -60,6 +60,23 @@ static const aiImporterDesc desc = { "ogex" }; +namespace Grammar { + static const char *MetricType = "Metric"; + static const char *NameType = "Name"; + static const char *ObjectRefType = "ObjectRef"; + static const char *MaterialRefType = "MaterialRef"; + static const char *MetricKeyType = "key"; + static const char *GeometryNodeType = "GeometryNode"; + static const char *GeometryObjectType = "GeometryObject"; + static const char *TransformType = "Transform"; + static const char *MeshType = "Mesh"; + static const char *VertexArrayType = "VertexArray"; + static const char *IndexArrayType = "IndexArray"; + static const char *MaterialType = "Material"; + static const char *ColorType = "Color"; + static const char *TextureType = "Texture"; +} // Namespace Grammar + namespace Assimp { namespace OpenGEX { @@ -104,7 +121,7 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce bool success( myParser.parse() ); if( success ) { Context *ctx = myParser.getContext(); - importMetric( ctx ); + handleNodes( ctx->m_root ); } } @@ -115,14 +132,44 @@ const aiImporterDesc *OpenGEXImporter::GetInfo() const { //------------------------------------------------------------------------------------------------ void OpenGEXImporter::SetupProperties( const Importer *pImp ) { - + if( NULL == pImp ) { + return; + } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::importMetric( Context *ctx ) { - if( NULL == ctx ) { +void OpenGEXImporter::handleNodes( ODDLParser::DDLNode *node ) { + if( NULL == node ) { return; } + + DDLNode::DllNodeList childs = node->getChildNodeList(); + for( DDLNode::DllNodeList::iterator it = childs.begin(); it != childs.end(); it++ ) { + if( ( *it )->getType() == Grammar::MetricType ) { + importMetric( *it ); + } + } +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::importMetric( DDLNode *node ) { + if( NULL == node ) { + return; + } + + Property *prop( node->getProperties() ); + while( NULL != prop ) { + if( NULL != prop->m_id ) { + if( Value::ddl_string == prop->m_primData->m_type ) { + std::string valName( (char*) prop->m_primData->m_data ); + Value *val( node->getValue() ); + if( NULL != val ) { + + } + } + } + prop = prop->m_next; + } } //------------------------------------------------------------------------------------------------ diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 601721704..58641775e 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace ODDLParser { + class DDLNode; struct Context; } @@ -77,7 +78,8 @@ public: virtual void SetupProperties( const Importer *pImp ); protected: - void importMetric( ODDLParser::Context *ctx ); + void handleNodes( ODDLParser::DDLNode *node ); + void importMetric( ODDLParser::DDLNode *node ); void ParseGeoObject(); void ParseMaterial(); }; From c3e2fa07613afe25f269c330fa6347b9fea92d0b Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 10 Feb 2015 19:31:23 +0100 Subject: [PATCH 20/39] - untabify obj parser. - bugfix openddl: latest version Signed-off-by: Kim Kulling --- code/ObjFileImporter.cpp | 946 +++++++++---------- code/ObjFileImporter.h | 74 +- code/ObjFileParser.h | 118 +-- contrib/openddlparser/code/OpenDDLParser.cpp | 24 +- 4 files changed, 582 insertions(+), 580 deletions(-) diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index b44ca4f05..8f201aa5a 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -48,16 +48,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ObjFileData.h" static const aiImporterDesc desc = { - "Wavefront Object Importer", - "", - "", - "surfaces not supported", - aiImporterFlags_SupportTextFlavour, - 0, - 0, - 0, - 0, - "obj" + "Wavefront Object Importer", + "", + "", + "surfaces not supported", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "obj" }; static const unsigned int ObjMinSize = 16; @@ -69,99 +69,99 @@ using namespace std; // ------------------------------------------------------------------------------------------------ // Default constructor ObjFileImporter::ObjFileImporter() : - m_Buffer(), - m_pRootObject( NULL ), - m_strAbsPath( "" ) + m_Buffer(), + m_pRootObject( NULL ), + m_strAbsPath( "" ) { DefaultIOSystem io; - m_strAbsPath = io.getOsSeparator(); + m_strAbsPath = io.getOsSeparator(); } // ------------------------------------------------------------------------------------------------ // Destructor. ObjFileImporter::~ObjFileImporter() { - delete m_pRootObject; - m_pRootObject = NULL; + delete m_pRootObject; + m_pRootObject = NULL; } // ------------------------------------------------------------------------------------------------ // Returns true, if file is an obj file. bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const { - if(!checkSig) //Check File Extension - { - return SimpleExtensionCheck(pFile,"obj"); - } - else //Check file Header - { - static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " }; - return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 ); - } + if(!checkSig) //Check File Extension + { + return SimpleExtensionCheck(pFile,"obj"); + } + else //Check file Header + { + static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " }; + return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 ); + } } // ------------------------------------------------------------------------------------------------ const aiImporterDesc* ObjFileImporter::GetInfo () const { - return &desc; + return &desc; } // ------------------------------------------------------------------------------------------------ // Obj-file import implementation void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { - // Read file into memory - const std::string mode = "rb"; - boost::scoped_ptr file( pIOHandler->Open( pFile, mode)); + // Read file into memory + const std::string mode = "rb"; + boost::scoped_ptr file( pIOHandler->Open( pFile, mode)); if( !file.get() ) { throw DeadlyImportError( "Failed to open file " + pFile + "." ); } - // Get the file-size and validate it, throwing an exception when fails - size_t fileSize = file->FileSize(); + // Get the file-size and validate it, throwing an exception when fails + size_t fileSize = file->FileSize(); if( fileSize < ObjMinSize ) { - throw DeadlyImportError( "OBJ-file is too small."); + throw DeadlyImportError( "OBJ-file is too small."); } - // Allocate buffer and read file into it - TextFileToBuffer(file.get(),m_Buffer); + // Allocate buffer and read file into it + TextFileToBuffer(file.get(),m_Buffer); - // Get the model name - std::string strModelName; - std::string::size_type pos = pFile.find_last_of( "\\/" ); - if ( pos != std::string::npos ) - { - strModelName = pFile.substr(pos+1, pFile.size() - pos - 1); - } - else - { - strModelName = pFile; - } + // Get the model name + std::string strModelName; + std::string::size_type pos = pFile.find_last_of( "\\/" ); + if ( pos != std::string::npos ) + { + strModelName = pFile.substr(pos+1, pFile.size() - pos - 1); + } + else + { + strModelName = pFile; + } - // process all '\' - std::vector ::iterator iter = m_Buffer.begin(); - while (iter != m_Buffer.end()) - { - if (*iter == '\\') - { - // remove '\' - iter = m_Buffer.erase(iter); - // remove next character - while (*iter == '\r' || *iter == '\n') - iter = m_Buffer.erase(iter); - } - else - ++iter; - } + // process all '\' + std::vector ::iterator iter = m_Buffer.begin(); + while (iter != m_Buffer.end()) + { + if (*iter == '\\') + { + // remove '\' + iter = m_Buffer.erase(iter); + // remove next character + while (*iter == '\r' || *iter == '\n') + iter = m_Buffer.erase(iter); + } + else + ++iter; + } - // parse the file into a temporary representation - ObjFileParser parser(m_Buffer, strModelName, pIOHandler); + // parse the file into a temporary representation + ObjFileParser parser(m_Buffer, strModelName, pIOHandler); - // And create the proper return structures out of it - CreateDataFromImport(parser.GetModel(), pScene); + // And create the proper return structures out of it + CreateDataFromImport(parser.GetModel(), pScene); - // Clean up allocated storage for the next import - m_Buffer.clear(); + // Clean up allocated storage for the next import + m_Buffer.clear(); } // ------------------------------------------------------------------------------------------------ @@ -170,98 +170,98 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene if( 0L == pModel ) { return; } - - // Create the root node of the scene - pScene->mRootNode = new aiNode; - if ( !pModel->m_ModelName.empty() ) - { - // Set the name of the scene - pScene->mRootNode->mName.Set(pModel->m_ModelName); - } - else - { - // This is a fatal error, so break down the application - ai_assert(false); - } + + // Create the root node of the scene + pScene->mRootNode = new aiNode; + if ( !pModel->m_ModelName.empty() ) + { + // Set the name of the scene + pScene->mRootNode->mName.Set(pModel->m_ModelName); + } + else + { + // This is a fatal error, so break down the application + ai_assert(false); + } - // Create nodes for the whole scene - std::vector MeshArray; - for (size_t index = 0; index < pModel->m_Objects.size(); index++) - { - createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray); - } + // Create nodes for the whole scene + std::vector MeshArray; + for (size_t index = 0; index < pModel->m_Objects.size(); index++) + { + createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray); + } - // Create mesh pointer buffer for this scene - if (pScene->mNumMeshes > 0) - { - pScene->mMeshes = new aiMesh*[ MeshArray.size() ]; - for (size_t index =0; index < MeshArray.size(); index++) - { - pScene->mMeshes [ index ] = MeshArray[ index ]; - } - } + // Create mesh pointer buffer for this scene + if (pScene->mNumMeshes > 0) + { + pScene->mMeshes = new aiMesh*[ MeshArray.size() ]; + for (size_t index =0; index < MeshArray.size(); index++) + { + pScene->mMeshes [ index ] = MeshArray[ index ]; + } + } - // Create all materials - createMaterials( pModel, pScene ); + // Create all materials + createMaterials( pModel, pScene ); } // ------------------------------------------------------------------------------------------------ // Creates all nodes of the model aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject, - aiNode *pParent, aiScene* pScene, - std::vector &MeshArray ) + aiNode *pParent, aiScene* pScene, + std::vector &MeshArray ) { - ai_assert( NULL != pModel ); + ai_assert( NULL != pModel ); if( NULL == pObject ) { return NULL; } - - // Store older mesh size to be able to computes mesh offsets for new mesh instances - const size_t oldMeshSize = MeshArray.size(); - aiNode *pNode = new aiNode; + + // Store older mesh size to be able to computes mesh offsets for new mesh instances + const size_t oldMeshSize = MeshArray.size(); + aiNode *pNode = new aiNode; - pNode->mName = pObject->m_strObjName; - - // If we have a parent node, store it + pNode->mName = pObject->m_strObjName; + + // If we have a parent node, store it if( pParent != NULL ) { appendChildToParentNode( pParent, pNode ); } - for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ ) - { - unsigned int meshId = pObject->m_Meshes[ i ]; - aiMesh *pMesh = createTopology( pModel, pObject, meshId ); + for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ ) + { + unsigned int meshId = pObject->m_Meshes[ i ]; + aiMesh *pMesh = createTopology( pModel, pObject, meshId ); if( pMesh && pMesh->mNumFaces > 0 ) { - MeshArray.push_back( pMesh ); - } - } + MeshArray.push_back( pMesh ); + } + } - // Create all nodes from the sub-objects stored in the current object - if ( !pObject->m_SubObjects.empty() ) - { - size_t numChilds = pObject->m_SubObjects.size(); - pNode->mNumChildren = static_cast( numChilds ); - pNode->mChildren = new aiNode*[ numChilds ]; - pNode->mNumMeshes = 1; - pNode->mMeshes = new unsigned int[ 1 ]; - } + // Create all nodes from the sub-objects stored in the current object + if ( !pObject->m_SubObjects.empty() ) + { + size_t numChilds = pObject->m_SubObjects.size(); + pNode->mNumChildren = static_cast( numChilds ); + pNode->mChildren = new aiNode*[ numChilds ]; + pNode->mNumMeshes = 1; + pNode->mMeshes = new unsigned int[ 1 ]; + } - // Set mesh instances into scene- and node-instances - const size_t meshSizeDiff = MeshArray.size()- oldMeshSize; - if ( meshSizeDiff > 0 ) - { - pNode->mMeshes = new unsigned int[ meshSizeDiff ]; - pNode->mNumMeshes = static_cast( meshSizeDiff ); - size_t index = 0; - for (size_t i = oldMeshSize; i < MeshArray.size(); i++) - { - pNode->mMeshes[ index ] = pScene->mNumMeshes; - pScene->mNumMeshes++; - index++; - } - } - - return pNode; + // Set mesh instances into scene- and node-instances + const size_t meshSizeDiff = MeshArray.size()- oldMeshSize; + if ( meshSizeDiff > 0 ) + { + pNode->mMeshes = new unsigned int[ meshSizeDiff ]; + pNode->mNumMeshes = static_cast( meshSizeDiff ); + size_t index = 0; + for (size_t i = oldMeshSize; i < MeshArray.size(); i++) + { + pNode->mMeshes[ index ] = pScene->mNumMeshes; + pScene->mNumMeshes++; + index++; + } + } + + return pNode; } // ------------------------------------------------------------------------------------------------ @@ -269,83 +269,83 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData, unsigned int uiMeshIndex ) { - // Checking preconditions - ai_assert( NULL != pModel ); + // Checking preconditions + ai_assert( NULL != pModel ); if( NULL == pData ) { return NULL; } - // Create faces - ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ]; + // Create faces + ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ]; if( !pObjMesh ) { return NULL; } ai_assert( NULL != pObjMesh ); aiMesh* pMesh = new aiMesh; - for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) - { - ObjFile::Face *const inp = pObjMesh->m_Faces[ index ]; + for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) + { + ObjFile::Face *const inp = pObjMesh->m_Faces[ index ]; ai_assert( NULL != inp ); - if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { - pMesh->mNumFaces += inp->m_pVertices->size() - 1; - pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - } else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { - pMesh->mNumFaces += inp->m_pVertices->size(); - pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - } else { - ++pMesh->mNumFaces; - if (inp->m_pVertices->size() > 3) { - pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - } else { - pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - } - } - } + if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { + pMesh->mNumFaces += inp->m_pVertices->size() - 1; + pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; + } else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { + pMesh->mNumFaces += inp->m_pVertices->size(); + pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; + } else { + ++pMesh->mNumFaces; + if (inp->m_pVertices->size() > 3) { + pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; + } else { + pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; + } + } + } - unsigned int uiIdxCount( 0u ); - if ( pMesh->mNumFaces > 0 ) - { - pMesh->mFaces = new aiFace[ pMesh->mNumFaces ]; - if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial ) - { - pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex; - } + unsigned int uiIdxCount( 0u ); + if ( pMesh->mNumFaces > 0 ) + { + pMesh->mFaces = new aiFace[ pMesh->mNumFaces ]; + if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial ) + { + pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex; + } - unsigned int outIndex( 0 ); + unsigned int outIndex( 0 ); - // Copy all data from all stored meshes - for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) - { - ObjFile::Face* const inp = pObjMesh->m_Faces[ index ]; - if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { - for(size_t i = 0; i < inp->m_pVertices->size() - 1; ++i) { - aiFace& f = pMesh->mFaces[ outIndex++ ]; - uiIdxCount += f.mNumIndices = 2; - f.mIndices = new unsigned int[2]; - } - continue; - } - else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { - for(size_t i = 0; i < inp->m_pVertices->size(); ++i) { - aiFace& f = pMesh->mFaces[ outIndex++ ]; - uiIdxCount += f.mNumIndices = 1; - f.mIndices = new unsigned int[1]; - } - continue; - } + // Copy all data from all stored meshes + for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) + { + ObjFile::Face* const inp = pObjMesh->m_Faces[ index ]; + if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { + for(size_t i = 0; i < inp->m_pVertices->size() - 1; ++i) { + aiFace& f = pMesh->mFaces[ outIndex++ ]; + uiIdxCount += f.mNumIndices = 2; + f.mIndices = new unsigned int[2]; + } + continue; + } + else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { + for(size_t i = 0; i < inp->m_pVertices->size(); ++i) { + aiFace& f = pMesh->mFaces[ outIndex++ ]; + uiIdxCount += f.mNumIndices = 1; + f.mIndices = new unsigned int[1]; + } + continue; + } - aiFace *pFace = &pMesh->mFaces[ outIndex++ ]; - const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size(); - uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices; - if (pFace->mNumIndices > 0) { - pFace->mIndices = new unsigned int[ uiNumIndices ]; - } - } - } + aiFace *pFace = &pMesh->mFaces[ outIndex++ ]; + const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size(); + uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices; + if (pFace->mNumIndices > 0) { + pFace->mIndices = new unsigned int[ uiNumIndices ]; + } + } + } - // Create mesh vertices - createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount); + // Create mesh vertices + createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount); return pMesh; } @@ -353,335 +353,335 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj // ------------------------------------------------------------------------------------------------ // Creates a vertex array void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, - const ObjFile::Object* pCurrentObject, - unsigned int uiMeshIndex, - aiMesh* pMesh, - unsigned int uiIdxCount) + const ObjFile::Object* pCurrentObject, + unsigned int uiMeshIndex, + aiMesh* pMesh, + unsigned int uiIdxCount) { - // Checking preconditions - ai_assert( NULL != pCurrentObject ); - - // Break, if no faces are stored in object - if ( pCurrentObject->m_Meshes.empty() ) - return; + // Checking preconditions + ai_assert( NULL != pCurrentObject ); + + // Break, if no faces are stored in object + if ( pCurrentObject->m_Meshes.empty() ) + return; - // Get current mesh - ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ]; - if ( NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1) - return; + // Get current mesh + ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ]; + if ( NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1) + return; - // Copy vertices of this mesh instance - pMesh->mNumVertices = uiIdxCount; - pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; - - // Allocate buffer for normal vectors - if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals ) - pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ]; - - // Allocate buffer for texture coordinates - if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] ) - { - pMesh->mNumUVComponents[ 0 ] = 2; - pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ]; - } - - // Copy vertices, normals and textures into aiMesh instance - unsigned int newIndex = 0, outIndex = 0; - for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) - { - // Get source face - ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ]; + // Copy vertices of this mesh instance + pMesh->mNumVertices = uiIdxCount; + pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; + + // Allocate buffer for normal vectors + if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals ) + pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ]; + + // Allocate buffer for texture coordinates + if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] ) + { + pMesh->mNumUVComponents[ 0 ] = 2; + pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ]; + } + + // Copy vertices, normals and textures into aiMesh instance + unsigned int newIndex = 0, outIndex = 0; + for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) + { + // Get source face + ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ]; - // Copy all index arrays - for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ ) - { - const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex ); - if ( vertex >= pModel->m_Vertices.size() ) - throw DeadlyImportError( "OBJ: vertex index out of range" ); - - pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ]; - - // Copy all normals - if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size()) - { - const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex ); - if ( normal >= pModel->m_Normals.size() ) - throw DeadlyImportError("OBJ: vertex normal index out of range"); + // Copy all index arrays + for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ ) + { + const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex ); + if ( vertex >= pModel->m_Vertices.size() ) + throw DeadlyImportError( "OBJ: vertex index out of range" ); + + pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ]; + + // Copy all normals + if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size()) + { + const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex ); + if ( normal >= pModel->m_Normals.size() ) + throw DeadlyImportError("OBJ: vertex normal index out of range"); - pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ]; - } - - // Copy all texture coordinates - if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size()) - { - const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex ); - ai_assert( tex < pModel->m_TextureCoord.size() ); - - if ( tex >= pModel->m_TextureCoord.size() ) - throw DeadlyImportError("OBJ: texture coordinate index out of range"); + pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ]; + } + + // Copy all texture coordinates + if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size()) + { + const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex ); + ai_assert( tex < pModel->m_TextureCoord.size() ); + + if ( tex >= pModel->m_TextureCoord.size() ) + throw DeadlyImportError("OBJ: texture coordinate index out of range"); - const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ]; + const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ]; pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord3d.x, coord3d.y, coord3d.z ); - } + } - ai_assert( pMesh->mNumVertices > newIndex ); + ai_assert( pMesh->mNumVertices > newIndex ); - // Get destination face - aiFace *pDestFace = &pMesh->mFaces[ outIndex ]; + // Get destination face + aiFace *pDestFace = &pMesh->mFaces[ outIndex ]; - const bool last = ( vertexIndex == pSourceFace->m_pVertices->size() - 1 ); - if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) - { - pDestFace->mIndices[ outVertexIndex ] = newIndex; - outVertexIndex++; - } + const bool last = ( vertexIndex == pSourceFace->m_pVertices->size() - 1 ); + if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) + { + pDestFace->mIndices[ outVertexIndex ] = newIndex; + outVertexIndex++; + } - if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) - { - outIndex++; - outVertexIndex = 0; - } - else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) - { - outVertexIndex = 0; + if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) + { + outIndex++; + outVertexIndex = 0; + } + else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) + { + outVertexIndex = 0; - if(!last) - outIndex++; + if(!last) + outIndex++; - if (vertexIndex) { - if(!last) { - pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ]; - if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) { - pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ]; - } - if ( !pModel->m_TextureCoord.empty() ) { - for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) { - pMesh->mTextureCoords[ i ][ newIndex+1 ] = pMesh->mTextureCoords[ i ][ newIndex ]; - } - } - ++newIndex; - } + if (vertexIndex) { + if(!last) { + pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ]; + if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) { + pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ]; + } + if ( !pModel->m_TextureCoord.empty() ) { + for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) { + pMesh->mTextureCoords[ i ][ newIndex+1 ] = pMesh->mTextureCoords[ i ][ newIndex ]; + } + } + ++newIndex; + } - pDestFace[-1].mIndices[1] = newIndex; - } - } - else if (last) { - outIndex++; - } - ++newIndex; - } - } + pDestFace[-1].mIndices[1] = newIndex; + } + } + else if (last) { + outIndex++; + } + ++newIndex; + } + } } // ------------------------------------------------------------------------------------------------ // Counts all stored meshes void ObjFileImporter::countObjects(const std::vector &rObjects, int &iNumMeshes) { - iNumMeshes = 0; - if ( rObjects.empty() ) - return; + iNumMeshes = 0; + if ( rObjects.empty() ) + return; - iNumMeshes += static_cast( rObjects.size() ); - for (std::vector::const_iterator it = rObjects.begin(); - it != rObjects.end(); - ++it) - { - if (!(*it)->m_SubObjects.empty()) - { - countObjects((*it)->m_SubObjects, iNumMeshes); - } - } + iNumMeshes += static_cast( rObjects.size() ); + for (std::vector::const_iterator it = rObjects.begin(); + it != rObjects.end(); + ++it) + { + if (!(*it)->m_SubObjects.empty()) + { + countObjects((*it)->m_SubObjects, iNumMeshes); + } + } } // ------------------------------------------------------------------------------------------------ // Add clamp mode property to material if necessary void ObjFileImporter::addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode) { - ai_assert( NULL != mat); - mat->AddProperty(&clampMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0)); - mat->AddProperty(&clampMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0)); + ai_assert( NULL != mat); + mat->AddProperty(&clampMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0)); + mat->AddProperty(&clampMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0)); } // ------------------------------------------------------------------------------------------------ // Creates the material void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pScene ) { - ai_assert( NULL != pScene ); - if ( NULL == pScene ) - return; + ai_assert( NULL != pScene ); + if ( NULL == pScene ) + return; - const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size(); - pScene->mNumMaterials = 0; - if ( pModel->m_MaterialLib.empty() ) { - DefaultLogger::get()->debug("OBJ: no materials specified"); - return; - } - - pScene->mMaterials = new aiMaterial*[ numMaterials ]; - for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ ) - { - // Store material name - std::map::const_iterator it; - it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] ); - - // No material found, use the default material - if ( pModel->m_MaterialMap.end() == it ) - continue; + const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size(); + pScene->mNumMaterials = 0; + if ( pModel->m_MaterialLib.empty() ) { + DefaultLogger::get()->debug("OBJ: no materials specified"); + return; + } + + pScene->mMaterials = new aiMaterial*[ numMaterials ]; + for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ ) + { + // Store material name + std::map::const_iterator it; + it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] ); + + // No material found, use the default material + if ( pModel->m_MaterialMap.end() == it ) + continue; - aiMaterial* mat = new aiMaterial; - ObjFile::Material *pCurrentMaterial = (*it).second; - mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME ); + aiMaterial* mat = new aiMaterial; + ObjFile::Material *pCurrentMaterial = (*it).second; + mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME ); - // convert illumination model - int sm = 0; - switch (pCurrentMaterial->illumination_model) - { - case 0: - sm = aiShadingMode_NoShading; - break; - case 1: - sm = aiShadingMode_Gouraud; - break; - case 2: - sm = aiShadingMode_Phong; - break; - default: - sm = aiShadingMode_Gouraud; - DefaultLogger::get()->error("OBJ: unexpected illumination model (0-2 recognized)"); - } - - mat->AddProperty( &sm, 1, AI_MATKEY_SHADING_MODEL); + // convert illumination model + int sm = 0; + switch (pCurrentMaterial->illumination_model) + { + case 0: + sm = aiShadingMode_NoShading; + break; + case 1: + sm = aiShadingMode_Gouraud; + break; + case 2: + sm = aiShadingMode_Phong; + break; + default: + sm = aiShadingMode_Gouraud; + DefaultLogger::get()->error("OBJ: unexpected illumination model (0-2 recognized)"); + } + + mat->AddProperty( &sm, 1, AI_MATKEY_SHADING_MODEL); - // multiplying the specular exponent with 2 seems to yield better results - pCurrentMaterial->shineness *= 4.f; + // multiplying the specular exponent with 2 seems to yield better results + pCurrentMaterial->shineness *= 4.f; - // Adding material colors - mat->AddProperty( &pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT ); - mat->AddProperty( &pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE ); - mat->AddProperty( &pCurrentMaterial->specular, 1, AI_MATKEY_COLOR_SPECULAR ); - mat->AddProperty( &pCurrentMaterial->emissive, 1, AI_MATKEY_COLOR_EMISSIVE ); - mat->AddProperty( &pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS ); - mat->AddProperty( &pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY ); + // Adding material colors + mat->AddProperty( &pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT ); + mat->AddProperty( &pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE ); + mat->AddProperty( &pCurrentMaterial->specular, 1, AI_MATKEY_COLOR_SPECULAR ); + mat->AddProperty( &pCurrentMaterial->emissive, 1, AI_MATKEY_COLOR_EMISSIVE ); + mat->AddProperty( &pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS ); + mat->AddProperty( &pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY ); - // Adding refraction index - mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI ); + // Adding refraction index + mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI ); - // Adding textures - if ( 0 != pCurrentMaterial->texture.length ) - { - mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0)); - if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType]) - { - addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE); - } - } + // Adding textures + if ( 0 != pCurrentMaterial->texture.length ) + { + mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType]) + { + addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE); + } + } - if ( 0 != pCurrentMaterial->textureAmbient.length ) - { - mat->AddProperty( &pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0)); - if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType]) - { - addTextureMappingModeProperty(mat, aiTextureType_AMBIENT); - } - } + if ( 0 != pCurrentMaterial->textureAmbient.length ) + { + mat->AddProperty( &pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType]) + { + addTextureMappingModeProperty(mat, aiTextureType_AMBIENT); + } + } - if ( 0 != pCurrentMaterial->textureEmissive.length ) - mat->AddProperty( &pCurrentMaterial->textureEmissive, AI_MATKEY_TEXTURE_EMISSIVE(0)); + if ( 0 != pCurrentMaterial->textureEmissive.length ) + mat->AddProperty( &pCurrentMaterial->textureEmissive, AI_MATKEY_TEXTURE_EMISSIVE(0)); - if ( 0 != pCurrentMaterial->textureSpecular.length ) - { - mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0)); - if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType]) - { - addTextureMappingModeProperty(mat, aiTextureType_SPECULAR); - } - } + if ( 0 != pCurrentMaterial->textureSpecular.length ) + { + mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType]) + { + addTextureMappingModeProperty(mat, aiTextureType_SPECULAR); + } + } - if ( 0 != pCurrentMaterial->textureBump.length ) - { - mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0)); - if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) - { - addTextureMappingModeProperty(mat, aiTextureType_HEIGHT); - } - } + if ( 0 != pCurrentMaterial->textureBump.length ) + { + mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) + { + addTextureMappingModeProperty(mat, aiTextureType_HEIGHT); + } + } - if ( 0 != pCurrentMaterial->textureNormal.length ) - { - mat->AddProperty( &pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0)); - if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) - { - addTextureMappingModeProperty(mat, aiTextureType_NORMALS); - } - } + if ( 0 != pCurrentMaterial->textureNormal.length ) + { + mat->AddProperty( &pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) + { + addTextureMappingModeProperty(mat, aiTextureType_NORMALS); + } + } - if ( 0 != pCurrentMaterial->textureDisp.length ) - { - mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) ); - if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType]) - { - addTextureMappingModeProperty(mat, aiTextureType_DISPLACEMENT); - } - } + if ( 0 != pCurrentMaterial->textureDisp.length ) + { + mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) ); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType]) + { + addTextureMappingModeProperty(mat, aiTextureType_DISPLACEMENT); + } + } - if ( 0 != pCurrentMaterial->textureOpacity.length ) - { - mat->AddProperty( &pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0)); - if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType]) - { - addTextureMappingModeProperty(mat, aiTextureType_OPACITY); - } - } + if ( 0 != pCurrentMaterial->textureOpacity.length ) + { + mat->AddProperty( &pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType]) + { + addTextureMappingModeProperty(mat, aiTextureType_OPACITY); + } + } - if ( 0 != pCurrentMaterial->textureSpecularity.length ) - { - mat->AddProperty( &pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0)); - if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType]) - { - addTextureMappingModeProperty(mat, aiTextureType_SHININESS); - } - } - - // Store material property info in material array in scene - pScene->mMaterials[ pScene->mNumMaterials ] = mat; - pScene->mNumMaterials++; - } - - // Test number of created materials. - ai_assert( pScene->mNumMaterials == numMaterials ); + if ( 0 != pCurrentMaterial->textureSpecularity.length ) + { + mat->AddProperty( &pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType]) + { + addTextureMappingModeProperty(mat, aiTextureType_SHININESS); + } + } + + // Store material property info in material array in scene + pScene->mMaterials[ pScene->mNumMaterials ] = mat; + pScene->mNumMaterials++; + } + + // Test number of created materials. + ai_assert( pScene->mNumMaterials == numMaterials ); } // ------------------------------------------------------------------------------------------------ // Appends this node to the parent node void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) { - // Checking preconditions - ai_assert( NULL != pParent ); - ai_assert( NULL != pChild ); + // Checking preconditions + ai_assert( NULL != pParent ); + ai_assert( NULL != pChild ); - // Assign parent to child - pChild->mParent = pParent; - - // If already children was assigned to the parent node, store them in a - std::vector temp; - if (pParent->mChildren != NULL) - { - ai_assert( 0 != pParent->mNumChildren ); - for (size_t index = 0; index < pParent->mNumChildren; index++) - { - temp.push_back(pParent->mChildren [ index ] ); - } - delete [] pParent->mChildren; - } - - // Copy node instances into parent node - pParent->mNumChildren++; - pParent->mChildren = new aiNode*[ pParent->mNumChildren ]; - for (size_t index = 0; index < pParent->mNumChildren-1; index++) - { - pParent->mChildren[ index ] = temp [ index ]; - } - pParent->mChildren[ pParent->mNumChildren-1 ] = pChild; + // Assign parent to child + pChild->mParent = pParent; + + // If already children was assigned to the parent node, store them in a + std::vector temp; + if (pParent->mChildren != NULL) + { + ai_assert( 0 != pParent->mNumChildren ); + for (size_t index = 0; index < pParent->mNumChildren; index++) + { + temp.push_back(pParent->mChildren [ index ] ); + } + delete [] pParent->mChildren; + } + + // Copy node instances into parent node + pParent->mNumChildren++; + pParent->mChildren = new aiNode*[ pParent->mNumChildren ]; + for (size_t index = 0; index < pParent->mNumChildren-1; index++) + { + pParent->mChildren[ index ] = temp [ index ]; + } + pParent->mChildren[ pParent->mNumChildren-1 ] = pChild; } // ------------------------------------------------------------------------------------------------ diff --git a/code/ObjFileImporter.h b/code/ObjFileImporter.h index 716cf65d1..0168c2673 100644 --- a/code/ObjFileImporter.h +++ b/code/ObjFileImporter.h @@ -64,57 +64,57 @@ struct Model; class ObjFileImporter : public BaseImporter { public: - /// \brief Default constructor - ObjFileImporter(); + /// \brief Default constructor + ObjFileImporter(); - /// \brief Destructor - ~ObjFileImporter(); + /// \brief Destructor + ~ObjFileImporter(); public: - /// \brief Returns whether the class can handle the format of the given file. - /// \remark See BaseImporter::CanRead() for details. - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; + /// \brief Returns whether the class can handle the format of the given file. + /// \remark See BaseImporter::CanRead() for details. + bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; private: - //! \brief Appends the supported extension. - const aiImporterDesc* GetInfo () const; + //! \brief Appends the supported extension. + const aiImporterDesc* GetInfo () const; - //! \brief File import implementation. - void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); - - //! \brief Create the data from imported content. - void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene); - - //! \brief Creates all nodes stored in imported content. - aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData, - aiNode *pParent, aiScene* pScene, std::vector &MeshArray); + //! \brief File import implementation. + void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); + + //! \brief Create the data from imported content. + void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene); + + //! \brief Creates all nodes stored in imported content. + aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData, + aiNode *pParent, aiScene* pScene, std::vector &MeshArray); - //! \brief Creates topology data like faces and meshes for the geometry. + //! \brief Creates topology data like faces and meshes for the geometry. aiMesh *createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData, - unsigned int uiMeshIndex ); - - //! \brief Creates vertices from model. - void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject, - unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount); + unsigned int uiMeshIndex ); + + //! \brief Creates vertices from model. + void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject, + unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount); - //! \brief Object counter helper method. - void countObjects(const std::vector &rObjects, int &iNumMeshes); + //! \brief Object counter helper method. + void countObjects(const std::vector &rObjects, int &iNumMeshes); - //! \brief Material creation. - void createMaterials(const ObjFile::Model* pModel, aiScene* pScene); - void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1); + //! \brief Material creation. + void createMaterials(const ObjFile::Model* pModel, aiScene* pScene); + void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1); - //! \brief Appends a child node to a parent node and updates the data structures. - void appendChildToParentNode(aiNode *pParent, aiNode *pChild); + //! \brief Appends a child node to a parent node and updates the data structures. + void appendChildToParentNode(aiNode *pParent, aiNode *pChild); private: - //! Data buffer - std::vector m_Buffer; - //! Pointer to root object instance - ObjFile::Object *m_pRootObject; - //! Absolute pathname of model in file system - std::string m_strAbsPath; + //! Data buffer + std::vector m_Buffer; + //! Pointer to root object instance + ObjFile::Object *m_pRootObject; + //! Absolute pathname of model in file system + std::string m_strAbsPath; }; // ------------------------------------------------------------------------------------------------ diff --git a/code/ObjFileParser.h b/code/ObjFileParser.h index 500e8d0f9..d22ca3d8e 100644 --- a/code/ObjFileParser.h +++ b/code/ObjFileParser.h @@ -63,76 +63,76 @@ class IOSystem; class ObjFileParser { public: - static const size_t BUFFERSIZE = 4096; - typedef std::vector DataArray; - typedef std::vector::iterator DataArrayIt; - typedef std::vector::const_iterator ConstDataArrayIt; + static const size_t BUFFERSIZE = 4096; + typedef std::vector DataArray; + typedef std::vector::iterator DataArrayIt; + typedef std::vector::const_iterator ConstDataArrayIt; public: - /// \brief Constructor with data array. - ObjFileParser(std::vector &Data,const std::string &strModelName, IOSystem* io); - /// \brief Destructor - ~ObjFileParser(); - /// \brief Model getter. - ObjFile::Model *GetModel() const; + /// \brief Constructor with data array. + ObjFileParser(std::vector &Data,const std::string &strModelName, IOSystem* io); + /// \brief Destructor + ~ObjFileParser(); + /// \brief Model getter. + ObjFile::Model *GetModel() const; private: - /// Parse the loaded file - void parseFile(); - /// Method to copy the new delimited word in the current line. - void copyNextWord(char *pBuffer, size_t length); - /// Method to copy the new line. - void copyNextLine(char *pBuffer, size_t length); + /// Parse the loaded file + void parseFile(); + /// Method to copy the new delimited word in the current line. + void copyNextWord(char *pBuffer, size_t length); + /// Method to copy the new line. + void copyNextLine(char *pBuffer, size_t length); /// Stores the vector void getVector( std::vector &point3d_array ); /// Stores the following 3d vector. - void getVector3( std::vector &point3d_array ); - /// Stores the following 3d vector. - void getVector2(std::vector &point2d_array); + void getVector3( std::vector &point3d_array ); + /// Stores the following 3d vector. + void getVector2(std::vector &point2d_array); /// Stores the following face. - void getFace(aiPrimitiveType type); - /// Reads the material description. + void getFace(aiPrimitiveType type); + /// Reads the material description. void getMaterialDesc(); - /// Gets a comment. - void getComment(); - /// Gets a a material library. - void getMaterialLib(); - /// Creates a new material. - void getNewMaterial(); - /// Gets the group name from file. - void getGroupName(); - /// Gets the group number from file. - void getGroupNumber(); - /// Gets the group number and resolution from file. - void getGroupNumberAndResolution(); - /// Returns the index of the material. Is -1 if not material was found. - int getMaterialIndex( const std::string &strMaterialName ); - /// Parse object name - void getObjectName(); - /// Creates a new object. - void createObject(const std::string &strObjectName); - /// Creates a new mesh. - void createMesh(); - /// Returns true, if a new mesh instance must be created. - bool needsNewMesh( const std::string &rMaterialName ); - /// Error report in token - void reportErrorTokenInFace(); + /// Gets a comment. + void getComment(); + /// Gets a a material library. + void getMaterialLib(); + /// Creates a new material. + void getNewMaterial(); + /// Gets the group name from file. + void getGroupName(); + /// Gets the group number from file. + void getGroupNumber(); + /// Gets the group number and resolution from file. + void getGroupNumberAndResolution(); + /// Returns the index of the material. Is -1 if not material was found. + int getMaterialIndex( const std::string &strMaterialName ); + /// Parse object name + void getObjectName(); + /// Creates a new object. + void createObject(const std::string &strObjectName); + /// Creates a new mesh. + void createMesh(); + /// Returns true, if a new mesh instance must be created. + bool needsNewMesh( const std::string &rMaterialName ); + /// Error report in token + void reportErrorTokenInFace(); private: - /// Default material name - static const std::string DEFAULT_MATERIAL; - //! Iterator to current position in buffer - DataArrayIt m_DataIt; - //! Iterator to end position of buffer - DataArrayIt m_DataItEnd; - //! Pointer to model instance - ObjFile::Model *m_pModel; - //! Current line (for debugging) - unsigned int m_uiLine; - //! Helper buffer - char m_buffer[BUFFERSIZE]; - /// Pointer to IO system instance. - IOSystem *m_pIO; + /// Default material name + static const std::string DEFAULT_MATERIAL; + //! Iterator to current position in buffer + DataArrayIt m_DataIt; + //! Iterator to end position of buffer + DataArrayIt m_DataItEnd; + //! Pointer to model instance + ObjFile::Model *m_pModel; + //! Current line (for debugging) + unsigned int m_uiLine; + //! Helper buffer + char m_buffer[BUFFERSIZE]; + /// Pointer to IO system instance. + IOSystem *m_pIO; }; } // Namespace Assimp diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 684eb20b7..b869aa2a1 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -244,15 +244,6 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { in++; } - // set the properties - if( ddl_nullptr != first ) { - std::cout << id->m_buffer << std::endl; - DDLNode *current( top() ); - if( current ) { - current->setProperties( first ); - } - } - // store the node DDLNode *node( createDDLNode( id, this ) ); if( nullptr != node ) { @@ -261,6 +252,11 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { std::cerr << "nullptr returned by creating DDLNode." << std::endl; } + // set the properties + if( ddl_nullptr != first ) { + node->setProperties( first ); + } + Name *name( ddl_nullptr ); in = OpenDDLParser::parseName( in, end, &name ); if( ddl_nullptr != name ) { @@ -277,6 +273,7 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { return in; } + bool error( false ); in = getNextToken( in, end ); if( *in == '{' ) { in++; @@ -307,6 +304,7 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { } } else { std::cerr << "0 for array is invalid." << std::endl; + error = true; } } @@ -324,12 +322,16 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { } else { in++; logInvalidTokenError( in, "{", m_logCallback ); + error = true; return in; } in = getNextToken( in, end ); - - in++; + + // pop node from stack after successful parsing + if( !error ) { + popNode(); + } return in; } From 556bc9c1f34c0d344535617a464f4eb87992f49e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 10 Feb 2015 20:09:03 +0100 Subject: [PATCH 21/39] fix build Signed-off-by: Kim Kulling --- contrib/openddlparser/include/openddlparser/DDLNode.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/openddlparser/include/openddlparser/DDLNode.h b/contrib/openddlparser/include/openddlparser/DDLNode.h index d5b4a56c9..bb5f87b79 100644 --- a/contrib/openddlparser/include/openddlparser/DDLNode.h +++ b/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -61,10 +61,10 @@ public: Value *getValue() const; void setDataArrayList( DataArrayList *dtArrayList ); DataArrayList *getDataArrayList() const; - static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = nullptr ); + static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr ); private: - DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = nullptr ); + DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_nullptr ); DDLNode(); DDLNode( const DDLNode & ); DDLNode &operator = ( const DDLNode & ); From 9e87fa178af58fda5d2acb6a2d32c86128217e6c Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 10 Feb 2015 20:09:26 +0100 Subject: [PATCH 22/39] add property parsing to opengex parser. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 167 ++++++++++++++++++++++++++++++++------- code/OpenGEXImporter.h | 17 ++++ 2 files changed, 157 insertions(+), 27 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index af9b550b5..83bde51fe 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -61,35 +61,116 @@ static const aiImporterDesc desc = { }; namespace Grammar { - static const char *MetricType = "Metric"; - static const char *NameType = "Name"; - static const char *ObjectRefType = "ObjectRef"; - static const char *MaterialRefType = "MaterialRef"; - static const char *MetricKeyType = "key"; - static const char *GeometryNodeType = "GeometryNode"; - static const char *GeometryObjectType = "GeometryObject"; - static const char *TransformType = "Transform"; - static const char *MeshType = "Mesh"; - static const char *VertexArrayType = "VertexArray"; - static const char *IndexArrayType = "IndexArray"; - static const char *MaterialType = "Material"; - static const char *ColorType = "Color"; - static const char *TextureType = "Texture"; + static const char *MetricType = "Metric"; + static const char *Metric_DistanceType = "distance"; + static const char *Metric_AngleType = "angle"; + static const char *Metric_TimeType = "time"; + static const char *Metric_UpType = "up"; + static const char *NameType = "Name"; + static const char *ObjectRefType = "ObjectRef"; + static const char *MaterialRefType = "MaterialRef"; + static const char *MetricKeyType = "key"; + static const char *GeometryNodeType = "GeometryNode"; + static const char *GeometryObjectType = "GeometryObject"; + static const char *TransformType = "Transform"; + static const char *MeshType = "Mesh"; + static const char *VertexArrayType = "VertexArray"; + static const char *IndexArrayType = "IndexArray"; + static const char *MaterialType = "Material"; + static const char *ColorType = "Color"; + static const char *TextureType = "Texture"; + + enum TokenType { + NoneType = -1, + MetricToken, + NameToken, + ObjectRefToken, + MaterialRefToken, + MetricKeyToken, + GeometryNodeToken, + GeometryObjectToken, + TransformToken, + MeshToken, + VertexArrayToken, + IndexArrayToken, + MaterialToken, + ColorToken, + TextureToken + }; + + static const char *ValidMetricToken[ 4 ] = { + Metric_DistanceType, + Metric_AngleType, + Metric_TimeType, + Metric_UpType + }; + + static int isValidMetricType( const char *token ) { + if( NULL == token ) { + return false; + } + + int idx( -1 ); + for( size_t i = 0; i < 4; i++ ) { + if( 0 == strncmp( ValidMetricToken[ i ], token, strlen( token ) ) ) { + idx = (int) i; + break; + } + } + + return idx; + } + + static TokenType matchTokenType( const char *tokenType ) { + if( 0 == strncmp( MetricType, tokenType, strlen( tokenType ) ) ) { + return MetricToken; + } else if( 0 == strncmp( NameType, tokenType, strlen( tokenType ) ) ) { + return NameToken; + } else if( 0 == strncmp( ObjectRefType, tokenType, strlen( tokenType ) ) ) { + return ObjectRefToken; + } else if( 0 == strncmp( MaterialRefType, tokenType, strlen( tokenType ) ) ) { + return MaterialRefToken; + } else if( 0 == strncmp( MetricKeyType, tokenType, strlen( tokenType ) ) ) { + return MetricKeyToken; + } else if( 0 == strncmp( GeometryNodeType, tokenType, strlen( tokenType ) ) ) { + return GeometryNodeToken; + } else if( 0 == strncmp( GeometryObjectType, tokenType, strlen( tokenType ) ) ) { + return GeometryObjectToken; + } else if( 0 == strncmp( TransformType, tokenType, strlen( tokenType ) ) ) { + return TransformToken; + } else if( 0 == strncmp( MeshType, tokenType, strlen( tokenType ) ) ) { + return MeshToken; + } else if( 0 == strncmp( VertexArrayType, tokenType, strlen( tokenType ) ) ) { + return VertexArrayToken; + } else if( 0 == strncmp( IndexArrayType, tokenType, strlen( tokenType ) ) ) { + return IndexArrayToken; + } else if( 0 == strncmp( MaterialType, tokenType, strlen( tokenType ) ) ) { + return MaterialToken; + } else if( 0 == strncmp( ColorType, tokenType, strlen( tokenType ) ) ) { + return ColorToken; + } else if( 0 == strncmp( TextureType, tokenType, strlen( tokenType ) ) ) { + return TextureToken; + } + + return NoneType; + } + } // Namespace Grammar namespace Assimp { namespace OpenGEX { - USE_ODDLPARSER_NS +USE_ODDLPARSER_NS //------------------------------------------------------------------------------------------------ -OpenGEXImporter::OpenGEXImporter() { - +OpenGEXImporter::OpenGEXImporter() +: m_ctx( NULL ) { + // empty } //------------------------------------------------------------------------------------------------ OpenGEXImporter::~OpenGEXImporter() { - + m_ctx = NULL; } //------------------------------------------------------------------------------------------------ @@ -120,8 +201,8 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce myParser.setBuffer( &buffer[ 0 ], buffer.size() ); bool success( myParser.parse() ); if( success ) { - Context *ctx = myParser.getContext(); - handleNodes( ctx->m_root ); + m_ctx = myParser.getContext(); + handleNodes( m_ctx->m_root ); } } @@ -138,22 +219,45 @@ void OpenGEXImporter::SetupProperties( const Importer *pImp ) { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleNodes( ODDLParser::DDLNode *node ) { +void OpenGEXImporter::handleNodes( DDLNode *node ) { if( NULL == node ) { return; } DDLNode::DllNodeList childs = node->getChildNodeList(); for( DDLNode::DllNodeList::iterator it = childs.begin(); it != childs.end(); it++ ) { - if( ( *it )->getType() == Grammar::MetricType ) { - importMetric( *it ); + Grammar::TokenType tokenType( Grammar::matchTokenType( ( *it )->getType().c_str() ) ); + switch( tokenType ) { + case Grammar::MetricToken: + importMetric( *it ); + break; + + case Grammar::NameToken: + case Grammar::ObjectRefToken: + case Grammar::MaterialRefToken: + case Grammar::MetricKeyToken: + case Grammar::GeometryNodeToken: + case Grammar::GeometryObjectToken: + case Grammar::TransformToken: + case Grammar::MeshToken: + case Grammar::VertexArrayToken: + case Grammar::IndexArrayToken: + case Grammar::MaterialToken: + case Grammar::ColorToken: + case Grammar::TextureToken: + default: + break; } } } //------------------------------------------------------------------------------------------------ void OpenGEXImporter::importMetric( DDLNode *node ) { - if( NULL == node ) { + if( NULL == node || NULL == m_ctx ) { + return; + } + + if( m_ctx->m_root != node->getParent() ) { return; } @@ -162,9 +266,18 @@ void OpenGEXImporter::importMetric( DDLNode *node ) { if( NULL != prop->m_id ) { if( Value::ddl_string == prop->m_primData->m_type ) { std::string valName( (char*) prop->m_primData->m_data ); - Value *val( node->getValue() ); - if( NULL != val ) { - + int type( Grammar::isValidMetricType( valName.c_str() ) ); + if( -1 != type ) { + Value *val( node->getValue() ); + if( NULL != val ) { + if( Value::ddl_float == val->m_type ) { + m_metrics[ type ].m_floatValue = val->getFloat(); + } else if( Value::ddl_int32 == val->m_type ) { + m_metrics[ type ].m_floatValue = val->getInt32(); + } else { + throw DeadlyImportError( "OpenGEX: invalid data type for Metric node." ); + } + } } } } diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 58641775e..9e8b06ff3 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -53,6 +53,19 @@ namespace ODDLParser { namespace Assimp { namespace OpenGEX { +struct MetricInfo { + enum Type { + Distance = 0, + Angle, + Time, + Up, + Max + }; + + std::string m_stringValue; + float m_floatValue; +}; + /** @brief This class is used to implement the OpenGEX importer * * See http://opengex.org/OpenGEX.pdf for spec. @@ -82,6 +95,10 @@ protected: void importMetric( ODDLParser::DDLNode *node ); void ParseGeoObject(); void ParseMaterial(); + +private: + ODDLParser::Context *m_ctx; + MetricInfo m_metrics[ MetricInfo::Max ]; }; } // Namespace OpenGEX From bd1168af30b89f3c02a3c04369cbebc64867b977 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 10 Feb 2015 20:46:02 +0100 Subject: [PATCH 23/39] fix invalid line endling handling. Signed-off-by: Kim Kulling --- code/ObjFileParser.cpp | 914 +++++++++--------- code/ParsingUtils.h | 70 +- .../openddlparser/OpenDDLParserUtils.h | 2 +- 3 files changed, 493 insertions(+), 493 deletions(-) diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index 34bb01e0a..c4dff0ba0 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -57,177 +57,177 @@ const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME; // ------------------------------------------------------------------- // Constructor with loaded data and directories. ObjFileParser::ObjFileParser(std::vector &Data,const std::string &strModelName, IOSystem *io ) : - m_DataIt(Data.begin()), - m_DataItEnd(Data.end()), - m_pModel(NULL), - m_uiLine(0), - m_pIO( io ) + m_DataIt(Data.begin()), + m_DataItEnd(Data.end()), + m_pModel(NULL), + m_uiLine(0), + m_pIO( io ) { - std::fill_n(m_buffer,BUFFERSIZE,0); + std::fill_n(m_buffer,BUFFERSIZE,0); - // Create the model instance to store all the data - m_pModel = new ObjFile::Model(); - m_pModel->m_ModelName = strModelName; - + // Create the model instance to store all the data + m_pModel = new ObjFile::Model(); + m_pModel->m_ModelName = strModelName; + // create default material and store it - m_pModel->m_pDefaultMaterial = new ObjFile::Material(); - m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL ); + m_pModel->m_pDefaultMaterial = new ObjFile::Material(); + m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL ); m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL ); - m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial; - - // Start parsing the file - parseFile(); + m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial; + + // Start parsing the file + parseFile(); } // ------------------------------------------------------------------- // Destructor ObjFileParser::~ObjFileParser() { - delete m_pModel; - m_pModel = NULL; + delete m_pModel; + m_pModel = NULL; } // ------------------------------------------------------------------- // Returns a pointer to the model instance. ObjFile::Model *ObjFileParser::GetModel() const { - return m_pModel; + return m_pModel; } // ------------------------------------------------------------------- // File parsing method. void ObjFileParser::parseFile() { - if (m_DataIt == m_DataItEnd) - return; + if (m_DataIt == m_DataItEnd) + return; - while (m_DataIt != m_DataItEnd) - { - switch (*m_DataIt) - { - case 'v': // Parse a vertex texture coordinate - { - ++m_DataIt; - if (*m_DataIt == ' ' || *m_DataIt == '\t') { - // read in vertex definition - getVector3(m_pModel->m_Vertices); - } else if (*m_DataIt == 't') { - // read in texture coordinate ( 2D or 3D ) + while (m_DataIt != m_DataItEnd) + { + switch (*m_DataIt) + { + case 'v': // Parse a vertex texture coordinate + { + ++m_DataIt; + if (*m_DataIt == ' ' || *m_DataIt == '\t') { + // read in vertex definition + getVector3(m_pModel->m_Vertices); + } else if (*m_DataIt == 't') { + // read in texture coordinate ( 2D or 3D ) ++m_DataIt; getVector( m_pModel->m_TextureCoord ); - } else if (*m_DataIt == 'n') { - // Read in normal vector definition - ++m_DataIt; - getVector3( m_pModel->m_Normals ); - } - } - break; + } else if (*m_DataIt == 'n') { + // Read in normal vector definition + ++m_DataIt; + getVector3( m_pModel->m_Normals ); + } + } + break; - case 'p': // Parse a face, line or point statement - case 'l': - case 'f': - { - getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' - ? aiPrimitiveType_LINE : aiPrimitiveType_POINT)); - } - break; + case 'p': // Parse a face, line or point statement + case 'l': + case 'f': + { + getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' + ? aiPrimitiveType_LINE : aiPrimitiveType_POINT)); + } + break; - case '#': // Parse a comment - { - getComment(); - } - break; + case '#': // Parse a comment + { + getComment(); + } + break; - case 'u': // Parse a material desc. setter - { - getMaterialDesc(); - } - break; + case 'u': // Parse a material desc. setter + { + getMaterialDesc(); + } + break; - case 'm': // Parse a material library or merging group ('mg') - { - if (*(m_DataIt + 1) == 'g') - getGroupNumberAndResolution(); - else - getMaterialLib(); - } - break; + case 'm': // Parse a material library or merging group ('mg') + { + if (*(m_DataIt + 1) == 'g') + getGroupNumberAndResolution(); + else + getMaterialLib(); + } + break; - case 'g': // Parse group name - { - getGroupName(); - } - break; + case 'g': // Parse group name + { + getGroupName(); + } + break; - case 's': // Parse group number - { - getGroupNumber(); - } - break; + case 's': // Parse group number + { + getGroupNumber(); + } + break; - case 'o': // Parse object name - { - getObjectName(); - } - break; - - default: - { - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - } - break; - } - } + case 'o': // Parse object name + { + getObjectName(); + } + break; + + default: + { + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + } + } } // ------------------------------------------------------------------- // Copy the next word in a temporary buffer void ObjFileParser::copyNextWord(char *pBuffer, size_t length) { - size_t index = 0; - m_DataIt = getNextWord(m_DataIt, m_DataItEnd); + size_t index = 0; + m_DataIt = getNextWord(m_DataIt, m_DataItEnd); while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) { - pBuffer[index] = *m_DataIt; - index++; + pBuffer[index] = *m_DataIt; + index++; if( index == length - 1 ) { break; } - ++m_DataIt; - } + ++m_DataIt; + } - ai_assert(index < length); - pBuffer[index] = '\0'; + ai_assert(index < length); + pBuffer[index] = '\0'; } // ------------------------------------------------------------------- // Copy the next line into a temporary buffer void ObjFileParser::copyNextLine(char *pBuffer, size_t length) { - size_t index = 0u; + size_t index = 0u; - // some OBJ files have line continuations using \ (such as in C++ et al) - bool continuation = false; - for (;m_DataIt != m_DataItEnd && index < length-1; ++m_DataIt) - { - const char c = *m_DataIt; - if (c == '\\') { - continuation = true; - continue; - } - - if (c == '\n' || c == '\r') { - if(continuation) { - pBuffer[ index++ ] = ' '; - continue; - } - break; - } + // some OBJ files have line continuations using \ (such as in C++ et al) + bool continuation = false; + for (;m_DataIt != m_DataItEnd && index < length-1; ++m_DataIt) + { + const char c = *m_DataIt; + if (c == '\\') { + continuation = true; + continue; + } + + if (c == '\n' || c == '\r') { + if(continuation) { + pBuffer[ index++ ] = ' '; + continue; + } + break; + } - continuation = false; - pBuffer[ index++ ] = c; - } - ai_assert(index < length); - pBuffer[ index ] = '\0'; + continuation = false; + pBuffer[ index++ ] = c; + } + ai_assert(index < length); + pBuffer[ index ] = '\0'; } // ------------------------------------------------------------------- @@ -268,391 +268,391 @@ void ObjFileParser::getVector( std::vector &point3d_array ) { // ------------------------------------------------------------------- // Get values for a new 3D vector instance void ObjFileParser::getVector3(std::vector &point3d_array) { - float x, y, z; - copyNextWord(m_buffer, BUFFERSIZE); - x = (float) fast_atof(m_buffer); - - copyNextWord(m_buffer, BUFFERSIZE); - y = (float) fast_atof(m_buffer); + float x, y, z; + copyNextWord(m_buffer, BUFFERSIZE); + x = (float) fast_atof(m_buffer); + + copyNextWord(m_buffer, BUFFERSIZE); + y = (float) fast_atof(m_buffer); copyNextWord( m_buffer, BUFFERSIZE ); z = ( float ) fast_atof( m_buffer ); - point3d_array.push_back( aiVector3D( x, y, z ) ); - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + point3d_array.push_back( aiVector3D( x, y, z ) ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get values for a new 2D vector instance void ObjFileParser::getVector2( std::vector &point2d_array ) { - float x, y; - copyNextWord(m_buffer, BUFFERSIZE); - x = (float) fast_atof(m_buffer); - - copyNextWord(m_buffer, BUFFERSIZE); - y = (float) fast_atof(m_buffer); + float x, y; + copyNextWord(m_buffer, BUFFERSIZE); + x = (float) fast_atof(m_buffer); + + copyNextWord(m_buffer, BUFFERSIZE); + y = (float) fast_atof(m_buffer); - point2d_array.push_back(aiVector2D(x, y)); + point2d_array.push_back(aiVector2D(x, y)); - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get values for a new face instance void ObjFileParser::getFace(aiPrimitiveType type) { - copyNextLine(m_buffer, BUFFERSIZE); - if (m_DataIt == m_DataItEnd) - return; + copyNextLine(m_buffer, BUFFERSIZE); + if (m_DataIt == m_DataItEnd) + return; - char *pPtr = m_buffer; - char *pEnd = &pPtr[BUFFERSIZE]; - pPtr = getNextToken(pPtr, pEnd); - if (pPtr == pEnd || *pPtr == '\0') - return; + char *pPtr = m_buffer; + char *pEnd = &pPtr[BUFFERSIZE]; + pPtr = getNextToken(pPtr, pEnd); + if (pPtr == pEnd || *pPtr == '\0') + return; - std::vector *pIndices = new std::vector; - std::vector *pTexID = new std::vector; - std::vector *pNormalID = new std::vector; - bool hasNormal = false; + std::vector *pIndices = new std::vector; + std::vector *pTexID = new std::vector; + std::vector *pNormalID = new std::vector; + bool hasNormal = false; - const int vSize = m_pModel->m_Vertices.size(); - const int vtSize = m_pModel->m_TextureCoord.size(); - const int vnSize = m_pModel->m_Normals.size(); + const int vSize = m_pModel->m_Vertices.size(); + const int vtSize = m_pModel->m_TextureCoord.size(); + const int vnSize = m_pModel->m_Normals.size(); - const bool vt = (!m_pModel->m_TextureCoord.empty()); - const bool vn = (!m_pModel->m_Normals.empty()); - int iStep = 0, iPos = 0; - while (pPtr != pEnd) - { - iStep = 1; + const bool vt = (!m_pModel->m_TextureCoord.empty()); + const bool vn = (!m_pModel->m_Normals.empty()); + int iStep = 0, iPos = 0; + while (pPtr != pEnd) + { + iStep = 1; - if (IsLineEnd(*pPtr)) - break; + if (IsLineEnd(*pPtr)) + break; - if (*pPtr=='/' ) - { - if (type == aiPrimitiveType_POINT) { - DefaultLogger::get()->error("Obj: Separator unexpected in point statement"); - } - if (iPos == 0) - { - //if there are no texture coordinates in the file, but normals - if (!vt && vn) { - iPos = 1; - iStep++; - } - } - iPos++; - } + if (*pPtr=='/' ) + { + if (type == aiPrimitiveType_POINT) { + DefaultLogger::get()->error("Obj: Separator unexpected in point statement"); + } + if (iPos == 0) + { + //if there are no texture coordinates in the file, but normals + if (!vt && vn) { + iPos = 1; + iStep++; + } + } + iPos++; + } else if( IsSpaceOrNewLine( *pPtr ) ) - { - iPos = 0; - } - else - { - //OBJ USES 1 Base ARRAYS!!!! - const int iVal = atoi( pPtr ); + { + iPos = 0; + } + else + { + //OBJ USES 1 Base ARRAYS!!!! + const int iVal = atoi( pPtr ); - // increment iStep position based off of the sign and # of digits - int tmp = iVal; - if (iVal < 0) - ++iStep; - while ( ( tmp = tmp / 10 )!=0 ) - ++iStep; + // increment iStep position based off of the sign and # of digits + int tmp = iVal; + if (iVal < 0) + ++iStep; + while ( ( tmp = tmp / 10 )!=0 ) + ++iStep; - if ( iVal > 0 ) - { - // Store parsed index - if ( 0 == iPos ) - { - pIndices->push_back( iVal-1 ); - } - else if ( 1 == iPos ) - { - pTexID->push_back( iVal-1 ); - } - else if ( 2 == iPos ) - { - pNormalID->push_back( iVal-1 ); - hasNormal = true; - } - else - { - reportErrorTokenInFace(); - } - } - else if ( iVal < 0 ) - { - // Store relatively index - if ( 0 == iPos ) - { - pIndices->push_back( vSize + iVal ); - } - else if ( 1 == iPos ) - { - pTexID->push_back( vtSize + iVal ); - } - else if ( 2 == iPos ) - { - pNormalID->push_back( vnSize + iVal ); - hasNormal = true; - } - else - { - reportErrorTokenInFace(); - } - } - } - pPtr += iStep; - } + if ( iVal > 0 ) + { + // Store parsed index + if ( 0 == iPos ) + { + pIndices->push_back( iVal-1 ); + } + else if ( 1 == iPos ) + { + pTexID->push_back( iVal-1 ); + } + else if ( 2 == iPos ) + { + pNormalID->push_back( iVal-1 ); + hasNormal = true; + } + else + { + reportErrorTokenInFace(); + } + } + else if ( iVal < 0 ) + { + // Store relatively index + if ( 0 == iPos ) + { + pIndices->push_back( vSize + iVal ); + } + else if ( 1 == iPos ) + { + pTexID->push_back( vtSize + iVal ); + } + else if ( 2 == iPos ) + { + pNormalID->push_back( vnSize + iVal ); + hasNormal = true; + } + else + { + reportErrorTokenInFace(); + } + } + } + pPtr += iStep; + } - if ( pIndices->empty() ) - { - DefaultLogger::get()->error("Obj: Ignoring empty face"); - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - return; - } + if ( pIndices->empty() ) + { + DefaultLogger::get()->error("Obj: Ignoring empty face"); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + return; + } - ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type ); - - // Set active material, if one set - if (NULL != m_pModel->m_pCurrentMaterial) - face->m_pMaterial = m_pModel->m_pCurrentMaterial; - else - face->m_pMaterial = m_pModel->m_pDefaultMaterial; + ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type ); + + // Set active material, if one set + if (NULL != m_pModel->m_pCurrentMaterial) + face->m_pMaterial = m_pModel->m_pCurrentMaterial; + else + face->m_pMaterial = m_pModel->m_pDefaultMaterial; - // Create a default object, if nothing is there - if ( NULL == m_pModel->m_pCurrent ) - createObject( "defaultobject" ); - - // Assign face to mesh - if ( NULL == m_pModel->m_pCurrentMesh ) - { - createMesh(); - } - - // Store the face - m_pModel->m_pCurrentMesh->m_Faces.push_back( face ); - m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size(); - m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size(); - if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) - { - m_pModel->m_pCurrentMesh->m_hasNormals = true; - } - // Skip the rest of the line - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + // Create a default object, if nothing is there + if ( NULL == m_pModel->m_pCurrent ) + createObject( "defaultobject" ); + + // Assign face to mesh + if ( NULL == m_pModel->m_pCurrentMesh ) + { + createMesh(); + } + + // Store the face + m_pModel->m_pCurrentMesh->m_Faces.push_back( face ); + m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size(); + m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size(); + if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) + { + m_pModel->m_pCurrentMesh->m_hasNormals = true; + } + // Skip the rest of the line + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get values for a new material description void ObjFileParser::getMaterialDesc() { - // Each material request a new object. - // Sometimes the object is already created (see 'o' tag by example), but it is not initialized ! - // So, we create a new object only if the current on is already initialized ! - if (m_pModel->m_pCurrent != NULL && - ( m_pModel->m_pCurrent->m_Meshes.size() > 1 || - (m_pModel->m_pCurrent->m_Meshes.size() == 1 && m_pModel->m_Meshes[m_pModel->m_pCurrent->m_Meshes[0]]->m_Faces.size() != 0) ) - ) - m_pModel->m_pCurrent = NULL; + // Each material request a new object. + // Sometimes the object is already created (see 'o' tag by example), but it is not initialized ! + // So, we create a new object only if the current on is already initialized ! + if (m_pModel->m_pCurrent != NULL && + ( m_pModel->m_pCurrent->m_Meshes.size() > 1 || + (m_pModel->m_pCurrent->m_Meshes.size() == 1 && m_pModel->m_Meshes[m_pModel->m_pCurrent->m_Meshes[0]]->m_Faces.size() != 0) ) + ) + m_pModel->m_pCurrent = NULL; - // Get next data for material data - m_DataIt = getNextToken(m_DataIt, m_DataItEnd); - if (m_DataIt == m_DataItEnd) - return; + // Get next data for material data + m_DataIt = getNextToken(m_DataIt, m_DataItEnd); + if (m_DataIt == m_DataItEnd) + return; - char *pStart = &(*m_DataIt); + char *pStart = &(*m_DataIt); while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) { ++m_DataIt; } - // Get name - std::string strName(pStart, &(*m_DataIt)); - if ( strName.empty()) - return; + // Get name + std::string strName(pStart, &(*m_DataIt)); + if ( strName.empty()) + return; - // Search for material - std::map::iterator it = m_pModel->m_MaterialMap.find( strName ); - if ( it == m_pModel->m_MaterialMap.end() ) - { - // Not found, use default material - m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; - DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping"); - } - else - { - // Found, using detected material - m_pModel->m_pCurrentMaterial = (*it).second; - if ( needsNewMesh( strName )) - { - createMesh(); - } - m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName ); - } + // Search for material + std::map::iterator it = m_pModel->m_MaterialMap.find( strName ); + if ( it == m_pModel->m_MaterialMap.end() ) + { + // Not found, use default material + m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; + DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping"); + } + else + { + // Found, using detected material + m_pModel->m_pCurrentMaterial = (*it).second; + if ( needsNewMesh( strName )) + { + createMesh(); + } + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName ); + } - // Skip rest of line - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + // Skip rest of line + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get a comment, values will be skipped void ObjFileParser::getComment() { - while (m_DataIt != m_DataItEnd) - { - if ( '\n' == (*m_DataIt)) - { - ++m_DataIt; - break; - } - else - { - ++m_DataIt; - } - } + while (m_DataIt != m_DataItEnd) + { + if ( '\n' == (*m_DataIt)) + { + ++m_DataIt; + break; + } + else + { + ++m_DataIt; + } + } } // ------------------------------------------------------------------- // Get material library from file. void ObjFileParser::getMaterialLib() { - // Translate tuple - m_DataIt = getNextToken(m_DataIt, m_DataItEnd); + // Translate tuple + m_DataIt = getNextToken(m_DataIt, m_DataItEnd); if( m_DataIt == m_DataItEnd ) { return; } - - char *pStart = &(*m_DataIt); + + char *pStart = &(*m_DataIt); while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) { ++m_DataIt; } - // Check for existence - const std::string strMatName(pStart, &(*m_DataIt)); - IOStream *pFile = m_pIO->Open(strMatName); + // Check for existence + const std::string strMatName(pStart, &(*m_DataIt)); + IOStream *pFile = m_pIO->Open(strMatName); - if (!pFile ) - { - DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName); - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - return; - } + if (!pFile ) + { + DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + return; + } - // Import material library data from file - std::vector buffer; - BaseImporter::TextFileToBuffer(pFile,buffer); - m_pIO->Close( pFile ); + // Import material library data from file + std::vector buffer; + BaseImporter::TextFileToBuffer(pFile,buffer); + m_pIO->Close( pFile ); - // Importing the material library - ObjFileMtlImporter mtlImporter( buffer, strMatName, m_pModel ); + // Importing the material library + ObjFileMtlImporter mtlImporter( buffer, strMatName, m_pModel ); } // ------------------------------------------------------------------- // Set a new material definition as the current material. void ObjFileParser::getNewMaterial() { - m_DataIt = getNextToken(m_DataIt, m_DataItEnd); - m_DataIt = getNextWord(m_DataIt, m_DataItEnd); + m_DataIt = getNextToken(m_DataIt, m_DataItEnd); + m_DataIt = getNextWord(m_DataIt, m_DataItEnd); if( m_DataIt == m_DataItEnd ) { return; } - char *pStart = &(*m_DataIt); - std::string strMat( pStart, *m_DataIt ); + char *pStart = &(*m_DataIt); + std::string strMat( pStart, *m_DataIt ); while( m_DataIt != m_DataItEnd && IsSpaceOrNewLine( *m_DataIt ) ) { ++m_DataIt; } - std::map::iterator it = m_pModel->m_MaterialMap.find( strMat ); - if ( it == m_pModel->m_MaterialMap.end() ) - { - // Show a warning, if material was not found - DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat); - m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; - } - else - { - // Set new material - if ( needsNewMesh( strMat ) ) - { - createMesh(); - } - m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat ); - } + std::map::iterator it = m_pModel->m_MaterialMap.find( strMat ); + if ( it == m_pModel->m_MaterialMap.end() ) + { + // Show a warning, if material was not found + DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat); + m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; + } + else + { + // Set new material + if ( needsNewMesh( strMat ) ) + { + createMesh(); + } + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat ); + } - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- int ObjFileParser::getMaterialIndex( const std::string &strMaterialName ) { - int mat_index = -1; + int mat_index = -1; if( strMaterialName.empty() ) { return mat_index; } - for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) - { - if ( strMaterialName == m_pModel->m_MaterialLib[ index ]) - { - mat_index = (int)index; - break; - } - } - return mat_index; + for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) + { + if ( strMaterialName == m_pModel->m_MaterialLib[ index ]) + { + mat_index = (int)index; + break; + } + } + return mat_index; } // ------------------------------------------------------------------- // Getter for a group name. void ObjFileParser::getGroupName() { - std::string strGroupName; + std::string strGroupName; - m_DataIt = getName(m_DataIt, m_DataItEnd, strGroupName); + m_DataIt = getName(m_DataIt, m_DataItEnd, strGroupName); if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) { return; } - // Change active group, if necessary - if ( m_pModel->m_strActiveGroup != strGroupName ) - { - // Search for already existing entry - ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(strGroupName); - - // We are mapping groups into the object structure - createObject( strGroupName ); - - // New group name, creating a new entry - if (it == m_pModel->m_Groups.end()) - { - std::vector *pFaceIDArray = new std::vector; - m_pModel->m_Groups[ strGroupName ] = pFaceIDArray; - m_pModel->m_pGroupFaceIDs = (pFaceIDArray); - } - else - { - m_pModel->m_pGroupFaceIDs = (*it).second; - } - m_pModel->m_strActiveGroup = strGroupName; - } - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + // Change active group, if necessary + if ( m_pModel->m_strActiveGroup != strGroupName ) + { + // Search for already existing entry + ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(strGroupName); + + // We are mapping groups into the object structure + createObject( strGroupName ); + + // New group name, creating a new entry + if (it == m_pModel->m_Groups.end()) + { + std::vector *pFaceIDArray = new std::vector; + m_pModel->m_Groups[ strGroupName ] = pFaceIDArray; + m_pModel->m_pGroupFaceIDs = (pFaceIDArray); + } + else + { + m_pModel->m_pGroupFaceIDs = (*it).second; + } + m_pModel->m_strActiveGroup = strGroupName; + } + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Not supported void ObjFileParser::getGroupNumber() { - // Not used + // Not used - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Not supported void ObjFileParser::getGroupNumberAndResolution() { - // Not used + // Not used - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- @@ -660,105 +660,105 @@ void ObjFileParser::getGroupNumberAndResolution() // identify it. void ObjFileParser::getObjectName() { - m_DataIt = getNextToken(m_DataIt, m_DataItEnd); + m_DataIt = getNextToken(m_DataIt, m_DataItEnd); if( m_DataIt == m_DataItEnd ) { return; } - char *pStart = &(*m_DataIt); + char *pStart = &(*m_DataIt); while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) { ++m_DataIt; } - std::string strObjectName(pStart, &(*m_DataIt)); - if (!strObjectName.empty()) - { - // Reset current object - m_pModel->m_pCurrent = NULL; - - // Search for actual object - for (std::vector::const_iterator it = m_pModel->m_Objects.begin(); - it != m_pModel->m_Objects.end(); - ++it) - { - if ((*it)->m_strObjName == strObjectName) - { - m_pModel->m_pCurrent = *it; - break; - } - } + std::string strObjectName(pStart, &(*m_DataIt)); + if (!strObjectName.empty()) + { + // Reset current object + m_pModel->m_pCurrent = NULL; + + // Search for actual object + for (std::vector::const_iterator it = m_pModel->m_Objects.begin(); + it != m_pModel->m_Objects.end(); + ++it) + { + if ((*it)->m_strObjName == strObjectName) + { + m_pModel->m_pCurrent = *it; + break; + } + } - // Allocate a new object, if current one was not found before + // Allocate a new object, if current one was not found before if( NULL == m_pModel->m_pCurrent ) { createObject( strObjectName ); } - } - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Creates a new object instance void ObjFileParser::createObject(const std::string &strObjectName) { - ai_assert( NULL != m_pModel ); - //ai_assert( !strObjectName.empty() ); + ai_assert( NULL != m_pModel ); + //ai_assert( !strObjectName.empty() ); - m_pModel->m_pCurrent = new ObjFile::Object; - m_pModel->m_pCurrent->m_strObjName = strObjectName; - m_pModel->m_Objects.push_back( m_pModel->m_pCurrent ); - - createMesh(); + m_pModel->m_pCurrent = new ObjFile::Object; + m_pModel->m_pCurrent->m_strObjName = strObjectName; + m_pModel->m_Objects.push_back( m_pModel->m_pCurrent ); + + createMesh(); - if( m_pModel->m_pCurrentMaterial ) - { - m_pModel->m_pCurrentMesh->m_uiMaterialIndex = - getMaterialIndex( m_pModel->m_pCurrentMaterial->MaterialName.data ); - m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial; - } + if( m_pModel->m_pCurrentMaterial ) + { + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = + getMaterialIndex( m_pModel->m_pCurrentMaterial->MaterialName.data ); + m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial; + } } // ------------------------------------------------------------------- // Creates a new mesh void ObjFileParser::createMesh() { - ai_assert( NULL != m_pModel ); - m_pModel->m_pCurrentMesh = new ObjFile::Mesh; - m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh ); - unsigned int meshId = m_pModel->m_Meshes.size()-1; - if ( NULL != m_pModel->m_pCurrent ) - { - m_pModel->m_pCurrent->m_Meshes.push_back( meshId ); - } - else - { - DefaultLogger::get()->error("OBJ: No object detected to attach a new mesh instance."); - } + ai_assert( NULL != m_pModel ); + m_pModel->m_pCurrentMesh = new ObjFile::Mesh; + m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh ); + unsigned int meshId = m_pModel->m_Meshes.size()-1; + if ( NULL != m_pModel->m_pCurrent ) + { + m_pModel->m_pCurrent->m_Meshes.push_back( meshId ); + } + else + { + DefaultLogger::get()->error("OBJ: No object detected to attach a new mesh instance."); + } } // ------------------------------------------------------------------- // Returns true, if a new mesh must be created. bool ObjFileParser::needsNewMesh( const std::string &rMaterialName ) { - if(m_pModel->m_pCurrentMesh == 0) - { - // No mesh data yet - return true; - } - bool newMat = false; - int matIdx = getMaterialIndex( rMaterialName ); - int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex; - if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) || curMatIdx != matIdx ) - { - // New material -> only one material per mesh, so we need to create a new - // material - newMat = true; - } - return newMat; + if(m_pModel->m_pCurrentMesh == 0) + { + // No mesh data yet + return true; + } + bool newMat = false; + int matIdx = getMaterialIndex( rMaterialName ); + int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex; + if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) || curMatIdx != matIdx ) + { + // New material -> only one material per mesh, so we need to create a new + // material + newMat = true; + } + return newMat; } // ------------------------------------------------------------------- // Shows an error in parsing process. void ObjFileParser::reportErrorTokenInFace() { - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - DefaultLogger::get()->error("OBJ: Not supported token in face description detected"); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + DefaultLogger::get()->error("OBJ: Not supported token in face description detected"); } // ------------------------------------------------------------------- diff --git a/code/ParsingUtils.h b/code/ParsingUtils.h index 25495fd51..ce15f790f 100644 --- a/code/ParsingUtils.h +++ b/code/ParsingUtils.h @@ -64,7 +64,7 @@ static const unsigned int BufferSize = 4096; template AI_FORCE_INLINE char_t ToLower( char_t in) { - return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in; + return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in; } // --------------------------------------------------------------------------------- @@ -77,35 +77,35 @@ AI_FORCE_INLINE char_t ToUpper( char_t in) { template AI_FORCE_INLINE bool IsUpper( char_t in) { - return (in >= (char_t)'A' && in <= (char_t)'Z'); + return (in >= (char_t)'A' && in <= (char_t)'Z'); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsLower( char_t in) { - return (in >= (char_t)'a' && in <= (char_t)'z'); + return (in >= (char_t)'a' && in <= (char_t)'z'); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsSpace( char_t in) { - return (in == (char_t)' ' || in == (char_t)'\t'); + return (in == (char_t)' ' || in == (char_t)'\t'); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsLineEnd( char_t in) { - return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f'); + return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f'); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in) { - return IsSpace(in) || IsLineEnd(in); + return IsSpace(in) || IsLineEnd(in); } // --------------------------------------------------------------------------------- @@ -115,15 +115,15 @@ AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out) while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) { ++in; } - *out = in; - return !IsLineEnd(*in); + *out = in; + return !IsLineEnd(*in); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipSpaces( const char_t** inout) { - return SkipSpaces(*inout,inout); + return SkipSpaces(*inout,inout); } // --------------------------------------------------------------------------------- @@ -134,19 +134,19 @@ AI_FORCE_INLINE bool SkipLine( const char_t* in, const char_t** out) ++in; } - // files are opened in binary mode. Ergo there are both NL and CR + // files are opened in binary mode. Ergo there are both NL and CR while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { ++in; } - *out = in; - return *in != (char_t)'\0'; + *out = in; + return *in != (char_t)'\0'; } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipLine( const char_t** inout) { - return SkipLine(*inout,inout); + return SkipLine(*inout,inout); } // --------------------------------------------------------------------------------- @@ -156,15 +156,15 @@ AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { ++in; } - *out = in; - return *in != '\0'; + *out = in; + return *in != '\0'; } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout) { - return SkipSpacesAndLineEnd(*inout,inout); + return SkipSpacesAndLineEnd(*inout,inout); } // --------------------------------------------------------------------------------- @@ -175,12 +175,12 @@ AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize return false; } - char* _out = out; + char* _out = out; char* const end = _out + BufferSize; while( !IsLineEnd( *buffer ) && _out < end ) { *_out++ = *buffer++; } - *_out = (char_t)'\0'; + *_out = (char_t)'\0'; while( IsLineEnd( *buffer ) && '\0' != *buffer ) { ++buffer; @@ -193,19 +193,19 @@ AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize template AI_FORCE_INLINE bool IsNumeric( char_t in) { - return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in; + return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in; } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len) { - if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) { - in += len+1; - return true; - } + if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) { + in += len+1; + return true; + } - return false; + return false; } // --------------------------------------------------------------------------------- /** @brief Case-ignoring version of TokenMatch @@ -215,25 +215,25 @@ AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len */ AI_FORCE_INLINE bool TokenMatchI(const char*& in, const char* token, unsigned int len) { - if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) { - in += len+1; - return true; - } - return false; + if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) { + in += len+1; + return true; + } + return false; } // --------------------------------------------------------------------------------- AI_FORCE_INLINE void SkipToken(const char*& in) { - SkipSpaces(&in); - while (!IsSpaceOrNewLine(*in))++in; + SkipSpaces(&in); + while (!IsSpaceOrNewLine(*in))++in; } // --------------------------------------------------------------------------------- AI_FORCE_INLINE std::string GetNextToken(const char*& in) { - SkipSpacesAndLineEnd(&in); - const char* cur = in; - while (!IsSpaceOrNewLine(*in))++in; - return std::string(cur,(size_t)(in-cur)); + SkipSpacesAndLineEnd(&in); + const char* cur = in; + while (!IsSpaceOrNewLine(*in))++in; + return std::string(cur,(size_t)(in-cur)); } // --------------------------------------------------------------------------------- diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h index 9e978ade2..179a51326 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -62,7 +62,7 @@ bool isSpace( const T in ) { template inline bool isNewLine( const T in ) { - return ( '\n' == in ); + return ( '\n' == in || ( '\r' == in ) ); } template From f5f0c9f7cf15ca6ecabc8e6ec82346191f204b00 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 14 Feb 2015 16:11:46 +0100 Subject: [PATCH 24/39] update openddl-parser. Signed-off-by: Kim Kulling --- contrib/openddlparser/code/Value.cpp | 16 +++++++++++++++- .../openddlparser/include/openddlparser/Value.h | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/contrib/openddlparser/code/Value.cpp b/contrib/openddlparser/code/Value.cpp index 802e8dd61..5e88d6572 100644 --- a/contrib/openddlparser/code/Value.cpp +++ b/contrib/openddlparser/code/Value.cpp @@ -21,6 +21,7 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ #include + #include #include @@ -109,6 +110,15 @@ double Value::getDouble() const { return v; } +void Value::setString( const std::string &str ) { + assert( ddl_string == m_type ); + ::memcpy( m_data, str.c_str(), str.size() ); + m_data[ str.size() ] = '\0'; +} +const char *Value::getString() const { + return (const char*) m_data; +} + void Value::dump() { switch( m_type ) { case ddl_none: @@ -223,7 +233,11 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) { } if( data->m_size ) { - data->m_size *= len; + size_t len1( len ); + if( Value::ddl_string == type ) { + len1++; + } + data->m_size *= len1; data->m_data = new unsigned char[ data->m_size ]; } diff --git a/contrib/openddlparser/include/openddlparser/Value.h b/contrib/openddlparser/include/openddlparser/Value.h index 0d719f994..48eb6e771 100644 --- a/contrib/openddlparser/include/openddlparser/Value.h +++ b/contrib/openddlparser/include/openddlparser/Value.h @@ -26,6 +26,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include +#include + BEGIN_ODDLPARSER_NS ///------------------------------------------------------------------------------------------------ @@ -73,6 +75,8 @@ public: float getFloat() const; void setDouble( double value ); double getDouble() const; + void setString( const std::string &str ); + const char *getString() const; void dump(); void setNext( Value *next ); Value *getNext() const; From 029286891799b1d306e59408903247b69b6dfc52 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 14 Feb 2015 16:12:09 +0100 Subject: [PATCH 25/39] add geomentry node handling. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 41 +++++++++++++++----- code/OpenGEXImporter.h | 15 +++++-- contrib/openddlparser/code/OpenDDLParser.cpp | 2 +- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 83bde51fe..0b940d39e 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -164,7 +164,8 @@ USE_ODDLPARSER_NS //------------------------------------------------------------------------------------------------ OpenGEXImporter::OpenGEXImporter() -: m_ctx( NULL ) { +: m_ctx( NULL ) +, m_currentNode( NULL ) { // empty } @@ -202,7 +203,7 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce bool success( myParser.parse() ); if( success ) { m_ctx = myParser.getContext(); - handleNodes( m_ctx->m_root ); + handleNodes( m_ctx->m_root, pScene ); } } @@ -219,7 +220,7 @@ void OpenGEXImporter::SetupProperties( const Importer *pImp ) { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleNodes( DDLNode *node ) { +void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) { if( NULL == node ) { return; } @@ -229,14 +230,20 @@ void OpenGEXImporter::handleNodes( DDLNode *node ) { Grammar::TokenType tokenType( Grammar::matchTokenType( ( *it )->getType().c_str() ) ); switch( tokenType ) { case Grammar::MetricToken: - importMetric( *it ); + handleMetricNode( *it, pScene ); break; case Grammar::NameToken: + handleNameNode( *it, pScene ); + break; + case Grammar::ObjectRefToken: case Grammar::MaterialRefToken: case Grammar::MetricKeyToken: case Grammar::GeometryNodeToken: + handleGeometryNode( *it, pScene ); + break; + case Grammar::GeometryObjectToken: case Grammar::TransformToken: case Grammar::MeshToken: @@ -252,7 +259,7 @@ void OpenGEXImporter::handleNodes( DDLNode *node ) { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::importMetric( DDLNode *node ) { +void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) { if( NULL == node || NULL == m_ctx ) { return; } @@ -267,13 +274,15 @@ void OpenGEXImporter::importMetric( DDLNode *node ) { if( Value::ddl_string == prop->m_primData->m_type ) { std::string valName( (char*) prop->m_primData->m_data ); int type( Grammar::isValidMetricType( valName.c_str() ) ); - if( -1 != type ) { + if( Grammar::NoneType != type ) { Value *val( node->getValue() ); if( NULL != val ) { if( Value::ddl_float == val->m_type ) { m_metrics[ type ].m_floatValue = val->getFloat(); } else if( Value::ddl_int32 == val->m_type ) { m_metrics[ type ].m_floatValue = val->getInt32(); + } else if( Value::ddl_string == val->m_type ) { + m_metrics[type].m_stringValue = std::string( val->getString() ); } else { throw DeadlyImportError( "OpenGEX: invalid data type for Metric node." ); } @@ -286,13 +295,27 @@ void OpenGEXImporter::importMetric( DDLNode *node ) { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::ParseGeoObject() { +void OpenGEXImporter::handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene ) { + if( NULL == m_currentNode ) { + throw DeadlyImportError( "No parent node for name." ); + return; + } + Value *val( node->getValue() ); + if( NULL != val ) { + if( Value::ddl_string != val->m_type ) { + throw DeadlyImportError( "OpenGEX: invalid data type for value in node name." ); + } + + std::string name( val->getString() ); + m_currentNode->mName.Set( name.c_str() ); + } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::ParseMaterial() { - +void OpenGEXImporter::handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene ) { + m_currentNode = new aiNode; + handleNodes( node, pScene ); } //------------------------------------------------------------------------------------------------ diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 9e8b06ff3..2bea23b45 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -64,6 +64,12 @@ struct MetricInfo { std::string m_stringValue; float m_floatValue; + + MetricInfo() + : m_stringValue( "" ) + , m_floatValue( 0.0f ) { + // empty + } }; /** @brief This class is used to implement the OpenGEX importer @@ -91,14 +97,15 @@ public: virtual void SetupProperties( const Importer *pImp ); protected: - void handleNodes( ODDLParser::DDLNode *node ); - void importMetric( ODDLParser::DDLNode *node ); - void ParseGeoObject(); - void ParseMaterial(); + void handleNodes( ODDLParser::DDLNode *node, aiScene *pScene ); + void handleMetricNode( ODDLParser::DDLNode *node, aiScene *pScene ); + void handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene ); + void handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene ); private: ODDLParser::Context *m_ctx; MetricInfo m_metrics[ MetricInfo::Max ]; + aiNode *m_currentNode; }; } // Namespace OpenGEX diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index b869aa2a1..c85f498de 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -669,7 +669,7 @@ char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData len++; } - *stringData = ValueAllocator::allocPrimData( Value::ddl_string, len + 1 ); + *stringData = ValueAllocator::allocPrimData( Value::ddl_string, len ); ::strncpy( ( char* ) ( *stringData )->m_data, start, len ); ( *stringData )->m_data[len] = '\0'; in++; From 79db48a0d14163da70a1d9f61969cd8762463285 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 9 Mar 2015 10:17:23 +0100 Subject: [PATCH 26/39] openddl-parser: latest greatest. Signed-off-by: Kim Kulling --- contrib/openddlparser/code/DDLNode.cpp | 11 +- contrib/openddlparser/code/OpenDDLParser.cpp | 216 ++++++++++-------- .../include/openddlparser/DDLNode.h | 3 + .../include/openddlparser/OpenDDLCommon.h | 10 +- .../include/openddlparser/OpenDDLParser.h | 3 +- .../openddlparser/OpenDDLParserUtils.h | 14 ++ 6 files changed, 162 insertions(+), 95 deletions(-) diff --git a/contrib/openddlparser/code/DDLNode.cpp b/contrib/openddlparser/code/DDLNode.cpp index aba11d8ae..e65f1c45e 100644 --- a/contrib/openddlparser/code/DDLNode.cpp +++ b/contrib/openddlparser/code/DDLNode.cpp @@ -52,7 +52,8 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, , m_properties( ddl_nullptr ) , m_value( ddl_nullptr ) , m_idx( idx ) -, m_dtArrayList( ddl_nullptr ) { +, m_dtArrayList( ddl_nullptr ) +, m_references( ddl_nullptr ) { if( m_parent ) { m_parent->m_children.push_back( this ); } @@ -140,6 +141,14 @@ DataArrayList *DDLNode::getDataArrayList() const { return m_dtArrayList; } +void DDLNode::setReferences( Reference *refs ) { + m_references = refs; +} + +Reference *DDLNode::getReferences() const { + return m_references; +} + DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) { const size_t idx( s_allocatedNodes.size() ); DDLNode *node = new DDLNode( type, name, idx, parent ); diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index c85f498de..46eb50fd8 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -37,26 +37,33 @@ BEGIN_ODDLPARSER_NS static const char *Version = "0.1.0"; -static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = { - "bool", - "int8", - "int16", - "int32", - "int64", - "unsigned_int8", - "unsigned_int16", - "unsigned_int32", - "unsigned_int64", - "half", - "float", - "double", - "string", - "ref" -}; +namespace Grammar { + static const char *OpenBracketToken = "{"; + static const char *CloseBracketToken = "}"; + static const char *OpenPropertyToken = "("; + static const char *ClosePropertyToken = ")"; + static const char *BoolTrue = "true"; + static const char *BoolFalse = "false"; + static const char *RefToken = "ref"; + + static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = { + "bool", + "int8", + "int16", + "int32", + "int64", + "unsigned_int8", + "unsigned_int16", + "unsigned_int32", + "unsigned_int64", + "half", + "float", + "double", + "string", + "ref" + }; +} // Namespace Grammar -static const char *BoolTrue = "true"; -static const char *BoolFalse = "false"; -static const char *RefToken = "ref"; static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallback callback ) { std::stringstream stream; @@ -65,7 +72,8 @@ static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallbac } static bool isIntegerType( Value::ValueType integerType ) { - if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) { + if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && + integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) { return false; } @@ -203,6 +211,12 @@ char *OpenDDLParser::parseNextNode( char *in, char *end ) { return in; } +static void dumpId( Identifier *id ) { + if( ddl_nullptr != id ) { + std::cout << id->m_buffer << std::endl; + } +} + char *OpenDDLParser::parseHeader( char *in, char *end ) { if( nullptr == in || in == end ) { return in; @@ -212,9 +226,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { in = OpenDDLParser::parseIdentifier( in, end, &id ); #ifdef DEBUG_HEADER_NAME - if( ddl_nullptr != id ) { - std::cout << id->m_buffer << std::endl; - } + dumpId( id ); #endif // DEBUG_HEADER_NAME in = getNextToken( in, end ); @@ -224,13 +236,14 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { in++; Property *prop( ddl_nullptr ), *prev( ddl_nullptr ); while( *in != ')' && in != end ) { - in = parseProperty( in, end, &prop ); + in = OpenDDLParser::parseProperty( in, end, &prop ); in = getNextToken( in, end ); if( *in != ',' && *in != ')' ) { logInvalidTokenError( in, ")", m_logCallback ); return in; } + if( ddl_nullptr != prop && *in != ',' ) { if( ddl_nullptr == first ) { first = prop; @@ -276,55 +289,17 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { bool error( false ); in = getNextToken( in, end ); if( *in == '{' ) { + do { + // loop over all childs ( data and nodes ) + in = parseStructureBody( in, end, error ); + } while ( *in != '}' ); in++; - in = getNextToken( in, end ); - Value::ValueType type( Value::ddl_none ); - size_t arrayLen( 0 ); - in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen ); - if( Value::ddl_none != type ) { - in = getNextToken( in, end ); - if( *in == '{' ) { - DataArrayList *dtArrayList( ddl_nullptr ); - Value *values( ddl_nullptr ); - if( 1 == arrayLen ) { - in = parseDataList( in, end, &values ); - if( ddl_nullptr != values ){ - DDLNode *currentNode( top() ); - if( ddl_nullptr != currentNode ) { - currentNode->setValue( values ); - } - } - } else if( arrayLen > 1 ) { - in = parseDataArrayList( in, end, &dtArrayList ); - if( ddl_nullptr != dtArrayList ) { - DDLNode *currentNode( top() ); - if( ddl_nullptr != currentNode ) { - currentNode->setDataArrayList( dtArrayList ); - } - } - } else { - std::cerr << "0 for array is invalid." << std::endl; - error = true; - } - } - - in = getNextToken( in, end ); - if( *in != '}' ) { - logInvalidTokenError( in, "}", m_logCallback ); - } - else { - in++; - } - } else { - in = parseHeader( in, end ); - in = parseStructure( in, end ); - } - } else { + } + else { in++; logInvalidTokenError( in, "{", m_logCallback ); error = true; return in; - } in = getNextToken( in, end ); @@ -336,6 +311,71 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { return in; } +static void setNodeValues( DDLNode *currentNode, Value *values ) { + if( ddl_nullptr != values ){ + if( ddl_nullptr != currentNode ) { + currentNode->setValue( values ); + } + } +} + +static void setNodeReferences( DDLNode *currentNode, Reference *refs ) { + if( ddl_nullptr != refs ) { + if( ddl_nullptr != currentNode ) { + currentNode->setReferences( refs ); + } + } +} + +static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayList ) { + if( ddl_nullptr != dtArrayList ) { + if( ddl_nullptr != currentNode ) { + currentNode->setDataArrayList( dtArrayList ); + } + } +} + +char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) { + if( !isNumeric( *in ) && !isCharacter( *in ) ) { + in++; + } + + in = getNextToken( in, end ); + Value::ValueType type( Value::ddl_none ); + size_t arrayLen( 0 ); + in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen ); + if( Value::ddl_none != type ) { + in = getNextToken( in, end ); + if( *in == '{' ) { + Reference *refs( ddl_nullptr ); + DataArrayList *dtArrayList( ddl_nullptr ); + Value *values( ddl_nullptr ); + if( 1 == arrayLen ) { + in = parseDataList( in, end, &values, &refs ); + setNodeValues( top(), values ); + setNodeReferences( top(), refs ); + } else if( arrayLen > 1 ) { + in = parseDataArrayList( in, end, &dtArrayList ); + setNodeDataArrayList( top(), dtArrayList ); + } else { + std::cerr << "0 for array is invalid." << std::endl; + error = true; + } + } + + in = getNextToken( in, end ); + if( *in != '}' ) { + logInvalidTokenError( in, "}", m_logCallback ); + } else { + //in++; + } + } else { + in = parseNextNode( in, end ); + } + + return in; +} + void OpenDDLParser::pushNode( DDLNode *node ) { if( nullptr == node ) { return; @@ -469,9 +509,10 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy return in; } + size_t prim_len( 0 ); for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) { - const size_t prim_len( strlen( PrimitiveTypeToken[ i ] ) ); - if( 0 == strncmp( in, PrimitiveTypeToken[ i ], prim_len ) ) { + prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] ); + if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) { type = ( Value::ValueType ) i; break; } @@ -481,7 +522,7 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy in = getNextToken( in, end ); return in; } else { - in += strlen( PrimitiveTypeToken[ type ] ); + in += prim_len; } bool ok( true ); @@ -513,27 +554,12 @@ char *OpenDDLParser::parseReference( char *in, char *end, std::vector &na return in; } - if( 0 != strncmp( in, RefToken, strlen( RefToken ) ) ) { - return in; - } else { - const size_t refTokenLen( strlen( RefToken ) ); - in += refTokenLen; - } - - in = getNextToken( in, end ); - if( '{' != *in ) { - return in; - } else { - in++; - } - - in = getNextToken( in, end ); Name *nextName( ddl_nullptr ); in = parseName( in, end, &nextName ); if( nextName ) { names.push_back( nextName ); } - while( '}' != *in ) { + while( ',' == *in ) { in = getNextSeparator( in, end ); if( ',' == *in ) { in = parseName( in, end, &nextName ); @@ -562,9 +588,9 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) len++; } len++; - int res = ::strncmp( BoolTrue, start, strlen( BoolTrue ) ); + int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) ); if( 0 != res ) { - res = ::strncmp( BoolFalse, start, strlen( BoolFalse ) ); + res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) ); if( 0 != res ) { *boolean = ddl_nullptr; return in; @@ -770,7 +796,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { return in; } -char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) { +char *OpenDDLParser::parseDataList( char *in, char *end, Value **data, Reference **refs ) { *data = ddl_nullptr; if( ddl_nullptr == in || in == end ) { return in; @@ -791,6 +817,13 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) { in = parseStringLiteral( in, end, ¤t ); } else if( isHexLiteral( in, end ) ) { in = parseHexaLiteral( in, end, ¤t ); + } else { // reference data + std::vector names; + in = parseReference( in, end, names ); + if( !names.empty() ) { + Reference *ref = new Reference( names.size(), &names[ 0 ] ); + *refs = ref; + } } if( ddl_nullptr != current ) { @@ -824,9 +857,10 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **da if( *in == '{' ) { in++; Value *current( ddl_nullptr ); + Reference *refs( nullptr ); DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); do { - in = parseDataList( in, end, ¤t ); + in = parseDataList( in, end, ¤t, &refs ); if( ddl_nullptr != current ) { if( ddl_nullptr == prev ) { *dataList = new DataArrayList; diff --git a/contrib/openddlparser/include/openddlparser/DDLNode.h b/contrib/openddlparser/include/openddlparser/DDLNode.h index bb5f87b79..93b447bb2 100644 --- a/contrib/openddlparser/include/openddlparser/DDLNode.h +++ b/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -61,6 +61,8 @@ public: Value *getValue() const; void setDataArrayList( DataArrayList *dtArrayList ); DataArrayList *getDataArrayList() const; + void setReferences( Reference *refs ); + Reference *getReferences() const; static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr ); private: @@ -78,6 +80,7 @@ private: Property *m_properties; Value *m_value; DataArrayList *m_dtArrayList; + Reference *m_references; size_t m_idx; static DllNodeList s_allocatedNodes; }; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index 789bc15ad..c7fd844a2 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -88,9 +88,15 @@ struct Reference { size_t m_numRefs; Name **m_referencedName; + Reference() + : m_numRefs( 0 ) + , m_referencedName( ddl_nullptr ) { + // empty + } + Reference( size_t numrefs, Name **names ) - : m_numRefs( numrefs ) - , m_referencedName( names ) { + : m_numRefs( numrefs ) + , m_referencedName( names ) { // empty } }; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h index 4f003a0e4..00f2c2e58 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h @@ -77,6 +77,7 @@ public: char *parseNextNode( char *current, char *end ); char *parseHeader( char *in, char *end ); char *parseStructure( char *in, char *end ); + char *parseStructureBody( char *in, char *end, bool &error ); void pushNode( DDLNode *node ); DDLNode *popNode(); DDLNode *top(); @@ -95,7 +96,7 @@ public: // static parser helpers static char *parseStringLiteral( char *in, char *end, Value **stringData ); static char *parseHexaLiteral( char *in, char *end, Value **data ); static char *parseProperty( char *in, char *end, Property **prop ); - static char *parseDataList( char *in, char *end, Value **data ); + static char *parseDataList( char *in, char *end, Value **data, Reference **refs ); static char *parseDataArrayList( char *in, char *end, DataArrayList **dataList ); static const char *getVersion(); diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h index 179a51326..b1b4f6cde 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -196,6 +196,20 @@ bool isHexLiteral( T *in, T *end ) { return false; } +template +inline +bool isReference( T *in, T *end ) { + if( *in == 'r' ) { + if( *(in+1) == 'e' ) { + if( *(in+2) == 'f' ) { + return true; + } + } + } + + return false; +} + template inline bool isEndofLine( const T in ) { From d9d7dd31ea5eb23f9ed9aac2625e8ab7fca0aba1 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 11 Mar 2015 19:05:37 +0100 Subject: [PATCH 27/39] fix linker error: undefined references to openddl_parser. Signed-off-by: Kim Kulling --- tools/assimp_cmd/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/assimp_cmd/CMakeLists.txt b/tools/assimp_cmd/CMakeLists.txt index b549f9b10..78b3139ee 100644 --- a/tools/assimp_cmd/CMakeLists.txt +++ b/tools/assimp_cmd/CMakeLists.txt @@ -28,7 +28,7 @@ IF( WIN32 ) MAIN_DEPENDENCY assimp) ENDIF( WIN32 ) -TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES}) +TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES} openddl_parser) SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES OUTPUT_NAME assimp ) From 207906f0393e829fffc4260129e0f6fb681f585f Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 16 Mar 2015 20:34:42 +0100 Subject: [PATCH 28/39] first parsing of references and geometry objects. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 47 +++++++++++++++++-- code/OpenGEXImporter.h | 6 +++ contrib/openddlparser/code/OpenDDLParser.cpp | 6 +-- .../include/openddlparser/OpenDDLCommon.h | 4 +- .../openddlparser/OpenDDLParserUtils.h | 4 +- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 0b940d39e..9c953b035 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -164,7 +164,9 @@ USE_ODDLPARSER_NS //------------------------------------------------------------------------------------------------ OpenGEXImporter::OpenGEXImporter() -: m_ctx( NULL ) +: m_meshCache() +, m_mesh2refMap() +, m_ctx( NULL ) , m_currentNode( NULL ) { // empty } @@ -205,6 +207,8 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce m_ctx = myParser.getContext(); handleNodes( m_ctx->m_root, pScene ); } + + resolveReferences(); } //------------------------------------------------------------------------------------------------ @@ -238,6 +242,9 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) { break; case Grammar::ObjectRefToken: + handleObjectRefNode( *it, pScene ); + break; + case Grammar::MaterialRefToken: case Grammar::MetricKeyToken: case Grammar::GeometryNodeToken: @@ -245,6 +252,9 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) { break; case Grammar::GeometryObjectToken: + handleGeometryObject( *it, pScene ); + break; + case Grammar::TransformToken: case Grammar::MeshToken: case Grammar::VertexArrayToken: @@ -295,7 +305,7 @@ void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene ) { +void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene *pScene ) { if( NULL == m_currentNode ) { throw DeadlyImportError( "No parent node for name." ); return; @@ -313,11 +323,42 @@ void OpenGEXImporter::handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene ) { +void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) { + if( NULL == m_currentNode ) { + throw DeadlyImportError( "No parent node for name." ); + return; + } + + Reference *ref = node->getReferences(); + if( NULL != ref ) { + for( size_t i = 0; i < ref->m_numRefs; i++ ) { + Name *currentName( ref->m_referencedName[ i ] ); + } + } +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::handleGeometryNode( DDLNode *node, aiScene *pScene ) { m_currentNode = new aiNode; handleNodes( node, pScene ); } +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) { + aiMesh *currentMesh( new aiMesh ); + const size_t idx( m_meshCache.size() ); + m_meshCache.push_back( currentMesh ); + + // store name to reference relation + m_mesh2refMap[ node->getName() ] = idx; + +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::resolveReferences() { + +} + //------------------------------------------------------------------------------------------------ } // Namespace OpenGEX diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 2bea23b45..105716f3c 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BaseImporter.h" +#include namespace ODDLParser { class DDLNode; @@ -100,9 +101,14 @@ protected: void handleNodes( ODDLParser::DDLNode *node, aiScene *pScene ); void handleMetricNode( ODDLParser::DDLNode *node, aiScene *pScene ); void handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene ); + void handleObjectRefNode( ODDLParser::DDLNode *node, aiScene *pScene ); void handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene ); + void handleGeometryObject( ODDLParser::DDLNode *node, aiScene *pScene ); + void resolveReferences(); private: + std::vector m_meshCache; + std::map m_mesh2refMap; ODDLParser::Context *m_ctx; MetricInfo m_metrics[ MetricInfo::Max ]; aiNode *m_currentNode; diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 46eb50fd8..99274f412 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -65,7 +65,7 @@ namespace Grammar { } // Namespace Grammar -static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallback callback ) { +static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) { std::stringstream stream; stream << "Invalid token " << *in << ", " << exp << " expected." << std::endl; callback( ddl_error_msg, stream.str() ); @@ -297,7 +297,7 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { } else { in++; - logInvalidTokenError( in, "{", m_logCallback ); + logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback ); error = true; return in; } @@ -365,7 +365,7 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) { in = getNextToken( in, end ); if( *in != '}' ) { - logInvalidTokenError( in, "}", m_logCallback ); + logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback ); } else { //in++; } diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index c7fd844a2..4a1ff2749 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # ifdef OPENDDLPARSER_BUILD # define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT # else -# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT +# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT # endif // OPENDDLPARSER_BUILD # pragma warning( disable : 4251 ) #else @@ -52,7 +52,7 @@ BEGIN_ODDLPARSER_NS # define ddl_nullptr nullptr #else # define ddl_nullptr NULL -#endif +#endif // OPENDDL_NO_USE_CPP11 class DDLNode; class Value; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h index b1b4f6cde..eb900309c 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -202,7 +202,9 @@ bool isReference( T *in, T *end ) { if( *in == 'r' ) { if( *(in+1) == 'e' ) { if( *(in+2) == 'f' ) { - return true; + if( ( in + 2 ) != end ) { + return true; + } } } } From 7d7ccfd6301449c47c884b2092032d42b81d8ec5 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 17 Mar 2015 14:24:28 +0100 Subject: [PATCH 29/39] fix compiler warning. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 105716f3c..0bc2378b7 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -65,10 +65,12 @@ struct MetricInfo { std::string m_stringValue; float m_floatValue; + int m_intValue; MetricInfo() : m_stringValue( "" ) - , m_floatValue( 0.0f ) { + , m_floatValue( 0.0f ) + , m_intValue( -1 ) { // empty } }; @@ -102,16 +104,33 @@ protected: void handleMetricNode( ODDLParser::DDLNode *node, aiScene *pScene ); void handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene ); void handleObjectRefNode( ODDLParser::DDLNode *node, aiScene *pScene ); + void handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene ); void handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene ); void handleGeometryObject( ODDLParser::DDLNode *node, aiScene *pScene ); + void handleMaterial( ODDLParser::DDLNode *node, aiScene *pScene ); void resolveReferences(); private: + struct RefInfo { + enum Type { + MeshRef, + MaterialRef + }; + + aiNode *m_node; + Type m_type; + std::vector m_Names; + + RefInfo( aiNode *node, Type type, std::vector &names ); + }; + std::vector m_meshCache; std::map m_mesh2refMap; + ODDLParser::Context *m_ctx; MetricInfo m_metrics[ MetricInfo::Max ]; aiNode *m_currentNode; + std::vector m_unresolvedRefStack; }; } // Namespace OpenGEX From 0d5a2ce4c1106f74cd4c13da30234c91f2af05c3 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 17 Mar 2015 14:25:15 +0100 Subject: [PATCH 30/39] openddl-parser: latest greatest with fixes for invalid reference information. Signed-off-by: Kim Kulling --- contrib/openddlparser/code/DDLNode.cpp | 17 +++++++++++++++-- .../include/openddlparser/OpenDDLCommon.h | 10 +++++++--- .../include/openddlparser/OpenDDLParserUtils.h | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/contrib/openddlparser/code/DDLNode.cpp b/contrib/openddlparser/code/DDLNode.cpp index e65f1c45e..24f0da9d1 100644 --- a/contrib/openddlparser/code/DDLNode.cpp +++ b/contrib/openddlparser/code/DDLNode.cpp @@ -44,6 +44,18 @@ static void releaseDataType( T *ptr ) { } } +static void releaseReferencedNames( Reference *ref ) { + if( ddl_nullptr == ref ) { + return; + } + + if( ref->m_referencedName ) { + for( size_t i = 0; i < ref->m_numRefs; i++ ) { + delete ref->m_referencedName; + } + } +} + DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent ) : m_type( type ) , m_name( name ) @@ -51,9 +63,9 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, , m_children() , m_properties( ddl_nullptr ) , m_value( ddl_nullptr ) -, m_idx( idx ) , m_dtArrayList( ddl_nullptr ) -, m_references( ddl_nullptr ) { +, m_references( ddl_nullptr ) +, m_idx( idx ) { if( m_parent ) { m_parent->m_children.push_back( this ); } @@ -62,6 +74,7 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode::~DDLNode() { releaseDataType( m_properties ); releaseDataType( m_value ); + releaseReferencedNames( m_references ); delete m_dtArrayList; m_dtArrayList = ddl_nullptr; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index 4a1ff2749..ff182432d 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -96,8 +96,12 @@ struct Reference { Reference( size_t numrefs, Name **names ) : m_numRefs( numrefs ) - , m_referencedName( names ) { - // empty + , m_referencedName( ddl_nullptr ) { + m_referencedName = new Name *[ numrefs ]; + for( size_t i = 0; i < numrefs; i++ ) { + Name *name = new Name( names[ i ]->m_type, names[ i ]->m_id ); + m_referencedName[ i ] = name; + } } }; @@ -105,7 +109,7 @@ struct Identifier { size_t m_len; char *m_buffer; - Identifier( size_t len, char *buffer ) + Identifier( size_t len, char buffer[] ) : m_len( len ) , m_buffer( buffer ) { // empty diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h index eb900309c..a8d21b710 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -173,7 +173,7 @@ bool isFloat( T *in, T *end ) { template inline bool isCharacter( const T in ) { - return ( in >= 'a' && in <= 'z' || in >= 'A' && in <= 'Z' ); + return ( ( in >= 'a' && in <= 'z' ) || ( in >= 'A' && in <= 'Z' ) ); } template From 59633d172f042ca28de0761820245bb58de3edb6 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 17 Mar 2015 14:25:40 +0100 Subject: [PATCH 31/39] implementation for mesh resolving. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 99 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 7 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 9c953b035..8f9a359ae 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -162,12 +162,21 @@ namespace OpenGEX { USE_ODDLPARSER_NS +//------------------------------------------------------------------------------------------------ +OpenGEXImporter::RefInfo::RefInfo( aiNode *node, Type type, std::vector &names ) +: m_node( node ) +, m_type( type ) +, m_Names( names ) { + // empty +} + //------------------------------------------------------------------------------------------------ OpenGEXImporter::OpenGEXImporter() : m_meshCache() , m_mesh2refMap() , m_ctx( NULL ) -, m_currentNode( NULL ) { +, m_currentNode( NULL ) +, m_unresolvedRefStack() { // empty } @@ -246,7 +255,12 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) { break; case Grammar::MaterialRefToken: + handleMaterialRefNode( *it, pScene ); + break; + case Grammar::MetricKeyToken: + break; + case Grammar::GeometryNodeToken: handleGeometryNode( *it, pScene ); break; @@ -256,12 +270,27 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) { break; case Grammar::TransformToken: + break; + case Grammar::MeshToken: + break; + case Grammar::VertexArrayToken: + break; + case Grammar::IndexArrayToken: + break; + case Grammar::MaterialToken: + handleMaterial( *it, pScene ); + break; + case Grammar::ColorToken: + break; + case Grammar::TextureToken: + break; + default: break; } @@ -290,7 +319,7 @@ void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) { if( Value::ddl_float == val->m_type ) { m_metrics[ type ].m_floatValue = val->getFloat(); } else if( Value::ddl_int32 == val->m_type ) { - m_metrics[ type ].m_floatValue = val->getInt32(); + m_metrics[ type ].m_intValue = val->getInt32(); } else if( Value::ddl_string == val->m_type ) { m_metrics[type].m_stringValue = std::string( val->getString() ); } else { @@ -322,6 +351,24 @@ void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene *pScene ) { } } +//------------------------------------------------------------------------------------------------ +static void getRefNames( DDLNode *node, std::vector &names ) { + ai_assert( NULL != node ); + + Reference *ref = node->getReferences(); + if( NULL != ref ) { + for( size_t i = 0; i < ref->m_numRefs; i++ ) { + Name *currentName( ref->m_referencedName[ i ] ); + if( NULL != currentName && NULL != currentName->m_id ) { + const std::string name( currentName->m_id->m_buffer ); + if( !name.empty() ) { + names.push_back( name ); + } + } + } + } +} + //------------------------------------------------------------------------------------------------ void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) { if( NULL == m_currentNode ) { @@ -329,11 +376,26 @@ void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) { return; } - Reference *ref = node->getReferences(); - if( NULL != ref ) { - for( size_t i = 0; i < ref->m_numRefs; i++ ) { - Name *currentName( ref->m_referencedName[ i ] ); - } + std::vector objRefNames; + getRefNames( node, objRefNames ); + m_currentNode->mNumMeshes = objRefNames.size(); + m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ]; + if( !objRefNames.empty() ) { + m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) ); + } +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene ) { + if( NULL == m_currentNode ) { + throw DeadlyImportError( "No parent node for name." ); + return; + } + + std::vector matRefNames; + getRefNames( node, matRefNames ); + if( !matRefNames.empty() ) { + m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MaterialRef, matRefNames ) ); } } @@ -351,12 +413,35 @@ void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) { // store name to reference relation m_mesh2refMap[ node->getName() ] = idx; +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::handleMaterial( ODDLParser::DDLNode *node, aiScene *pScene ) { } //------------------------------------------------------------------------------------------------ void OpenGEXImporter::resolveReferences() { + if( m_unresolvedRefStack.empty() ) { + return; + } + RefInfo *currentRefInfo( NULL ); + for( std::vector::iterator it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) { + currentRefInfo = *it; + if( NULL != currentRefInfo ) { + aiNode *node( currentRefInfo->m_node ); + if( RefInfo::MeshRef == currentRefInfo->m_type ) { + for( size_t i = 0; i < currentRefInfo->m_Names.size(); i++ ) { + const std::string &name(currentRefInfo->m_Names[ i ] ); + unsigned int meshIdx = m_mesh2refMap[ name ]; + node->mMeshes[ i ] = meshIdx; + } + } else if( RefInfo::MaterialRef == currentRefInfo->m_type ) { + // ToDo + } + } + } } //------------------------------------------------------------------------------------------------ From 05208a5014bfc029cab3c5b0834c94aa6c22c35a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 17 Mar 2015 19:43:41 +0100 Subject: [PATCH 32/39] try to fix build of win32 crosscompile. Signed-off-by: Kim Kulling --- contrib/openddlparser/include/openddlparser/OpenDDLCommon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index ff182432d..87209af86 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -29,7 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include -#ifdef _WIN32 +#ifdef _MSC_VER # define TAG_DLL_EXPORT __declspec(dllexport) # define TAG_DLL_IMPORT __declspec(dllimport ) # ifdef OPENDDLPARSER_BUILD From f15d62194b599cf5c925e6f34aeffb036f6f1052 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 18 Mar 2015 21:37:57 +0100 Subject: [PATCH 33/39] add nodestack to deal with node hierarchy. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 55 +++++++++++++++++++++++++++++++++++++++- code/OpenGEXImporter.h | 5 ++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 8f9a359ae..4172ae97b 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -176,6 +176,7 @@ OpenGEXImporter::OpenGEXImporter() , m_mesh2refMap() , m_ctx( NULL ) , m_currentNode( NULL ) +, m_nodeStack() , m_unresolvedRefStack() { // empty } @@ -214,6 +215,8 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce bool success( myParser.parse() ); if( success ) { m_ctx = myParser.getContext(); + pScene->mRootNode = new aiNode; + pScene->mRootNode->mName.Set( filename ); handleNodes( m_ctx->m_root, pScene ); } @@ -401,8 +404,12 @@ void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene //------------------------------------------------------------------------------------------------ void OpenGEXImporter::handleGeometryNode( DDLNode *node, aiScene *pScene ) { - m_currentNode = new aiNode; + aiNode *newNode = new aiNode; + pushNode( newNode, pScene ); + m_currentNode = newNode; handleNodes( node, pScene ); + + popNode(); } //------------------------------------------------------------------------------------------------ @@ -413,6 +420,10 @@ void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) { // store name to reference relation m_mesh2refMap[ node->getName() ] = idx; + + // todo: child nodes? + + handleNodes( node, pScene ); } //------------------------------------------------------------------------------------------------ @@ -444,6 +455,48 @@ void OpenGEXImporter::resolveReferences() { } } +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) { + ai_assert( NULL != pScene ); + + if( NULL != node ) { + if( m_nodeStack.empty() ) { + node->mParent = pScene->mRootNode; + } else { + aiNode *parent( m_nodeStack.back() ); + ai_assert( NULL != parent ); + node->mParent = parent; + } + m_nodeStack.push_back( node ); + } +} + +//------------------------------------------------------------------------------------------------ +aiNode *OpenGEXImporter::popNode() { + if( m_nodeStack.empty() ) { + return NULL; + } + + aiNode *node( top() ); + m_nodeStack.pop_back(); + + return node; +} + +//------------------------------------------------------------------------------------------------ +aiNode *OpenGEXImporter::top() const { + if( m_nodeStack.empty() ) { + return NULL; + } + + return m_nodeStack.back(); +} + +//------------------------------------------------------------------------------------------------ +void OpenGEXImporter::clearNodeStack() { + m_nodeStack.clear(); +} + //------------------------------------------------------------------------------------------------ } // Namespace OpenGEX diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 0bc2378b7..13154e06d 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -109,6 +109,10 @@ protected: void handleGeometryObject( ODDLParser::DDLNode *node, aiScene *pScene ); void handleMaterial( ODDLParser::DDLNode *node, aiScene *pScene ); void resolveReferences(); + void pushNode( aiNode *node, aiScene *pScene ); + aiNode *popNode(); + aiNode *top() const; + void clearNodeStack(); private: struct RefInfo { @@ -130,6 +134,7 @@ private: ODDLParser::Context *m_ctx; MetricInfo m_metrics[ MetricInfo::Max ]; aiNode *m_currentNode; + std::vector m_nodeStack; std::vector m_unresolvedRefStack; }; From b0753c38de6a51d8da87172faf38377bf73d9312 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 19 Mar 2015 11:37:11 +0100 Subject: [PATCH 34/39] fix code reading finding: rename definition. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 4 ++-- code/OpenGEXImporter.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 4172ae97b..c495773a9 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -37,7 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER +#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER #include "AssimpPCH.h" #include "OpenGEXImporter.h" @@ -502,4 +502,4 @@ void OpenGEXImporter::clearNodeStack() { } // Namespace OpenGEX } // Namespace Assimp -#endif // ASSIMP_BUILD_NO_OPEMGEX_IMPORTER +#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index 13154e06d..5355f0dea 100644 --- a/code/OpenGEXImporter.h +++ b/code/OpenGEXImporter.h @@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_OPENGEX_IMPORTER_H #define AI_OPENGEX_IMPORTER_H -#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER +#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER #include "BaseImporter.h" @@ -141,6 +141,6 @@ private: } // Namespace OpenGEX } // Namespace Assimp -#endif // ASSIMP_BUILD_NO_OPEMGEX_IMPORTER +#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER #endif // AI_OPENGEX_IMPORTER_H From 12efa1477720011b64e6ff7021d12e6b3958d468 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 19 Mar 2015 11:37:58 +0100 Subject: [PATCH 35/39] add openddl_parser directly to assimp. Signed-off-by: Kim Kulling --- CMakeLists.txt | 4 ---- code/CMakeLists.txt | 18 ++++++++++++++++++ tools/assimp_cmd/CMakeLists.txt | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 231166824..8a3a325be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,10 +156,6 @@ else(NOT ZLIB_FOUND) endif(NOT ZLIB_FOUND) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) -add_subdirectory( contrib/openddlparser ) -INCLUDE_DIRECTORIES( contrib/openddlparser/include ) -SET( OPENDDL_PARSER_LIBRARIES openddl_parser ) - # Search for unzip if (PKG_CONFIG_FOUND) PKG_CHECK_MODULES(UNZIP minizip) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 3286d4a1d..e14215838 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -640,6 +640,18 @@ SET( unzip_SRCS ) SOURCE_GROUP( unzip FILES ${unzip_SRCS}) +SET ( openddl_parser_SRCS + ../contrib/openddlparser/code/OpenDDLParser.cpp + ../contrib/openddlparser/code/DDLNode.cpp + ../contrib/openddlparser/code/Value.cpp + ../contrib/openddlparser/include/openddlparser/OpenDDLParser.h + ../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h + ../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h + ../contrib/openddlparser/include/openddlparser/DDLNode.h + ../contrib/openddlparser/include/openddlparser/Value.h +) +SOURCE_GROUP( openddl_parser FILES ${openddl_parser_SRCS}) + # VC2010 fixes if(MSVC10) option( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF ) @@ -719,6 +731,7 @@ SET( assimp_src ${unzip_compile_SRCS} ${Poly2Tri_SRCS} ${Clipper_SRCS} + ${openddl_parser_SRCS} # Necessary to show the headers in the project when using the VC++ generator: ${Boost_SRCS} @@ -730,6 +743,11 @@ SET( assimp_src # Moreover it's a drag to recompile assimp entirely each time a modification is made to one of the included header, which is definitely counter-productive.) AssimpPCH.cpp ) +add_definitions( -DOPENDDLPARSER_BUILD ) + +INCLUDE_DIRECTORIES( + ../contrib/openddlparser/include +) IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER) SET( assimp_src ${assimp_src} ${C4D_SRCS}) diff --git a/tools/assimp_cmd/CMakeLists.txt b/tools/assimp_cmd/CMakeLists.txt index 78b3139ee..6857a0ba2 100644 --- a/tools/assimp_cmd/CMakeLists.txt +++ b/tools/assimp_cmd/CMakeLists.txt @@ -28,7 +28,7 @@ IF( WIN32 ) MAIN_DEPENDENCY assimp) ENDIF( WIN32 ) -TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES} openddl_parser) +TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES} ) SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES OUTPUT_NAME assimp ) From 70aafa478d330543ccbe44dd9462d1ddc2fa2f84 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 19 Mar 2015 11:38:15 +0100 Subject: [PATCH 36/39] avoid copying of private struct. Signed-off-by: Kim Kulling --- code/OpenGEXImporter.cpp | 5 +++++ code/OpenGEXImporter.h | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index c495773a9..fcb15e587 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -170,6 +170,11 @@ OpenGEXImporter::RefInfo::RefInfo( aiNode *node, Type type, std::vector m_Names; RefInfo( aiNode *node, Type type, std::vector &names ); + ~RefInfo(); + + private: + RefInfo( const RefInfo & ); + RefInfo &operator = ( const RefInfo & ); }; std::vector m_meshCache; From f7e5f3ec6b345b0f13bc0170bc7ce7c4c9c34027 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 19 Mar 2015 12:07:16 +0100 Subject: [PATCH 37/39] assimp: fix build with latest version of openddl-parser lib. Signed-off-by: Kim Kulling --- contrib/openddlparser/code/OpenDDLParser.cpp | 10 +++++----- .../include/openddlparser/OpenDDLCommon.h | 11 +++-------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 99274f412..1050baeb4 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -81,7 +81,7 @@ static bool isIntegerType( Value::ValueType integerType ) { } static DDLNode *createDDLNode( Identifier *id, OpenDDLParser *parser ) { - if( nullptr == id || ddl_nullptr == parser ) { + if( ddl_nullptr == id || ddl_nullptr == parser ) { return ddl_nullptr; } @@ -132,7 +132,7 @@ OpenDDLParser::~OpenDDLParser() { } void OpenDDLParser::setLogCallback( logCallback callback ) { - if( nullptr != callback ) { + if( ddl_nullptr != callback ) { // install user-specific log callback m_logCallback = callback; } else { @@ -607,7 +607,7 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) { *integer = ddl_nullptr; - if( nullptr == in || in == end ) { + if( ddl_nullptr == in || in == end ) { return in; } @@ -705,7 +705,7 @@ char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData } static void createPropertyWithData( Identifier *id, Value *primData, Property **prop ) { - if( nullptr != primData ) { + if( ddl_nullptr != primData ) { ( *prop ) = new Property( id ); ( *prop )->m_primData = primData; } @@ -857,7 +857,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **da if( *in == '{' ) { in++; Value *current( ddl_nullptr ); - Reference *refs( nullptr ); + Reference *refs( ddl_nullptr ); DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); do { in = parseDataList( in, end, ¤t, &refs ); diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index 87209af86..40e54ea4b 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -74,7 +74,7 @@ enum NameType { }; struct Name { - NameType m_type; + NameType m_type; Identifier *m_id; Name( NameType type, Identifier *id ) @@ -85,8 +85,8 @@ struct Name { }; struct Reference { - size_t m_numRefs; - Name **m_referencedName; + size_t m_numRefs; + Name **m_referencedName; Reference() : m_numRefs( 0 ) @@ -166,10 +166,5 @@ struct BufferIt { END_ODDLPARSER_NS -#define ODDL_NO_COPYING( classname ) \ -private: \ - classname( const classname & ); \ - classname &operator = ( const classname & ); - #endif // OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC From 40369010c36ce8c2fb8c7f34df8c7e13c28e433c Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 19 Mar 2015 12:14:17 +0100 Subject: [PATCH 38/39] fix usage of c++11 type nullptr. Signed-off-by: Kim Kulling --- contrib/openddlparser/code/OpenDDLParser.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 1050baeb4..4b9313a42 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -218,7 +218,7 @@ static void dumpId( Identifier *id ) { } char *OpenDDLParser::parseHeader( char *in, char *end ) { - if( nullptr == in || in == end ) { + if( ddl_nullptr == in || in == end ) { return in; } @@ -259,7 +259,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { // store the node DDLNode *node( createDDLNode( id, this ) ); - if( nullptr != node ) { + if( ddl_nullptr != node ) { pushNode( node ); } else { std::cerr << "nullptr returned by creating DDLNode." << std::endl; @@ -282,7 +282,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { } char *OpenDDLParser::parseStructure( char *in, char *end ) { - if( nullptr == in || in == end ) { + if( ddl_nullptr == in || in == end ) { return in; } @@ -377,7 +377,7 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) { } void OpenDDLParser::pushNode( DDLNode *node ) { - if( nullptr == node ) { + if( ddl_nullptr == node ) { return; } @@ -405,7 +405,7 @@ DDLNode *OpenDDLParser::top() { } DDLNode *OpenDDLParser::getRoot() const { - if( nullptr == m_context ) { + if( ddl_nullptr == m_context ) { return ddl_nullptr; } @@ -766,7 +766,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { in = getNextToken( in, end ); Identifier *id( ddl_nullptr ); in = parseIdentifier( in, end, &id ); - if( nullptr != id ) { + if( ddl_nullptr != id ) { in = getNextToken( in, end ); if( *in == '=' ) { in++; From abe82a5d73e404d7ead988c87dc9460dc68a4620 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 19 Mar 2015 12:34:11 +0100 Subject: [PATCH 39/39] add missing include Signed-off-by: Kim Kulling --- contrib/openddlparser/code/OpenDDLParser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 4b9313a42..186323730 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #ifdef _WIN32 # include