Merge remote-tracking branch 'official/master' into contrib

Conflicts:
	code/ColladaParser.cpp
	include/assimp/config.h
pull/546/head
Léo Terziman 2015-03-27 09:55:21 +01:00
commit 60d58901a5
64 changed files with 13943 additions and 1487 deletions

6
.gitignore vendored
View File

@ -10,7 +10,7 @@ build
# Output
bin/
lib/
contrib/
# Generated
assimp.pc
@ -54,3 +54,7 @@ tools/assimp_view/assimp_viewer.vcxproj.user
# Unix editor backups
*~
test/gtest/src/gtest-stamp/gtest-gitinfo.txt
test/gtest/src/gtest-stamp/gtest-gitclone-lastrun.txt
Assimp.opensdf
contrib/zlib/CTestTestfile.cmake

View File

@ -1,7 +1,14 @@
before_install:
- sudo apt-get install cmake python3
- echo -e "#ifndef A_R_H_INC\n#define A_R_H_INC\n#define GitVersion ${TRAVIS_JOB_ID}\n#define GitBranch \"${TRAVIS_BRANCH}\"\n#endif // A_R_H_INC" > revision.h
branches:
only:
- master
env:
global:
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
matrix:
- LINUX=1 TRAVIS_NO_EXPORT=YES
- LINUX=1 TRAVIS_NO_EXPORT=NO
@ -11,6 +18,7 @@ env:
- WINDOWS=1 TRAVIS_NO_EXPORT=NO
- WINDOWS=1 TRAVIS_STATIC_BUILD=ON
- WINDOWS=1 TRAVIS_STATIC_BUILD=OFF
- ANDROID=1
language: cpp
@ -20,8 +28,10 @@ compiler:
install:
- if [ $WINDOWS ]; then travis_retry sudo apt-get install -q -y gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64; fi
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
script:
- if [ $ANDROID ]; then ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni ; fi
- cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD
- make
- sudo make install
@ -34,4 +44,3 @@ script:
- echo "=========================================================="
- echo "REGRESSION TEST FAILS (results/run_regression_suite_failures.csv)"
- cat ../results/run_regression_suite_failures.csv

View File

@ -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

View File

@ -151,3 +151,8 @@ Ogre Binary format support
- Filip Wasil, Tieto Poland Sp. z o.o.
Android JNI asset extraction support
- Richard Steffen
Contributed X File exporter
Contributed ExportProperties interface

View File

@ -144,7 +144,7 @@ namespace {
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
if(!outfile) {
@ -188,8 +188,8 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, c
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
WriteMeshes();
WriteMaterials();
WriteMeshes();
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);

View File

@ -754,7 +754,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
}
};
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
AssbinExport exporter;
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );

View File

@ -621,7 +621,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
} // end of namespace AssxmlExport
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
IOStream * out = pIOSystem->Open( pFile, "wt" );
if (!out) return;

View File

@ -118,6 +118,16 @@ namespace Blender {
#ifdef _MSC_VER
# pragma warning(disable:4351)
#endif
struct ObjectCompare {
bool operator() (const Object* left, const Object* right) const {
return strcmp(left->id.name, right->id.name) == -1;
}
};
// When keeping objects in sets, sort them by their name.
typedef std::set<const Object*, ObjectCompare> ObjectSet;
// --------------------------------------------------------------------
/** ConversionData acts as intermediate storage location for
* the various ConvertXXX routines in BlenderImporter.*/
@ -130,7 +140,13 @@ namespace Blender {
, db(db)
{}
std::set<const Object*> objects;
struct ObjectCompare {
bool operator() (const Object* left, const Object* right) const {
return strcmp(left->id.name, right->id.name) == -1;
}
};
ObjectSet objects;
TempArray <std::vector, aiMesh> meshes;
TempArray <std::vector, aiCamera> cameras;

View File

@ -559,24 +559,26 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
if (index == static_cast<unsigned int>( -1 )) {
// ok, we need to add a dedicated default material for some poor material-less meshes
// Setup a default material.
boost::shared_ptr<Material> p(new Material());
ai_assert(::strlen(AI_DEFAULT_MATERIAL_NAME) < sizeof(p->id.name)-2);
strcpy( p->id.name+2, AI_DEFAULT_MATERIAL_NAME );
// Note: MSVC11 does not zero-initialize Material here, although it should.
// Thus all relevant fields should be explicitly initialized. We cannot add
// a default constructor to Material since the DNA codegen does not support
// parsing it.
p->r = p->g = p->b = 0.6f;
p->specr = p->specg = p->specb = 0.6f;
p->ambr = p->ambg = p->ambb = 0.0f;
p->mirr = p->mirg = p->mirb = 0.0f;
p->emit = 0.f;
p->alpha = 0.f;
// XXX add more / or add default c'tor to Material
p->har = 0;
index = static_cast<unsigned int>( conv_data.materials_raw.size() );
conv_data.materials_raw.push_back(p);
LogInfo("Adding default material ...");
LogInfo("Adding default material");
}
mesh->mMaterialIndex = index;
}
@ -591,6 +593,7 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
aiMaterial* mout = new aiMaterial();
conv_data.materials->push_back(mout);
// For any new material field handled here, the default material above must be updated with an appropriate default value.
// set material name
aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA'
@ -1044,7 +1047,7 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform)
{
std::deque<const Object*> children;
for(std::set<const Object*>::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
for(ObjectSet::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
const Object* object = *it;
if (object->parent == obj) {
children.push_back(object);

View File

@ -120,9 +120,11 @@ public:
{
case aiOrigin_CUR:
cursor += pOffset;
break;
case aiOrigin_END:
cursor = file_size - pOffset;
break;
case aiOrigin_SET:
cursor = pOffset;

View File

@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the Cinema4D importer class.
*/
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
// no #ifdefing here, Cinema4D support is carried out in a branch of assimp
// where it is turned on in the CMake settings.
@ -639,3 +640,5 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
ai_assert((*it).second < mat_count);
return (*it).second;
}
#endif // ASSIMP_BUILD_NO_C4D_IMPORTER

View File

@ -265,8 +265,6 @@ SET( LWS_SRCS
)
SOURCE_GROUP( LWS FILES ${LWS_SRCS})
SET( MD2_SRCS
MD2FileData.h
MD2Loader.cpp
@ -360,6 +358,13 @@ SET( Ogre_SRCS
)
SOURCE_GROUP( Ogre FILES ${Ogre_SRCS})
SET( OpenGEX_SRCS
OpenGEXImporter.cpp
OpenGEXImporter.h
OpenGEXStructs.h
)
SOURCE_GROUP( OpenGEX FILES ${OpenGEX_SRCS})
SET( Ply_SRCS
PlyLoader.cpp
PlyLoader.h
@ -635,6 +640,17 @@ 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)
@ -690,6 +706,7 @@ SET( assimp_src
${OFFFormat_SRCS}
${Obj_SRCS}
${Ogre_SRCS}
${OpenGEX_SRCS}
${Ply_SRCS}
${Q3D_SRCS}
${Q3BSP_SRCS}
@ -714,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}
@ -725,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})
@ -735,7 +758,7 @@ ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
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)

View File

@ -59,7 +59,7 @@ namespace Assimp
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
std::string path = "";
std::string file = pFile;

View File

@ -1990,9 +1990,11 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
}
}
// small sanity check
if (primType != Prim_TriFans && primType != Prim_TriStrips)
ai_assert(actualPrimitives == numPrimitives)
#ifdef ASSIMP_BUILD_DEBUG
if (primType != Prim_TriFans && primType != Prim_TriStrips) {
ai_assert(actualPrimitives == numPrimitives);
}
#endif
// only when we're done reading all <p> tags (and thus know the final vertex count) can we commit the submesh
subgroup.mNumFaces = actualPrimitives;

View File

@ -72,16 +72,16 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
// ------------------------------------------------------------------------------------------------
// Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
// do not use const, because some exporter need to convert the scene temporary
void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
void ExportSceneXFile(const char*,IOSystem*, const aiScene*);
void ExportSceneObj(const char*,IOSystem*, const aiScene*);
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
void ExportScenePly(const char*,IOSystem*, const aiScene*);
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*);
void ExportScene3DS(const char*, IOSystem*, const aiScene*);
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*);
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*);
void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
// ------------------------------------------------------------------------------------------------
// global array of all export formats which Assimp supports in its current build
@ -91,7 +91,7 @@ Exporter::ExportFormatEntry gExporters[] =
Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
#endif
#ifndef ASSIMP_BUILD_NO_FXILE_EXPORTER
#ifndef ASSIMP_BUILD_NO_XFILE_EXPORTER
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
#endif
@ -226,7 +226,7 @@ bool Exporter :: IsDefaultIOHandler() const
// ------------------------------------------------------------------------------------------------
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int )
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int, const ExportProperties* pProperties)
{
if (pimpl->blob) {
delete pimpl->blob;
@ -282,7 +282,7 @@ bool IsVerboseFormat(const aiScene* pScene)
// ------------------------------------------------------------------------------------------------
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing )
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
{
ASSIMP_BEGIN_EXCEPTION_REGION();
@ -397,7 +397,8 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
proc.Execute(scenecopy.get());
}
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
}
catch (DeadlyExportError& err) {
pimpl->mError = err.what();
@ -492,4 +493,116 @@ void Exporter :: UnregisterExporter(const char* id)
}
}
ExportProperties :: ExportProperties() {}
ExportProperties::ExportProperties(const ExportProperties &other)
: mIntProperties(other.mIntProperties),
mFloatProperties(other.mFloatProperties),
mStringProperties(other.mStringProperties),
mMatrixProperties(other.mMatrixProperties)
{
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
void ExportProperties :: SetPropertyInteger(const char* szName, int iValue,
bool* bWasExisting /*= NULL*/)
{
SetGenericProperty<int>(mIntProperties, szName,iValue,bWasExisting);
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
void ExportProperties :: SetPropertyFloat(const char* szName, float iValue,
bool* bWasExisting /*= NULL*/)
{
SetGenericProperty<float>(mFloatProperties, szName,iValue,bWasExisting);
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
void ExportProperties :: SetPropertyString(const char* szName, const std::string& value,
bool* bWasExisting /*= NULL*/)
{
SetGenericProperty<std::string>(mStringProperties, szName,value,bWasExisting);
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
void ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value,
bool* bWasExisting /*= NULL*/)
{
SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value,bWasExisting);
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
int ExportProperties :: GetPropertyInteger(const char* szName,
int iErrorReturn /*= 0xffffffff*/) const
{
return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
float ExportProperties :: GetPropertyFloat(const char* szName,
float iErrorReturn /*= 10e10*/) const
{
return GetGenericProperty<float>(mFloatProperties,szName,iErrorReturn);
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
const std::string ExportProperties :: GetPropertyString(const char* szName,
const std::string& iErrorReturn /*= ""*/) const
{
return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName,
const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const
{
return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
bool ExportProperties :: HasPropertyInteger(const char* szName) const
{
return HasGenericProperty<int>(mIntProperties, szName);
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
bool ExportProperties :: HasPropertyBool(const char* szName) const
{
return HasGenericProperty<int>(mIntProperties, szName);
};
// ------------------------------------------------------------------------------------------------
// Has a configuration property
bool ExportProperties :: HasPropertyFloat(const char* szName) const
{
return HasGenericProperty<float>(mFloatProperties, szName);
};
// ------------------------------------------------------------------------------------------------
// Has a configuration property
bool ExportProperties :: HasPropertyString(const char* szName) const
{
return HasGenericProperty<std::string>(mStringProperties, szName);
};
// ------------------------------------------------------------------------------------------------
// Has a configuration property
bool ExportProperties :: HasPropertyMatrix(const char* szName) const
{
return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
};
#endif // !ASSIMP_BUILD_NO_EXPORT

View File

@ -108,5 +108,18 @@ inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
*bWasExisting = true;
}
// ------------------------------------------------------------------------------------------------
template <class T>
inline const bool HasGenericProperty(const std::map< unsigned int, T >& list,
const char* szName)
{
ai_assert(NULL != szName);
const uint32_t hash = SuperFastHash(szName);
typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
if (it == list.end()) return false;
return true;
}
#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED

View File

@ -648,10 +648,10 @@ void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
ai_assert(InRange(a) && InRange(b));
const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
out.verts.reserve( out.verts.size() + cnt );
out.verts.reserve( out.verts.size() + cnt + 1);
IfcFloat p = a, delta = (b-a)/cnt;
for(size_t i = 0; i < cnt; ++i, p += delta) {
for(size_t i = 0; i <= cnt; ++i, p += delta) {
out.verts.push_back(Eval(p));
}
}

View File

@ -677,10 +677,11 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
const STEP::DB::RefMap& refs = conv.db.GetRefs();
// skip over space and annotation nodes - usually, these have no meaning in Assimp's context
bool skipGeometry = false;
if(conv.settings.skipSpaceRepresentations) {
if(const IfcSpace* const space = el.ToPtr<IfcSpace>()) {
IFCImporter::LogDebug("skipping IfcSpace entity due to importer settings");
return NULL;
skipGeometry = true;
}
}
@ -850,8 +851,10 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
conv.apply_openings = &openings;
}
if (!skipGeometry) {
ProcessProductRepresentation(el,nd.get(),subnodes,conv);
conv.apply_openings = conv.collect_openings = NULL;
}
if (subnodes.size()) {
nd->mChildren = new aiNode*[subnodes.size()]();

View File

@ -236,7 +236,7 @@ IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const
struct CompareVector
{
bool operator () (const IfcVector3& a, const IfcVector3& b)
bool operator () (const IfcVector3& a, const IfcVector3& b) const
{
IfcVector3 d = a - b;
IfcFloat eps = 1e-6;

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team
Copyright (c) 2006-2015, assimp team
All rights reserved.
@ -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_OPENGEX_IMPORTER
# include "OpenGEXImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
# include "MS3DLoader.h"
#endif
@ -274,6 +277,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_OPENGEX_IMPORTER )
out.push_back( new OpenGEX::OpenGEXImporter() );
#endif
#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
out.push_back( new MS3DImporter());
#endif
@ -307,4 +313,4 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
#endif
}
}
} // namespace Assimp

View File

@ -51,7 +51,7 @@ namespace Assimp {
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
// invoke the exporter
ObjExporter exporter(pFile, pScene);

View File

@ -0,0 +1,691 @@
/*
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_OPENGEX_IMPORTER
#include "AssimpPCH.h"
#include "OpenGEXImporter.h"
#include "DefaultIOSystem.h"
#include <openddlparser/OpenDDLParser.h>
#include <vector>
static const aiImporterDesc desc = {
"Open Game Engine Exchange",
"",
"",
"",
aiImporterFlags_SupportTextFlavour,
0,
0,
0,
0,
"ogex"
};
namespace Grammar {
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( MetricType ) ) ) {
return MetricToken;
} else if( 0 == strncmp( NameType, tokenType, strlen( NameType ) ) ) {
return NameToken;
}
else if( 0 == strncmp( ObjectRefType, tokenType, strlen( ObjectRefType ) ) ) {
return ObjectRefToken;
}
else if( 0 == strncmp( MaterialRefType, tokenType, strlen( MaterialRefType ) ) ) {
return MaterialRefToken;
}
else if( 0 == strncmp( MetricKeyType, tokenType, strlen( MetricKeyType ) ) ) {
return MetricKeyToken;
}
else if( 0 == strncmp( GeometryNodeType, tokenType, strlen( GeometryNodeType ) ) ) {
return GeometryNodeToken;
}
else if( 0 == strncmp( GeometryObjectType, tokenType, strlen( GeometryObjectType ) ) ) {
return GeometryObjectToken;
}
else if( 0 == strncmp( TransformType, tokenType, strlen( TransformType ) ) ) {
return TransformToken;
}
else if( 0 == strncmp( MeshType, tokenType, strlen( MeshType ) ) ) {
return MeshToken;
}
else if( 0 == strncmp( VertexArrayType, tokenType, strlen( VertexArrayType ) ) ) {
return VertexArrayToken;
}
else if( 0 == strncmp( IndexArrayType, tokenType, strlen( IndexArrayType ) ) ) {
return IndexArrayToken;
}
else if( 0 == strncmp( MaterialType, tokenType, strlen( MaterialType ) ) ) {
return MaterialToken;
}
else if( 0 == strncmp( ColorType, tokenType, strlen( ColorType ) ) ) {
return ColorToken;
}
else if( 0 == strncmp( TextureType, tokenType, strlen( TextureType ) ) ) {
return TextureToken;
}
return NoneType;
}
} // Namespace Grammar
namespace Assimp {
namespace OpenGEX {
USE_ODDLPARSER_NS
//------------------------------------------------------------------------------------------------
OpenGEXImporter::RefInfo::RefInfo( aiNode *node, Type type, std::vector<std::string> &names )
: m_node( node )
, m_type( type )
, m_Names( names ) {
// empty
}
//------------------------------------------------------------------------------------------------
OpenGEXImporter::RefInfo::~RefInfo() {
// empty
}
//------------------------------------------------------------------------------------------------
OpenGEXImporter::OpenGEXImporter()
: m_meshCache()
, m_mesh2refMap()
, m_ctx( NULL )
, m_currentNode( NULL )
, m_currentMesh( NULL )
, m_nodeStack()
, m_unresolvedRefStack() {
// empty
}
//------------------------------------------------------------------------------------------------
OpenGEXImporter::~OpenGEXImporter() {
m_ctx = NULL;
}
//------------------------------------------------------------------------------------------------
bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const {
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 &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<char> buffer;
TextFileToBuffer( file, buffer );
OpenDDLParser myParser;
myParser.setBuffer( &buffer[ 0 ], buffer.size() );
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 );
}
resolveReferences();
}
//------------------------------------------------------------------------------------------------
const aiImporterDesc *OpenGEXImporter::GetInfo() const {
return &desc;
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::SetupProperties( const Importer *pImp ) {
if( NULL == pImp ) {
return;
}
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
if( NULL == node ) {
return;
}
DDLNode::DllNodeList childs = node->getChildNodeList();
for( DDLNode::DllNodeList::iterator it = childs.begin(); it != childs.end(); it++ ) {
Grammar::TokenType tokenType( Grammar::matchTokenType( ( *it )->getType().c_str() ) );
switch( tokenType ) {
case Grammar::MetricToken:
handleMetricNode( *it, pScene );
break;
case Grammar::NameToken:
handleNameNode( *it, pScene );
break;
case Grammar::ObjectRefToken:
handleObjectRefNode( *it, pScene );
break;
case Grammar::MaterialRefToken:
handleMaterialRefNode( *it, pScene );
break;
case Grammar::MetricKeyToken:
break;
case Grammar::GeometryNodeToken:
handleGeometryNode( *it, pScene );
break;
case Grammar::GeometryObjectToken:
handleGeometryObject( *it, pScene );
break;
case Grammar::TransformToken:
handleTransformNode( *it, pScene );
break;
case Grammar::MeshToken:
handleMeshNode( *it, pScene );
break;
case Grammar::VertexArrayToken:
handleVertexArrayNode( *it, pScene );
break;
case Grammar::IndexArrayToken:
handleIndexArrayNode( *it, pScene );
break;
case Grammar::MaterialToken:
handleMaterialNode( *it, pScene );
break;
case Grammar::ColorToken:
handleColorNode( *it, pScene );
break;
case Grammar::TextureToken:
handleTextureNode( *it, pScene );
break;
default:
break;
}
}
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) {
if( NULL == node || NULL == m_ctx ) {
return;
}
if( m_ctx->m_root != node->getParent() ) {
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 );
int type( Grammar::isValidMetricType( valName.c_str() ) );
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_intValue = 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." );
}
}
}
}
}
prop = prop->m_next;
}
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleNameNode( 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." );
return;
}
const std::string name( val->getString() );
m_currentNode->mName.Set( name.c_str() );
}
}
//------------------------------------------------------------------------------------------------
static void getRefNames( DDLNode *node, std::vector<std::string> &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 ) {
throw DeadlyImportError( "No parent node for name." );
return;
}
std::vector<std::string> 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<std::string> matRefNames;
getRefNames( node, matRefNames );
if( !matRefNames.empty() ) {
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MaterialRef, matRefNames ) );
}
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleGeometryNode( DDLNode *node, aiScene *pScene ) {
aiNode *newNode = new aiNode;
pushNode( newNode, pScene );
m_currentNode = newNode;
handleNodes( node, pScene );
popNode();
}
//------------------------------------------------------------------------------------------------
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;
// todo: child nodes?
handleNodes( node, pScene );
}
//------------------------------------------------------------------------------------------------
static void setMatrix( aiNode *node, DataArrayList *transformData ) {
ai_assert( NULL != node );
ai_assert( NULL != transformData );
float m[ 16 ];
size_t i( 1 );
Value *next( transformData->m_dataList->m_next );
m[ 0 ] = transformData->m_dataList->getFloat();
while( next != NULL ) {
m[ i ] = next->getFloat();
next = next->m_next;
i++;
}
node->mTransformation.a1 = m[ 0 ];
node->mTransformation.a2 = m[ 1 ];
node->mTransformation.a3 = m[ 2 ];
node->mTransformation.a4 = m[ 3 ];
node->mTransformation.b1 = m[ 4 ];
node->mTransformation.b2 = m[ 5 ];
node->mTransformation.b3 = m[ 6 ];
node->mTransformation.b4 = m[ 7 ];
node->mTransformation.c1 = m[ 8 ];
node->mTransformation.c2 = m[ 9 ];
node->mTransformation.c3 = m[ 10 ];
node->mTransformation.c4 = m[ 11 ];
node->mTransformation.d1 = m[ 12 ];
node->mTransformation.d2 = m[ 13 ];
node->mTransformation.d3 = m[ 14 ];
node->mTransformation.d4 = m[ 15 ];
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
if( NULL == m_currentNode ) {
throw DeadlyImportError( "No parent node for name." );
return;
}
DataArrayList *transformData( node->getDataArrayList() );
if( NULL != transformData ) {
if( transformData->m_numItems != 16 ) {
throw DeadlyImportError( "Invalid number of data for transform matrix." );
return;
}
setMatrix( m_currentNode, transformData );
}
}
//------------------------------------------------------------------------------------------------
static void propId2StdString( Property *prop, std::string &name, std::string &key ) {
name = key = "";
if( NULL == prop ) {
return;
}
if( NULL != prop->m_id ) {
name = prop->m_id->m_buffer;
if( Value::ddl_string == prop->m_primData->m_type ) {
key = prop->m_primData->getString();
}
}
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
Property *prop = node->getProperties();
m_currentMesh = new aiMesh;
m_meshCache.push_back( m_currentMesh );
if( NULL != prop ) {
std::string propName, propKey;
propId2StdString( prop, propName, propKey );
if( "triangles" == propName ) {
m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
}
}
handleNodes( node, pScene );
}
//------------------------------------------------------------------------------------------------
enum MeshAttribute {
None,
Position,
Normal,
TexCoord
};
//------------------------------------------------------------------------------------------------
static MeshAttribute getAttributeByName( const char *attribName ) {
ai_assert( NULL != attribName );
if( 0 == strncmp( "position", attribName, strlen( "position" ) ) ) {
return Position;
} else if( 0 == strncmp( "normal", attribName, strlen( "normal" ) ) ) {
return Normal;
} else if( 0 == strncmp( "texcoord", attribName, strlen( "texcoord" ) ) ) {
return TexCoord;
}
return None;
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
if( NULL == node ) {
throw DeadlyImportError( "No parent node for name." );
return;
}
Property *prop( node->getProperties() );
if( NULL != prop ) {
std::string propName, propKey;
propId2StdString( prop, propName, propKey );
MeshAttribute attribType( getAttributeByName( propName.c_str() ) );
if( None == attribType ) {
return;
}
DataArrayList *vaList = node->getDataArrayList();
if( NULL == vaList ) {
return;
}
if( Position == attribType ) {
aiVector3D *pos = new aiVector3D[ vaList->m_numItems ];
Value *next( vaList->m_dataList );
for( size_t i = 0; i < vaList->m_numItems; i++ ) {
}
} else if( Normal == attribType ) {
aiVector3D *normal = new aiVector3D[ vaList->m_numItems ];
} else if( TexCoord == attribType ) {
aiVector3D *tex = new aiVector3D[ vaList->m_numItems ];
}
}
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::resolveReferences() {
if( m_unresolvedRefStack.empty() ) {
return;
}
RefInfo *currentRefInfo( NULL );
for( std::vector<RefInfo*>::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
} else {
throw DeadlyImportError( "Unknown reference info to resolve." );
}
}
}
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
}
//------------------------------------------------------------------------------------------------
void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
}
//------------------------------------------------------------------------------------------------
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
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER

View File

@ -0,0 +1,158 @@
/*
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_OPENGEX_IMPORTER_H
#define AI_OPENGEX_IMPORTER_H
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
#include "BaseImporter.h"
#include <vector>
namespace ODDLParser {
class DDLNode;
struct Context;
}
namespace Assimp {
namespace OpenGEX {
struct MetricInfo {
enum Type {
Distance = 0,
Angle,
Time,
Up,
Max
};
std::string m_stringValue;
float m_floatValue;
int m_intValue;
MetricInfo()
: m_stringValue( "" )
, m_floatValue( 0.0f )
, m_intValue( -1 ) {
// empty
}
};
/** @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 );
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 handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene );
void handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene );
void handleGeometryObject( ODDLParser::DDLNode *node, aiScene *pScene );
void handleTransformNode( ODDLParser::DDLNode *node, aiScene *pScene );
void handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene );
void handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene );
void handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene );
void handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pScene );
void handleColorNode( ODDLParser::DDLNode *node, aiScene *pScene );
void handleTextureNode( ODDLParser::DDLNode *node, aiScene *pScene );
void resolveReferences();
void pushNode( aiNode *node, aiScene *pScene );
aiNode *popNode();
aiNode *top() const;
void clearNodeStack();
private:
struct RefInfo {
enum Type {
MeshRef,
MaterialRef
};
aiNode *m_node;
Type m_type;
std::vector<std::string> m_Names;
RefInfo( aiNode *node, Type type, std::vector<std::string> &names );
~RefInfo();
private:
RefInfo( const RefInfo & );
RefInfo &operator = ( const RefInfo & );
};
std::vector<aiMesh*> m_meshCache;
std::map<std::string, size_t> m_mesh2refMap;
ODDLParser::Context *m_ctx;
MetricInfo m_metrics[ MetricInfo::Max ];
aiNode *m_currentNode;
aiMesh *m_currentMesh;
std::vector<aiNode*> m_nodeStack;
std::vector<RefInfo*> m_unresolvedRefStack;
};
} // Namespace OpenGEX
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER
#endif // AI_OPENGEX_IMPORTER_H

View File

@ -0,0 +1,265 @@
/*
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 <string>
#include <map>
namespace Assimp {
namespace OpenGEX {
struct Skin;
struct Object;
struct LightObject;
struct CameraObject;
struct Material;
struct BoneNode;
struct BoneCountArray;
struct BoneIndexArray;
struct BoneWeightArray;
struct Metric {
float m_distance;
float m_angle;
float m_time;
float m_up;
};
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<std::string, Mesh*> 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

View File

@ -50,7 +50,7 @@ namespace Assimp {
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
// invoke the exporter
PlyExporter exporter(pFile, pScene);
@ -64,7 +64,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
}
void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
// invoke the exporter
PlyExporter exporter(pFile, pScene, true);

View File

@ -64,6 +64,25 @@ static const aiImporterDesc desc = {
"ply"
};
// ------------------------------------------------------------------------------------------------
// Internal stuff
namespace
{
// ------------------------------------------------------------------------------------------------
// Checks that property index is within range
template <class T>
const T &GetProperty(const std::vector<T> &props, int idx)
{
if( static_cast< size_t >( idx ) >= props.size() ) {
throw DeadlyImportError( "Invalid .ply file: Property index is out of range." );
}
return props[idx];
}
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
PLYImporter::PLYImporter()
@ -431,13 +450,13 @@ void PLYImporter::LoadTextureCoordinates(std::vector<aiVector2D>* pvOut)
if (0xFFFFFFFF != aiPositions[0])
{
vOut.x = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]);
GetProperty((*i).alProperties, aiPositions[0]).avList.front(),aiTypes[0]);
}
if (0xFFFFFFFF != aiPositions[1])
{
vOut.y = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]);
GetProperty((*i).alProperties, aiPositions[1]).avList.front(),aiTypes[1]);
}
// and add them to our nice list
pvOut->push_back(vOut);
@ -541,19 +560,19 @@ void PLYImporter::LoadVertices(std::vector<aiVector3D>* pvOut, bool p_bNormals)
if (0xFFFFFFFF != aiPositions[0])
{
vOut.x = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[0]].avList.front(),aiTypes[0]);
GetProperty((*i).alProperties, aiPositions[0]).avList.front(),aiTypes[0]);
}
if (0xFFFFFFFF != aiPositions[1])
{
vOut.y = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[1]].avList.front(),aiTypes[1]);
GetProperty((*i).alProperties, aiPositions[1]).avList.front(),aiTypes[1]);
}
if (0xFFFFFFFF != aiPositions[2])
{
vOut.z = PLY::PropertyInstance::ConvertTo<float>(
(*i).alProperties[aiPositions[2]].avList.front(),aiTypes[2]);
GetProperty((*i).alProperties, aiPositions[2]).avList.front(),aiTypes[2]);
}
// and add them to our nice list
@ -659,28 +678,28 @@ void PLYImporter::LoadVertexColor(std::vector<aiColor4D>* pvOut)
if (0xFFFFFFFF != aiPositions[0])
{
vOut.r = NormalizeColorValue((*i).alProperties[
aiPositions[0]].avList.front(),aiTypes[0]);
vOut.r = NormalizeColorValue(GetProperty((*i).alProperties,
aiPositions[0]).avList.front(),aiTypes[0]);
}
if (0xFFFFFFFF != aiPositions[1])
{
vOut.g = NormalizeColorValue((*i).alProperties[
aiPositions[1]].avList.front(),aiTypes[1]);
vOut.g = NormalizeColorValue(GetProperty((*i).alProperties,
aiPositions[1]).avList.front(),aiTypes[1]);
}
if (0xFFFFFFFF != aiPositions[2])
{
vOut.b = NormalizeColorValue((*i).alProperties[
aiPositions[2]].avList.front(),aiTypes[2]);
vOut.b = NormalizeColorValue(GetProperty((*i).alProperties,
aiPositions[2]).avList.front(),aiTypes[2]);
}
// assume 1.0 for the alpha channel ifit is not set
if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0f;
else
{
vOut.a = NormalizeColorValue((*i).alProperties[
aiPositions[3]].avList.front(),aiTypes[3]);
vOut.a = NormalizeColorValue(GetProperty((*i).alProperties,
aiPositions[3]).avList.front(),aiTypes[3]);
}
// and add them to our nice list
@ -773,11 +792,11 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
// parse the list of vertex indices
if (0xFFFFFFFF != iProperty)
{
const unsigned int iNum = (unsigned int)(*i).alProperties[iProperty].avList.size();
const unsigned int iNum = (unsigned int)GetProperty((*i).alProperties, iProperty).avList.size();
sFace.mIndices.resize(iNum);
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
(*i).alProperties[iProperty].avList.begin();
GetProperty((*i).alProperties, iProperty).avList.begin();
for (unsigned int a = 0; a < iNum;++a,++p)
{
@ -789,7 +808,7 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
if (0xFFFFFFFF != iMaterialIndex)
{
sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo<unsigned int>(
(*i).alProperties[iMaterialIndex].avList.front(),eType2);
GetProperty((*i).alProperties, iMaterialIndex).avList.front(),eType2);
}
pvOut->push_back(sFace);
}
@ -800,7 +819,7 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
// a value of -1 indicates a restart of the strip
bool flip = false;
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = (*i).alProperties[iProperty].avList;
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty((*i).alProperties, iProperty).avList;
pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
int aiTable[2] = {-1,-1};
@ -851,30 +870,30 @@ void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance>& avL
if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
else
{
clrOut->r = NormalizeColorValue(avList[
aiPositions[0]].avList.front(),aiTypes[0]);
clrOut->r = NormalizeColorValue(GetProperty(avList,
aiPositions[0]).avList.front(),aiTypes[0]);
}
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
else
{
clrOut->g = NormalizeColorValue(avList[
aiPositions[1]].avList.front(),aiTypes[1]);
clrOut->g = NormalizeColorValue(GetProperty(avList,
aiPositions[1]).avList.front(),aiTypes[1]);
}
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
else
{
clrOut->b = NormalizeColorValue(avList[
aiPositions[2]].avList.front(),aiTypes[2]);
clrOut->b = NormalizeColorValue(GetProperty(avList,
aiPositions[2]).avList.front(),aiTypes[2]);
}
// assume 1.0 for the alpha channel ifit is not set
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
else
{
clrOut->a = NormalizeColorValue(avList[
aiPositions[3]].avList.front(),aiTypes[3]);
clrOut->a = NormalizeColorValue(GetProperty(avList,
aiPositions[3]).avList.front(),aiTypes[3]);
}
}
@ -1025,7 +1044,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
// handle phong power and shading mode
int iMode;
if (0xFFFFFFFF != iPhong) {
float fSpec = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),ePhong);
float fSpec = PLY::PropertyInstance::ConvertTo<float>(GetProperty((*i).alProperties, iPhong).avList.front(),ePhong);
// if shininess is 0 (and the pow() calculation would therefore always
// become 1, not depending on the angle), use gouraud lighting
@ -1043,7 +1062,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut)
// handle opacity
if (0xFFFFFFFF != iOpacity) {
float fOpacity = PLY::PropertyInstance::ConvertTo<float>((*i).alProperties[iPhong].avList.front(),eOpacity);
float fOpacity = PLY::PropertyInstance::ConvertTo<float>(GetProperty((*i).alProperties, iPhong).avList.front(),eOpacity);
pcHelper->AddProperty<float>(&fOpacity, 1, AI_MATKEY_OPACITY);
}

View File

@ -50,7 +50,7 @@ namespace Assimp {
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
// invoke the exporter
STLExporter exporter(pFile, pScene);
@ -63,7 +63,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
}
void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
// invoke the exporter
STLExporter exporter(pFile, pScene, true);

View File

@ -59,7 +59,7 @@ namespace Assimp
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{
std::string path = "";
std::string file = pFile;
@ -78,13 +78,19 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
}
}
// create/copy Properties
ExportProperties props(*pProperties);
// set standard properties if not set
if (!props.HasPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT)) props.SetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT, false);
// invoke the exporter
XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file);
XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
// we're still here - export successfully completed. Write result to the given IOSYstem
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) {
throw DeadlyExportError("could not open output .dae file: " + std::string(pFile));
throw DeadlyExportError("could not open output .x file: " + std::string(pFile));
}
// XXX maybe use a small wrapper around IOStream that behaves like std::stringstream in order to avoid the extra copy.
@ -96,7 +102,7 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
// ------------------------------------------------------------------------------------------------
// Constructor for a specific scene to export
XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file)
XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties) : mIOSystem(pIOSystem), mPath(path), mFile(file), mProperties(pProperties)
{
// make sure that all formatting happens using the standard, C locale and not the user's current locale
mOutput.imbue( std::locale("C") );
@ -126,7 +132,7 @@ void XFileExporter::WriteFile()
{
// note, that all realnumber values must be comma separated in x files
mOutput.setf(std::ios::fixed);
mOutput.precision(6); // precission for float
mOutput.precision(16); // precission for double
// entry of writing the file
WriteHeader();
@ -148,6 +154,9 @@ void XFileExporter::WriteFile()
// Writes the asset header
void XFileExporter::WriteHeader()
{
if (mProperties->GetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT) == true)
mOutput << startstr << "xof 0303txt 0064" << endstr;
else
mOutput << startstr << "xof 0303txt 0032" << endstr;
mOutput << endstr;
mOutput << startstr << "template Frame {" << endstr;
@ -298,7 +307,7 @@ void XFileExporter::WriteNode( aiNode* pNode)
ss << "Node_" << pNode;
pNode->mName.Set(ss.str());
}
mOutput << startstr << "Frame " << pNode->mName.C_Str() << " {" << endstr;
mOutput << startstr << "Frame " << toXFileString(pNode->mName) << " {" << endstr;
PushTag();
@ -318,9 +327,9 @@ void XFileExporter::WriteNode( aiNode* pNode)
mOutput << startstr << "}" << endstr << endstr;
}
void XFileExporter::WriteMesh(const aiMesh* mesh)
void XFileExporter::WriteMesh(aiMesh* mesh)
{
mOutput << startstr << "Mesh " << mesh->mName.C_Str() << "_mShape" << " {" << endstr;
mOutput << startstr << "Mesh " << toXFileString(mesh->mName) << "_mShape" << " {" << endstr;
PushTag();
@ -496,6 +505,16 @@ void XFileExporter::WriteMesh(const aiMesh* mesh)
}
std::string XFileExporter::toXFileString(aiString &name)
{
std::string str = std::string(name.C_Str());
std::replace(str.begin(), str.end(), '<', '_');
std::replace(str.begin(), str.end(), '>', '_');
std::replace(str.begin(), str.end(), '{', '_');
std::replace(str.begin(), str.end(), '}', '_');
std::replace(str.begin(), str.end(), '$', '_');
return str;
}
void XFileExporter::writePath(aiString path)
{

View File

@ -61,7 +61,7 @@ class XFileExporter
{
public:
/// Constructor for a specific scene to export
XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties);
/// Destructor
virtual ~XFileExporter();
@ -80,7 +80,7 @@ protected:
void WriteNode( aiNode* pNode );
/// write a mesh entry of the scene
void WriteMesh(const aiMesh* mesh);
void WriteMesh( aiMesh* mesh);
/// Enters a new xml element, which increases the indentation
void PushTag() { startstr.append( " "); }
@ -94,6 +94,12 @@ public:
protected:
/// normalize the name to be accepted by xfile readers
std::string toXFileString(aiString &name);
/// hold the properties pointer
const ExportProperties* mProperties;
/// write a path
void writePath(aiString path);

View File

@ -0,0 +1,64 @@
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( -DOPENDDL_NO_USE_CPP11 )
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}
)

View File

@ -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
> <Repo-folder>/include
to your include-path and the
> <Repo-folder>/lib
to your lib-folder. Link the openddl.lib to your application.
Here is a small example how to use the lib:
```cpp
#include <iostream>
#include <cassert>
#include <openddlparser/OpenDDLParser.h>
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; i<childs.size(); i++ ) {
DDLNode *child = childs[ i ];
Property *prop = child->getProperty(); // 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.

View File

@ -0,0 +1,184 @@
/*-----------------------------------------------------------------------------------------------
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 <openddlparser/DDLNode.h>
#include <openddlparser/OpenDDLParser.h>
#include <algorithm>
BEGIN_ODDLPARSER_NS
DDLNode::DllNodeList DDLNode::s_allocatedNodes;
template<class T>
inline
static void releaseDataType( T *ptr ) {
if( ddl_nullptr == ptr ) {
return;
}
T *current( ddl_nullptr );
while( ptr ) {
current = ptr;
ptr = ptr->m_next;
delete current;
}
}
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 )
, m_parent( parent )
, m_children()
, m_properties( ddl_nullptr )
, m_value( ddl_nullptr )
, m_dtArrayList( ddl_nullptr )
, m_references( ddl_nullptr )
, m_idx( idx ) {
if( m_parent ) {
m_parent->m_children.push_back( this );
}
}
DDLNode::~DDLNode() {
releaseDataType<Property>( m_properties );
releaseDataType<Value>( m_value );
releaseReferencedNames( m_references );
delete m_dtArrayList;
m_dtArrayList = ddl_nullptr;
if( s_allocatedNodes[ m_idx ] == this ) {
s_allocatedNodes[ m_idx ] = ddl_nullptr;
}
}
void DDLNode::attachParent( DDLNode *parent ) {
if( m_parent == parent ) {
return;
}
m_parent = parent;
if( ddl_nullptr != m_parent ) {
m_parent->m_children.push_back( this );
}
}
void DDLNode::detachParent() {
if( m_parent ) {
std::vector<DDLNode*>::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 = ddl_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 *prop ) {
m_properties = prop;
}
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;
}
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 );
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

View File

@ -0,0 +1,900 @@
/*-----------------------------------------------------------------------------------------------
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 <openddlparser/OpenDDLParser.h>
#include <cassert>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <math.h>
#ifdef _WIN32
# include <windows.h>
#endif // _WIN32
#define DEBUG_HEADER_NAME
BEGIN_ODDLPARSER_NS
static const char *Version = "0.1.0";
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 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() );
}
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, OpenDDLParser *parser ) {
if( ddl_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 );
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_buffer()
, m_stack()
, m_context( ddl_nullptr ) {
// empty
}
OpenDDLParser::OpenDDLParser( char *buffer, size_t len )
: m_logCallback( &logMessage )
, m_buffer()
, m_context( ddl_nullptr ) {
if( 0 != len ) {
setBuffer( buffer, len );
}
}
OpenDDLParser::~OpenDDLParser() {
clear();
}
void OpenDDLParser::setLogCallback( logCallback callback ) {
if( ddl_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 ) {
clear();
if( 0 == len ) {
return;
}
m_buffer.resize( len );
::memcpy(&m_buffer[ 0 ], buffer, len );
}
void OpenDDLParser::setBuffer( const std::vector<char> &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_buffer.size();
}
void OpenDDLParser::clear() {
m_buffer.resize( 0 );
if( m_context ) {
m_context->m_root = ddl_nullptr;
}
DDLNode::releaseNodes();
}
bool OpenDDLParser::parse() {
if( m_buffer.empty() ) {
return false;
}
normalizeBuffer( m_buffer );
std::cout << &m_buffer[0] << std::endl;
m_context = new Context;
m_context->m_root = DDLNode::create( "root", "", ddl_nullptr );
pushNode( m_context->m_root );
// do the main parsing
char *current( &m_buffer[ 0 ] );
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;
}
char *OpenDDLParser::parseNextNode( char *in, char *end ) {
in = parseHeader( in, end );
in = parseStructure( in, 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( ddl_nullptr == in || in == end ) {
return in;
}
Identifier *id( ddl_nullptr );
in = OpenDDLParser::parseIdentifier( in, end, &id );
#ifdef DEBUG_HEADER_NAME
dumpId( id );
#endif // DEBUG_HEADER_NAME
in = lookForNextToken( in, end );
Property *first( ddl_nullptr );
if( ddl_nullptr != id ) {
if( *in == '(' ) {
in++;
Property *prop( ddl_nullptr ), *prev( ddl_nullptr );
while( *in != ')' && in != end ) {
in = OpenDDLParser::parseProperty( in, end, &prop );
in = lookForNextToken( in, end );
if( *in != ',' && *in != ')' ) {
logInvalidTokenError( in, ")", m_logCallback );
return in;
}
if( ddl_nullptr != prop && *in != ',' ) {
if( ddl_nullptr == first ) {
first = prop;
}
if( ddl_nullptr != prev ) {
prev->m_next = prop;
}
prev = prop;
}
}
in++;
}
// store the node
DDLNode *node( createDDLNode( id, this ) );
if( ddl_nullptr != node ) {
pushNode( node );
} else {
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 ) {
const std::string nodeName( name->m_id->m_buffer );
node->setName( nodeName );
}
}
return in;
}
char *OpenDDLParser::parseStructure( char *in, char *end ) {
if( ddl_nullptr == in || in == end ) {
return in;
}
bool error( false );
in = lookForNextToken( in, end );
if( *in == '{' ) {
// loop over all children ( data and nodes )
do {
in = parseStructureBody( in, end, error );
} while ( *in != '}' );
in++;
} else {
in++;
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
error = true;
return in;
}
in = lookForNextToken( in, end );
// pop node from stack after successful parsing
if( !error ) {
popNode();
}
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 = lookForNextToken( in, end );
Value::ValueType type( Value::ddl_none );
size_t arrayLen( 0 );
in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen );
if( Value::ddl_none != type ) {
// parse a primitive data type
in = lookForNextToken( in, end );
if( *in == '{' ) {
Reference *refs( ddl_nullptr );
DataArrayList *dtArrayList( ddl_nullptr );
Value *values( ddl_nullptr );
if( 1 == arrayLen ) {
size_t numRefs( 0 ), numValues( 0 );
in = parseDataList( in, end, &values, numValues, &refs, numRefs );
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 = lookForNextToken( in, end );
if( *in != '}' ) {
logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback );
} else {
//in++;
}
} else {
// parse a complex data type
in = parseNextNode( in, end );
}
return in;
}
void OpenDDLParser::pushNode( DDLNode *node ) {
if( ddl_nullptr == node ) {
return;
}
m_stack.push_back( node );
}
DDLNode *OpenDDLParser::popNode() {
if( m_stack.empty() ) {
return ddl_nullptr;
}
DDLNode *topNode( top() );
m_stack.pop_back();
return topNode;
}
DDLNode *OpenDDLParser::top() {
if( m_stack.empty() ) {
return ddl_nullptr;
}
DDLNode *top( m_stack.back() );
return top;
}
DDLNode *OpenDDLParser::getRoot() const {
if( ddl_nullptr == m_context ) {
return ddl_nullptr;
}
return m_context->m_root;
}
Context *OpenDDLParser::getContext() const {
return m_context;
}
void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
if( buffer.empty() ) {
return;
}
std::vector<char> newBuffer;
const size_t len( buffer.size() );
char *end( &buffer[ len-1 ] + 1 );
for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
char *c( &buffer[readIdx] );
// check for a comment
if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
newBuffer.push_back( buffer[ readIdx ] );
} else {
if( isComment<char>( c, end ) ) {
readIdx++;
// skip the comment and the rest of the line
while( !isEndofLine( buffer[ readIdx ] ) ) {
readIdx++;
}
}
}
}
buffer = newBuffer;
}
char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
*name = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
// ignore blanks
in = lookForNextToken( in, end );
if( *in != '$' && *in != '%' ) {
return in;
}
NameType ntype( GlobalName );
if( *in == '%' ) {
ntype = LocalName;
}
Name *currentName( ddl_nullptr );
Identifier *id( ddl_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 = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
// ignore blanks
in = lookForNextToken( in, end );
// staring with a number is forbidden
if( isNumeric<const char>( *in ) ) {
return in;
}
// get size of id
size_t idLen( 0 );
char *start( in );
while( !isSeparator( *in ) && !isNewLine( *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( ddl_nullptr == in || in == end ) {
return in;
}
size_t prim_len( 0 );
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
type = ( Value::ValueType ) i;
break;
}
}
if( Value::ddl_none == type ) {
in = lookForNextToken( in, end );
return in;
} else {
in += prim_len;
}
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<Name*> &names ) {
if( ddl_nullptr == in || in == end ) {
return in;
}
Name *nextName( ddl_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 = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
in = lookForNextToken( in, end );
char *start( in );
size_t len( 0 );
while( !isSeparator( *in ) && in != end ) {
in++;
len++;
}
len++;
int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
if( 0 != res ) {
res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
if( 0 != res ) {
*boolean = ddl_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 = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
if( !isIntegerType( integerType ) ) {
return in;
}
in = lookForNextToken( 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 = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
in = lookForNextToken( 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 = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
in = lookForNextToken( 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 );
::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( ddl_nullptr != primData ) {
( *prop ) = new Property( id );
( *prop )->m_primData = primData;
}
}
char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
*data = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
in = lookForNextToken( 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<int>( 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 = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
in = lookForNextToken( in, end );
Identifier *id( ddl_nullptr );
in = parseIdentifier( in, end, &id );
if( ddl_nullptr != id ) {
in = lookForNextToken( in, end );
if( *in == '=' ) {
in++;
in = getNextToken( in, end );
Value *primData( ddl_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<Name*> 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, size_t &numValues, Reference **refs, size_t &numRefs ) {
*data = ddl_nullptr;
numValues = numRefs = 0;
if( ddl_nullptr == in || in == end ) {
return in;
}
in = lookForNextToken( in, end );
if( *in == '{' ) {
in++;
Value *current( ddl_nullptr ), *prev( ddl_nullptr );
while( '}' != *in ) {
current = ddl_nullptr;
in = lookForNextToken( in, end );
if( isInteger( in, end ) ) {
in = parseIntegerLiteral( in, end, &current );
} else if( isFloat( in, end ) ) {
in = parseFloatingLiteral( in, end, &current );
} else if( isStringLiteral( *in ) ) {
in = parseStringLiteral( in, end, &current );
} else if( isHexLiteral( in, end ) ) {
in = parseHexaLiteral( in, end, &current );
} else { // reference data
std::vector<Name*> names;
in = parseReference( in, end, names );
if( !names.empty() ) {
Reference *ref = new Reference( names.size(), &names[ 0 ] );
*refs = ref;
numRefs = names.size();
}
}
if( ddl_nullptr != current ) {
if( ddl_nullptr == *data ) {
*data = current;
prev = current;
} else {
prev->setNext( current );
prev = current;
}
numValues++;
}
in = getNextSeparator( in, end );
if( ',' != *in && '}' != *in && !isSpace( *in ) ) {
break;
}
}
in++;
}
return in;
}
char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) {
*dataList = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
}
in = lookForNextToken( in, end );
if( *in == Grammar::OpenBracketToken[ 0 ] ) {
in++;
Value *current( ddl_nullptr );
Reference *refs( ddl_nullptr );
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
do {
size_t numRefs( 0 ), numValues( 0 );
in = parseDataList( in, end, &current, numValues, &refs, numRefs );
if( ddl_nullptr != current ) {
if( ddl_nullptr == prev ) {
*dataList = new DataArrayList;
( *dataList )->m_dataList = current;
( *dataList )->m_numItems = numValues;
prev = *dataList;
} else {
currentDataList = new DataArrayList;
if( ddl_nullptr != prev ) {
prev->m_next = currentDataList;
prev = currentDataList;
}
}
}
} while( ',' == *in && in != end );
in = lookForNextToken( in, end );
in++;
}
return in;
}
const char *OpenDDLParser::getVersion() {
return Version;
}
END_ODDLPARSER_NS

View File

@ -0,0 +1,256 @@
/*-----------------------------------------------------------------------------------------------
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 <openddlparser/Value.h>
#include <iostream>
#include <cassert>
BEGIN_ODDLPARSER_NS
Value::Value()
: m_type( ddl_none )
, m_size( 0 )
, m_data( ddl_nullptr )
, m_next( ddl_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::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:
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 ddl_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 ) {
size_t len1( len );
if( Value::ddl_string == type ) {
len1++;
}
data->m_size *= len1;
data->m_data = new unsigned char[ data->m_size ];
}
return data;
}
void ValueAllocator::releasePrimData( Value **data ) {
if( !data ) {
return;
}
delete *data;
*data = ddl_nullptr;
}
END_ODDLPARSER_NS

View File

@ -0,0 +1,90 @@
/*-----------------------------------------------------------------------------------------------
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 <openddlparser/OpenDDLCommon.h>
#include <vector>
#include <string>
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<DDLNode*> 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 *prop );
Property *getProperties() const;
void setValue( Value *val );
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:
DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_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<DDLNode*> m_children;
Property *m_properties;
Value *m_value;
DataArrayList *m_dtArrayList;
Reference *m_references;
size_t m_idx;
static DllNodeList s_allocatedNodes;
};
END_ODDLPARSER_NS
#endif // OPENDDLPARSER_DDLNODE_H_INC

View File

@ -0,0 +1,170 @@
/*-----------------------------------------------------------------------------------------------
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 <cstddef>
#include <vector>
#include <string.h>
#ifdef _MSC_VER
# 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
#ifndef OPENDDL_NO_USE_CPP11
# define ddl_nullptr nullptr
#else
# define ddl_nullptr NULL
#endif // OPENDDL_NO_USE_CPP11
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()
: m_numRefs( 0 )
, m_referencedName( ddl_nullptr ) {
// empty
}
Reference( size_t numrefs, Name **names )
: m_numRefs( numrefs )
, 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;
}
}
};
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( ddl_nullptr )
, m_ref( ddl_nullptr )
, m_next( ddl_nullptr ) {
// empty
}
};
struct DataArrayList {
size_t m_numItems;
Value *m_dataList;
DataArrayList *m_next;
DataArrayList()
: m_numItems( 0 )
, m_dataList( ddl_nullptr )
, m_next( ddl_nullptr ) {
// empty
}
};
struct Context {
DDLNode *m_root;
Context()
: m_root( ddl_nullptr ) {
// empty
}
};
struct BufferIt {
std::vector<char> m_buffer;
size_t m_idx;
BufferIt( const std::vector<char> &buffer )
: m_buffer( buffer )
, m_idx( 0 ) {
// empty
}
};
END_ODDLPARSER_NS
#endif // OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC

View File

@ -0,0 +1,131 @@
/*-----------------------------------------------------------------------------------------------
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 <openddlparser/OpenDDLCommon.h>
#include <openddlparser/DDLNode.h>
#include <openddlparser/OpenDDLParserUtils.h>
#include <openddlparser/Value.h>
#include <vector>
#include <string>
BEGIN_ODDLPARSER_NS
class DDLNode;
class Value;
struct Identifier;
struct Reference;
struct Property;
template<class T>
inline
T *lookForNextToken( T *in, T *end ) {
while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
in++;
}
return in;
}
template<class T>
inline
T *getNextToken( T *in, T *end ) {
T *tmp( in );
while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
in++;
}
if( tmp == in ) {
in++;
}
return in;
}
/// @brief Defines the log severity.
enum LogSeverity {
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 {
public:
typedef void( *logCallback )( LogSeverity severity, const std::string &msg );
public:
OpenDDLParser();
OpenDDLParser( char *buffer, size_t len );
~OpenDDLParser();
void setLogCallback( logCallback callback );
logCallback getLogCallback() const;
void setBuffer( char *buffer, size_t len );
void setBuffer( const std::vector<char> &buffer );
const 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 );
char *parseStructureBody( char *in, char *end, bool &error );
void pushNode( DDLNode *node );
DDLNode *popNode();
DDLNode *top();
DDLNode *getRoot() const;
Context *getContext() const;
public: // static parser helpers
static void normalizeBuffer( std::vector<char> &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 );
static char *parseReference( char *in, char *end, std::vector<Name*> &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, size_t &numValues, Reference **refs, size_t &numRefs );
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;
std::vector<char> m_buffer;
typedef std::vector<DDLNode*> DDLNodeStack;
DDLNodeStack m_stack;
Context *m_context;
};
END_ODDLPARSER_NS
#endif // OPENDDLPARSER_OPENDDLPARSER_H_INC

View File

@ -0,0 +1,249 @@
/*-----------------------------------------------------------------------------------------------
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 <openddlparser/OpenDDLCommon.h>
BEGIN_ODDLPARSER_NS
template<class T>
inline
bool isComment( T *in, T *end ) {
if( *in == '/' ) {
if( in + 1 != end ) {
if( *( in + 1 ) == '/' ) {
return true;
}
}
}
return false;
}
template<class T>
inline
bool isUpperCase( T in ) {
return ( in >= 'A' && in <= 'Z' );
}
template<class T>
inline
bool isLowerCase( T in ) {
return ( in >= 'a' && in <= 'z' );
}
template<class T>
inline
bool isSpace( const T in ) {
return ( ' ' == in || '\t' == in );
}
template<class T>
inline
bool isNewLine( const T in ) {
return ( '\n' == in || ( '\r' == in ) );
}
template<class T>
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<class T>
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<class T>
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<class T>
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<class T>
inline
bool isCharacter( const T in ) {
return ( ( in >= 'a' && in <= 'z' ) || ( in >= 'A' && in <= 'Z' ) );
}
template<class T>
inline
bool isStringLiteral( const T in ) {
return ( in == '\"' );
}
template<class T>
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<class T>
inline
bool isReference( T *in, T *end ) {
if( *in == 'r' ) {
if( *(in+1) == 'e' ) {
if( *(in+2) == 'f' ) {
if( ( in + 2 ) != end ) {
return true;
}
}
}
}
return false;
}
template<class T>
inline
bool isEndofLine( const T in ) {
return ( '\n' == in );
}
template<class T>
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

View File

@ -0,0 +1,97 @@
/*-----------------------------------------------------------------------------------------------
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 <openddlparser/OpenDDLCommon.h>
#include <string>
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, ///< 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,
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 setString( const std::string &str );
const char *getString() 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

View File

@ -26,7 +26,7 @@
# pragma pack(push,1)
# define PACK_STRUCT
#elif defined( __GNUC__ )
# if defined(__clang__)
# if !defined(HOST_MINGW)
# define PACK_STRUCT __attribute__((__packed__))
# else
# define PACK_STRUCT __attribute__((gcc_struct, __packed__))

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_EXPORT
#include "cexport.h"
#include <map>
namespace Assimp {
class ExporterPimpl;
@ -72,6 +73,9 @@ namespace Assimp {
* #ExportToBlob is especially useful if you intend to work
* with the data in-memory.
*/
class ASSIMP_API ExportProperties;
class ASSIMP_API Exporter
// TODO: causes good ol' base class has no dll interface warning
//#ifdef __cplusplus
@ -81,7 +85,7 @@ class ASSIMP_API Exporter
public:
/** Function pointer type of a Export worker function */
typedef void (*fpExportFunc)(const char*,IOSystem*, const aiScene*);
typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*);
/** Internal description of an Assimp export format option */
struct ExportFormatEntry
@ -171,8 +175,8 @@ public:
* Any IO handlers set via #SetIOHandler are ignored here.
* @note Use aiCopyScene() to get a modifiable copy of a previously
* imported scene. */
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u );
inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u );
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
// -------------------------------------------------------------------
@ -208,8 +212,8 @@ public:
* @return AI_SUCCESS if everything was fine.
* @note Use aiCopyScene() to get a modifiable copy of a previously
* imported scene.*/
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u);
inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u);
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
// -------------------------------------------------------------------
@ -309,16 +313,188 @@ protected:
};
// ----------------------------------------------------------------------------------
inline const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing )
class ASSIMP_API ExportProperties
{
return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing);
public:
// Data type to store the key hash
typedef unsigned int KeyType;
// typedefs for our four configuration maps.
// We don't need more, so there is no need for a generic solution
typedef std::map<KeyType, int> IntPropertyMap;
typedef std::map<KeyType, float> FloatPropertyMap;
typedef std::map<KeyType, std::string> StringPropertyMap;
typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
public:
/** Standard constructor
* @see ExportProperties()
*/
ExportProperties();
// -------------------------------------------------------------------
/** Copy constructor.
*
* This copies the configuration properties of another ExportProperties.
* @see ExportProperties(const ExportProperties& other)
*/
ExportProperties(const ExportProperties& other);
// -------------------------------------------------------------------
/** Set an integer configuration property.
* @param szName Name of the property. All supported properties
* are defined in the aiConfig.g header (all constants share the
* prefix AI_CONFIG_XXX and are simple strings).
* @param iValue New value of the property
* @param bWasExisting Optional pointer to receive true if the
* property was set before. The new value replaces the previous value
* in this case.
* @note Property of different types (float, int, string ..) are kept
* on different stacks, so calling SetPropertyInteger() for a
* floating-point property has no effect - the loader will call
* GetPropertyFloat() to read the property, but it won't be there.
*/
void SetPropertyInteger(const char* szName, int iValue,
bool* bWasExisting = NULL);
// -------------------------------------------------------------------
/** Set a boolean configuration property. Boolean properties
* are stored on the integer stack internally so it's possible
* to set them via #SetPropertyBool and query them with
* #GetPropertyBool and vice versa.
* @see SetPropertyInteger()
*/
void SetPropertyBool(const char* szName, bool value, bool* bWasExisting = NULL) {
SetPropertyInteger(szName,value,bWasExisting);
}
// -------------------------------------------------------------------
/** Set a floating-point configuration property.
* @see SetPropertyInteger()
*/
void SetPropertyFloat(const char* szName, float fValue,
bool* bWasExisting = NULL);
// -------------------------------------------------------------------
/** Set a string configuration property.
* @see SetPropertyInteger()
*/
void SetPropertyString(const char* szName, const std::string& sValue,
bool* bWasExisting = NULL);
// -------------------------------------------------------------------
/** Set a matrix configuration property.
* @see SetPropertyInteger()
*/
void SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue,
bool* bWasExisting = NULL);
// -------------------------------------------------------------------
/** Get a configuration property.
* @param szName Name of the property. All supported properties
* are defined in the aiConfig.g header (all constants share the
* prefix AI_CONFIG_XXX).
* @param iErrorReturn Value that is returned if the property
* is not found.
* @return Current value of the property
* @note Property of different types (float, int, string ..) are kept
* on different lists, so calling SetPropertyInteger() for a
* floating-point property has no effect - the loader will call
* GetPropertyFloat() to read the property, but it won't be there.
*/
int GetPropertyInteger(const char* szName,
int iErrorReturn = 0xffffffff) const;
// -------------------------------------------------------------------
/** Get a boolean configuration property. Boolean properties
* are stored on the integer stack internally so it's possible
* to set them via #SetPropertyBool and query them with
* #GetPropertyBool and vice versa.
* @see GetPropertyInteger()
*/
bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
return GetPropertyInteger(szName,bErrorReturn)!=0;
}
// -------------------------------------------------------------------
/** Get a floating-point configuration property
* @see GetPropertyInteger()
*/
float GetPropertyFloat(const char* szName,
float fErrorReturn = 10e10f) const;
// -------------------------------------------------------------------
/** Get a string configuration property
*
* The return value remains valid until the property is modified.
* @see GetPropertyInteger()
*/
const std::string GetPropertyString(const char* szName,
const std::string& sErrorReturn = "") const;
// -------------------------------------------------------------------
/** Get a matrix configuration property
*
* The return value remains valid until the property is modified.
* @see GetPropertyInteger()
*/
const aiMatrix4x4 GetPropertyMatrix(const char* szName,
const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
// -------------------------------------------------------------------
/** Determine a integer configuration property has been set.
* @see HasPropertyInteger()
*/
bool HasPropertyInteger(const char* szName) const;
/** Determine a boolean configuration property has been set.
* @see HasPropertyBool()
*/
bool HasPropertyBool(const char* szName) const;
/** Determine a boolean configuration property has been set.
* @see HasPropertyFloat()
*/
bool HasPropertyFloat(const char* szName) const;
/** Determine a String configuration property has been set.
* @see HasPropertyString()
*/
bool HasPropertyString(const char* szName) const;
/** Determine a Matrix configuration property has been set.
* @see HasPropertyMatrix()
*/
bool HasPropertyMatrix(const char* szName) const;
protected:
/** List of integer properties */
IntPropertyMap mIntProperties;
/** List of floating-point properties */
FloatPropertyMap mFloatProperties;
/** List of string properties */
StringPropertyMap mStringProperties;
/** List of Matrix properties */
MatrixPropertyMap mMatrixProperties;
};
// ----------------------------------------------------------------------------------
inline const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing, const ExportProperties* pProperties)
{
return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties);
}
// ----------------------------------------------------------------------------------
inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing )
inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
{
return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing);
return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties);
}
} // namespace Assimp

View File

@ -896,4 +896,13 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_COLLADA_INVERT_TRANSPARENCY "IMPORT_COLLADA_INVERT_TRANSPARENCY"
// ---------- All the Export defines ------------
/** @brief Specifies the xfile use double for real values of float
*
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
#endif // !! AI_CONFIG_H_INC

View File

@ -5,6 +5,9 @@
<property name="build.dir" value="jassimp/bin" />
<property name="dist.dir" value="dist" />
<property name="doc.dir" value="doc" />
<property environment="env"/>
<property name="ndk.dir" value="${env.NDK_HOME}" />
<property name="my.dir" value="${env.PWD}" />
<path id="classpath">
</path>
@ -27,6 +30,12 @@
</javah>
</target>
<target name="ndk-jni" depends="package">
<exec executable="${ndk.dir}/ndk-build">
<arg line="all NDK_PROJECT_PATH=${my.dir}/workspaces/Android-NDK"/>
</exec>
</target>
<target name="package" depends="compile">
<jar destfile="${dist.dir}/jassimp.jar" basedir="${build.dir}">
</jar>

View File

@ -0,0 +1,13 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jassimp
LOCAL_SRC_FILES := src/jassimp.cpp
LOCAL_CFLAGS += -DJNI_LOG
#LOCAL_STATIC_LIBRARIES := assimp_static
LOCAL_SHARED_LIBRARIES := assimp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

View File

@ -5,12 +5,16 @@
#ifdef JNI_LOG
#ifdef ANDROID
#include <android/log.h>
#define lprintf(...) __android_log_print(ANDROID_LOG_VERBOSE, __func__, __VA_ARGS__)
#else
#define lprintf(...) printf (__VA_ARGS__)
#endif /* ANDROID */
#else
#define lprintf
#endif
static bool createInstance(JNIEnv *env, const char* className, jobject& newInstance)
{
jclass clazz = env->FindClass(className);
@ -30,6 +34,7 @@ static bool createInstance(JNIEnv *env, const char* className, jobject& newInsta
}
newInstance = env->NewObject(clazz, ctr_id);
env->DeleteLocalRef(clazz);
if (NULL == newInstance)
{
@ -41,7 +46,7 @@ static bool createInstance(JNIEnv *env, const char* className, jobject& newInsta
}
static bool createInstance(JNIEnv *env, const char* className, const char* signature, const jvalue* params, jobject& newInstance)
static bool createInstance(JNIEnv *env, const char* className, const char* signature,/* const*/ jvalue* params, jobject& newInstance)
{
jclass clazz = env->FindClass(className);
@ -60,6 +65,7 @@ static bool createInstance(JNIEnv *env, const char* className, const char* signa
}
newInstance = env->NewObjectA(clazz, ctr_id, params);
env->DeleteLocalRef(clazz);
if (NULL == newInstance)
{
@ -82,6 +88,7 @@ static bool getField(JNIEnv *env, jobject object, const char* fieldName, const c
}
jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature);
env->DeleteLocalRef(clazz);
if (NULL == fieldId)
{
@ -106,6 +113,7 @@ static bool setIntField(JNIEnv *env, jobject object, const char* fieldName, jint
}
jfieldID fieldId = env->GetFieldID(clazz, fieldName, "I");
env->DeleteLocalRef(clazz);
if (NULL == fieldId)
{
@ -130,6 +138,7 @@ static bool setFloatField(JNIEnv *env, jobject object, const char* fieldName, jf
}
jfieldID fieldId = env->GetFieldID(clazz, fieldName, "F");
env->DeleteLocalRef(clazz);
if (NULL == fieldId)
{
@ -154,6 +163,7 @@ static bool setObjectField(JNIEnv *env, jobject object, const char* fieldName, c
}
jfieldID fieldId = env->GetFieldID(clazz, fieldName, signature);
env->DeleteLocalRef(clazz);
if (NULL == fieldId)
{
@ -192,7 +202,7 @@ static bool getStaticField(JNIEnv *env, const char* className, const char* field
static bool call(JNIEnv *env, jobject object, const char* typeName, const char* methodName,
const char* signature, const jvalue* params)
const char* signature,/* const*/ jvalue* params)
{
jclass clazz = env->FindClass(typeName);
@ -203,6 +213,7 @@ static bool call(JNIEnv *env, jobject object, const char* typeName, const char*
}
jmethodID mid = env->GetMethodID(clazz, methodName, signature);
env->DeleteLocalRef(clazz);
if (NULL == mid)
{
@ -210,6 +221,27 @@ static bool call(JNIEnv *env, jobject object, const char* typeName, const char*
return false;
}
jboolean jReturnValue = env->CallBooleanMethod(object, mid, params[0].l);
return (bool)jReturnValue;
}
static bool callv(JNIEnv *env, jobject object, const char* typeName,
const char* methodName, const char* signature,/* const*/ jvalue* params) {
jclass clazz = env->FindClass(typeName);
if (NULL == clazz) {
lprintf("could not find class %s\n", typeName);
return false;
}
jmethodID mid = env->GetMethodID(clazz, methodName, signature);
env->DeleteLocalRef(clazz);
if (NULL == mid) {
lprintf("could not find method %s with signature %s in type %s\n", methodName, signature, typeName);
return false;
}
env->CallVoidMethodA(object, mid, params);
return true;
@ -217,7 +249,7 @@ static bool call(JNIEnv *env, jobject object, const char* typeName, const char*
static bool callStaticObject(JNIEnv *env, const char* typeName, const char* methodName,
const char* signature, const jvalue* params, jobject& returnValue)
const char* signature,/* const*/ jvalue* params, jobject& returnValue)
{
jclass clazz = env->FindClass(typeName);
@ -338,7 +370,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
/* set general mesh data in java */
jvalue setTypesParams[1];
setTypesParams[0].i = cMesh->mPrimitiveTypes;
if (!call(env, jMesh, "jassimp/AiMesh", "setPrimitiveTypes", "(I)V", setTypesParams))
if (!callv(env, jMesh, "jassimp/AiMesh", "setPrimitiveTypes", "(I)V", setTypesParams))
{
return false;
}
@ -380,7 +412,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
allocateBuffersParams[1].i = cMesh->mNumFaces;
allocateBuffersParams[2].z = isPureTriangle;
allocateBuffersParams[3].i = (jint) faceBufferSize;
if (!call(env, jMesh, "jassimp/AiMesh", "allocateBuffers", "(IIZI)V", allocateBuffersParams))
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateBuffers", "(IIZI)V", allocateBuffersParams))
{
return false;
}
@ -470,7 +502,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
jvalue allocateDataChannelParams[2];
allocateDataChannelParams[0].i = 0;
allocateDataChannelParams[1].i = 0;
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
{
lprintf("could not allocate normal data channel\n");
return false;
@ -491,7 +523,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
jvalue allocateDataChannelParams[2];
allocateDataChannelParams[0].i = 1;
allocateDataChannelParams[1].i = 0;
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
{
lprintf("could not allocate tangents data channel\n");
return false;
@ -512,7 +544,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
jvalue allocateDataChannelParams[2];
allocateDataChannelParams[0].i = 2;
allocateDataChannelParams[1].i = 0;
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
{
lprintf("could not allocate bitangents data channel\n");
return false;
@ -535,7 +567,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
jvalue allocateDataChannelParams[2];
allocateDataChannelParams[0].i = 3;
allocateDataChannelParams[1].i = c;
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
{
lprintf("could not allocate colorset data channel\n");
return false;
@ -574,7 +606,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
}
allocateDataChannelParams[1].i = c;
if (!call(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
if (!callv(env, jMesh, "jassimp/AiMesh", "allocateDataChannel", "(II)V", allocateDataChannelParams))
{
lprintf("could not allocate texture coordinates data channel\n");
return false;
@ -671,7 +703,7 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapParams[0].l = jMatrixArr;
jobject jMatrix;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapMatrix", "([F)Ljava/lang/Object;", wrapParams, jMatrix))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapMatrix", "([F)Ljava/lang/Object;", wrapParams, jMatrix))
{
return false;
}
@ -701,6 +733,8 @@ static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
}
}
}
env->DeleteLocalRef(jMeshes);
env->DeleteLocalRef(jMesh);
}
return true;
@ -719,7 +753,7 @@ static bool loadSceneNode(JNIEnv *env, const aiNode *cNode, jobject parent, jobj
wrapMatParams[0].l = jMatrixArr;
jobject jMatrix;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapMatrix", "([F)Ljava/lang/Object;", wrapMatParams, jMatrix))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapMatrix", "([F)Ljava/lang/Object;", wrapMatParams, jMatrix))
{
return false;
}
@ -749,7 +783,7 @@ static bool loadSceneNode(JNIEnv *env, const aiNode *cNode, jobject parent, jobj
wrapNodeParams[2].l = jMeshrefArr;
wrapNodeParams[3].l = jNodeName;
jobject jNode;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapSceneNode",
if (!callStaticObject(env, "jassimp/Jassimp", "wrapSceneNode",
"(Ljava/lang/Object;Ljava/lang/Object;[ILjava/lang/String;)Ljava/lang/Object;", wrapNodeParams, jNode))
{
return false;
@ -842,7 +876,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
setNumberParams[0].i = ttInd;
setNumberParams[1].i = num;
if (!call(env, jMaterial, "jassimp/AiMaterial", "setTextureNumber", "(II)V", setNumberParams))
if (!callv(env, jMaterial, "jassimp/AiMaterial", "setTextureNumber", "(II)V", setNumberParams))
{
return false;
}
@ -880,7 +914,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapColorParams[0].f = ((float*) cProperty->mData)[0];
wrapColorParams[1].f = ((float*) cProperty->mData)[1];
wrapColorParams[2].f = ((float*) cProperty->mData)[2];
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jData))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jData))
{
return false;
}
@ -905,7 +939,7 @@ static bool loadMaterials(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapColorParams[1].f = ((float*) cProperty->mData)[1];
wrapColorParams[2].f = ((float*) cProperty->mData)[2];
wrapColorParams[3].f = ((float*) cProperty->mData)[3];
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor4", "(FFFF)Ljava/lang/Object;", wrapColorParams, jData))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor4", "(FFFF)Ljava/lang/Object;", wrapColorParams, jData))
{
return false;
}
@ -1137,7 +1171,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapColorParams[1].f = cLight->mColorDiffuse.g;
wrapColorParams[2].f = cLight->mColorDiffuse.b;
jobject jDiffuse;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jDiffuse))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jDiffuse))
{
return false;
}
@ -1146,7 +1180,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapColorParams[1].f = cLight->mColorSpecular.g;
wrapColorParams[2].f = cLight->mColorSpecular.b;
jobject jSpecular;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jSpecular))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jSpecular))
{
return false;
}
@ -1155,7 +1189,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapColorParams[1].f = cLight->mColorAmbient.g;
wrapColorParams[2].f = cLight->mColorAmbient.b;
jobject jAmbient;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jAmbient))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapColor3", "(FFF)Ljava/lang/Object;", wrapColorParams, jAmbient))
{
return false;
}
@ -1167,7 +1201,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapVec3Params[1].f = cLight->mPosition.y;
wrapVec3Params[2].f = cLight->mPosition.z;
jobject jPosition;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jPosition))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jPosition))
{
return false;
}
@ -1176,7 +1210,7 @@ static bool loadLights(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapVec3Params[1].f = cLight->mPosition.y;
wrapVec3Params[2].f = cLight->mPosition.z;
jobject jDirection;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jDirection))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapVec3Params, jDirection))
{
return false;
}
@ -1242,7 +1276,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapPositionParams[1].f = cCamera->mPosition.y;
wrapPositionParams[2].f = cCamera->mPosition.z;
jobject jPosition;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jPosition))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jPosition))
{
return false;
}
@ -1251,7 +1285,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapPositionParams[1].f = cCamera->mUp.y;
wrapPositionParams[2].f = cCamera->mUp.z;
jobject jUp;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jUp))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jUp))
{
return false;
}
@ -1260,7 +1294,7 @@ static bool loadCameras(JNIEnv *env, const aiScene* cScene, jobject& jScene)
wrapPositionParams[1].f = cCamera->mLookAt.y;
wrapPositionParams[2].f = cCamera->mLookAt.z;
jobject jLookAt;
if (!callStaticObject(env, "Ljassimp/Jassimp;", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jLookAt))
if (!callStaticObject(env, "jassimp/Jassimp", "wrapVec3", "(FFF)Ljava/lang/Object;", wrapPositionParams, jLookAt))
{
return false;
}

View File

@ -1,33 +0,0 @@
rem ------------------------------------------------------------------------------
rem Tiny script to execute a single unit test suite.
rem
rem Usage:
rem SET OUTDIR=<directory_for_test_results>
rem SET BINDIR=<directory_where_binaries_are_stored>
rem
rem CALL RunSingleUnitTestSuite <name_of_test> <output_file>
rem
rem Post:
rem FIRSTUTNA - if the test wasn't found, receives the test name
rem FIRSTUTFAILUR - if the test failed, receives the test name
rem
rem ------------------------------------------------------------------------------
IF NOT EXIST %BINDIR%\%1\unit.exe (
echo NOT AVAILABLE. Please rebuild this configuration
echo Unable to find %BINDIR%\%1\unit.exe > %OUTDIR%%2
SET FIRSTUTNA=%2
) ELSE (
%BINDIR%\%1\unit.exe > %OUTDIR%%2
IF errorlevel == 0 (
echo SUCCESS
) ELSE (
echo FAILURE, check output file: %2
SET FIRSTUTFAILURE=%2
)
)
echo.
echo.

View File

@ -1,94 +0,0 @@
rem ------------------------------------------------------------------------------
rem Tiny script to execute Assimp's fully unit test suite for all configurations
rem
rem Usage: call RunUnitTestSuite
rem ------------------------------------------------------------------------------
rem Setup the console environment
set errorlevel=0
color 4e
cls
@echo off
rem Setup target architecture
SET ARCHEXT=x64
IF %PROCESSOR_ARCHITECTURE% == x86 (
SET ARCHEXT=win32
)
rem Setup standard paths from here
SET OUTDIR=results\
SET BINDIR=..\bin\
SET FIRSTUTFAILURE=nil
SET FIRSTUTNA=nil
echo #=====================================================================
echo # Open Asset Import Library - Unittests
echo #=====================================================================
echo #
echo # Executes the Assimp library unit test suite for the following
echo # build configurations (if available):
echo #
echo # Release
echo # Release -st
echo # Release -noboost
echo # Release -dll
echo #
echo # Debug
echo # Debug -st
echo # Debug -noboost
echo # Debug -dll
echo ======================================================================
echo.
echo.
echo assimp-core release
echo **********************************************************************
call RunSingleUnitTestSuite unit_release_%ARCHEXT% release.txt
echo assimp-core release -st
echo **********************************************************************
call RunSingleUnitTestSuite unit_release-st_%ARCHEXT% release-st.txt
echo assimp-core release -noboost
echo **********************************************************************
call RunSingleUnitTestSuite unit_release-noboost-st_%ARCHEXT% release-st-noboost.txt
echo assimp-core release -dll
echo **********************************************************************
call RunSingleUnitTestSuite unit_release-dll_%ARCHEXT% release-dll.txt
echo assimp-core debug
echo **********************************************************************
call RunSingleUnitTestSuite unit_debug_%ARCHEXT% debug.txt
echo assimp-core debug -st
echo **********************************************************************
call RunSingleUnitTestSuite unit_debug-st_%ARCHEXT% debug-st.txt
echo assimp-core debug -noboost
echo **********************************************************************
call RunSingleUnitTestSuite unit_debug-noboost-st_%ARCHEXT% debug-st-noboost.txt
echo assimp-core debug -dll
echo **********************************************************************
call RunSingleUnitTestSuite unit_debug-dll_%ARCHEXT% debug-dll.txt
echo ======================================================================
IF %FIRSTUTNA% == nil (
echo All test configs have been found.
) ELSE (
echo One or more test configs are not available.
)
IF %FIRSTUTFAILURE% == nil (
echo All tests have been successful.
) ELSE (
echo One or more tests failed.
)
echo.
pause

View File

@ -0,0 +1,754 @@
ply
format ascii 1.0
element vertex 486
property float32 x
property float32 y
property float32 z
element face 912
property list uint8 int32 vertex_indices
end_header
-1.106 3.844 9.073
-0.3523 0.4402 11.07
1.028 3.76 9.209
0.137 -0.5632 10.73
2.01 4.503 5.887
0.07813 5.232 6.794
-0.7266 3.741 3.839
-2.789 3.179 5.07
-0.9185 2.402 3.279
1.445 2.139 3.394
-3.114 1.498 5.285
-1.317 -1.269 8.385
-0.854 -1.319 5.036
-0.9351 5.347 0.6162
-0.8184 2.622 3.235
0.4875 5.529 -0.2241
3.193 2.756 1.633
3.213 1.145 -2.568
-2.25 1.208 2.767
0.3225 0.8339 3.323
1.354 -1.725 1.105
0.1887 1.133 -5.785
-3.637 2.696 0.3325
-3.706 0.8936 -0.5452
-0.4326 -0.8737 -4.095
-2.994 -0.4858 0.9023
0.1252 -2.079 -1.51
2.856 -0.7459 -1.187
2.32 3.733 8.13
2.031 3.721 9.095
2.819 3.567 8.537
1.994 2.581 9.711
2.64 2.491 9.542
3.187 2.528 8.375
1.628 2.491 7.518
1.62 3.721 8.274
0.9868 2.471 8.914
1.552 2.106 9.414
2.657 1.774 8.918
-1.805 3.733 8.13
-2.094 3.721 9.095
-1.306 3.567 8.537
-2.131 2.581 9.711
-1.485 2.491 9.542
-0.938 2.528 8.375
-2.497 2.491 7.518
-2.505 3.721 8.274
-3.138 2.471 8.914
-2.573 2.106 9.414
-1.469 1.774 8.918
1.549 3.638 6.803
1.355 3.638 6.7
1.424 5.126 6.883
1.615 5.083 6.981
1.169 3.638 6.815
1.237 5.115 6.997
1.176 3.638 7.035
1.241 5.061 7.21
1.369 3.638 7.138
1.433 5.018 7.308
1.556 3.638 7.023
1.62 5.029 7.194
1.625 6.512 7.421
1.811 6.429 7.504
1.437 6.49 7.531
1.434 6.386 7.724
1.619 6.304 7.807
1.808 6.326 7.697
1.945 7.702 8.276
2.121 7.585 8.335
1.754 7.672 8.38
1.74 7.525 8.542
1.916 7.408 8.601
2.107 7.439 8.497
2.362 8.615 9.391
2.526 8.473 9.417
2.168 8.578 9.487
2.138 8.398 9.608
2.303 8.255 9.635
2.497 8.293 9.539
2.847 9.189 10.69
2.998 9.03 10.68
2.649 9.148 10.78
2.603 8.947 10.85
2.753 8.788 10.84
2.95 8.83 10.75
3.368 9.385 12.08
3.503 9.22 12.03
3.167 9.342 12.16
3.101 9.134 12.18
3.236 8.97 12.13
3.438 9.013 12.06
3.889 9.189 13.48
4.01 9.03 13.39
3.684 9.148 13.54
3.599 8.947 13.51
3.719 8.788 13.42
3.925 8.83 13.36
4.374 8.615 14.77
4.481 8.473 14.65
4.165 8.578 14.83
4.063 8.398 14.76
4.17 8.255 14.63
4.379 8.293 14.57
4.791 7.702 15.89
4.886 7.585 15.73
4.579 7.672 15.94
4.462 7.525 15.82
4.556 7.408 15.66
4.769 7.439 15.62
5.111 6.512 16.74
5.196 6.429 16.56
4.896 6.49 16.78
4.768 6.386 16.64
4.853 6.304 16.46
5.068 6.326 16.42
-1.141 5.126 6.883
-1.072 3.638 6.7
-1.266 3.638 6.803
-1.332 5.083 6.981
-0.9541 5.115 6.997
-0.886 3.638 6.815
-0.9585 5.061 7.21
-0.8928 3.638 7.035
-1.15 5.018 7.308
-1.086 3.638 7.138
-1.337 5.029 7.194
-1.272 3.638 7.023
-1.342 6.512 7.421
-1.528 6.429 7.504
-1.154 6.49 7.531
-1.151 6.386 7.724
-1.336 6.304 7.807
-1.525 6.326 7.697
-1.662 7.702 8.276
-1.838 7.585 8.335
-1.471 7.672 8.38
-1.457 7.525 8.542
-1.633 7.408 8.601
-1.824 7.439 8.497
-2.079 8.615 9.391
-2.243 8.473 9.417
-1.885 8.578 9.487
-1.855 8.398 9.608
-2.02 8.255 9.635
-2.214 8.293 9.539
-2.564 9.189 10.69
-2.715 9.03 10.68
-2.366 9.148 10.78
-2.32 8.947 10.85
-2.47 8.788 10.84
-2.667 8.83 10.75
-3.085 9.385 12.08
-3.22 9.22 12.03
-2.884 9.342 12.16
-2.818 9.134 12.18
-2.953 8.97 12.13
-3.155 9.013 12.06
-3.606 9.189 13.48
-3.726 9.03 13.39
-3.4 9.148 13.54
-3.316 8.947 13.51
-3.437 8.788 13.42
-3.642 8.83 13.36
-4.091 8.615 14.77
-4.198 8.473 14.65
-3.882 8.578 14.83
-3.78 8.398 14.76
-3.887 8.255 14.63
-4.096 8.293 14.57
-4.508 7.702 15.89
-4.603 7.585 15.73
-4.296 7.672 15.94
-4.179 7.525 15.82
-4.273 7.408 15.66
-4.485 7.439 15.62
-4.828 6.512 16.74
-4.913 6.429 16.56
-4.613 6.49 16.78
-4.484 6.386 16.64
-4.57 6.304 16.46
-4.784 6.326 16.42
-1.519 -2.27 2.989
-1.987 -1.082 3.408
-2.709 -1.989 3.536
-1.513 -2.259 2.974
-2.524 -1.536 2.471
-4.318 -0.3933 4.187
-4.692 -0.6204 3.123
-6.274 0.9227 4.173
-5.533 1.852 4.043
-6.084 1.387 3.082
-6.844 2.279 4.015
-6.83 1.957 4.012
-6.886 2.118 3.737
-7.536 1.346 4.658
-7.229 0.9683 4.298
-8.053 1.724 3.821
-7.747 1.346 3.46
-9.085 -0.1982 5.078
-9.347 -0.1982 3.597
-8.702 -0.7393 4.247
-10.91 -1.528 5.154
-10.39 -2.11 4.847
-11.08 -1.528 4.148
-10.49 -2.11 4.26
-11.58 -2.509 4.768
-11.57 -2.523 4.76
-11.59 -2.509 4.742
-11.57 -2.523 4.744
-12.39 -3.546 5.269
-11.93 -3.852 5.034
-12.52 -3.546 4.548
-12.87 -4.803 5.622
-12.58 -5.09 4.606
-13.49 -4.516 4.767
-13.11 -6.264 5.38
-14.78 -6.803 5.643
-14.49 -7.092 4.622
-15.35 -8.042 5.637
-14.73 -8.43 5.528
-15.15 -8.236 4.95
-15.78 -9.378 5.503
-15.77 -9.385 5.497
-15.78 -9.375 5.495
-15.78 -9.378 5.486
-15.77 -9.383 5.484
-1.522 -2.262 -1.24
-1.519 -2.258 -1.231
-1.522 -2.262 -1.222
-1.529 -2.27 -1.222
-1.529 -2.27 -1.24
-2.061 -1.082 -0.8906
-2.428 -1.536 -1.907
-3.082 -0.4963 -0.5522
-3.082 -0.4963 -1.91
-3.759 -1.333 -1.628
-5.567 0.1257 -0.8323
-5.665 1.852 -0.8818
-6.417 0.9227 -0.8818
-6.041 1.387 -1.924
-6.95 2.279 -1.137
-6.937 1.957 -1.326
-6.943 2.118 -1.418
-7.378 0.9683 -0.9246
-8.108 1.724 -0.9246
-7.743 1.346 -1.84
-8.797 0.8371 -0.6052
-9.793 0.269 -1.611
-8.891 -0.6654 -1.611
-10.59 -2.11 -0.9326
-10.57 -0.523 -0.8679
-11.3 -1.375 -0.9326
-10.94 -1.742 -1.823
-11.75 -2.506 -1.223
-11.73 -2.523 -1.223
-11.74 -2.514 -1.247
-12.76 -3.466 -1.017
-12.14 -3.852 -1.017
-12.45 -3.659 -1.656
-13.16 -4.803 -0.6001
-12.7 -5.09 -1.55
-13.62 -4.516 -1.55
-13.36 -6.264 -0.8809
-15.05 -6.803 -0.9114
-14.58 -7.092 -1.866
-15.6 -8.042 -1.016
-14.98 -8.43 -1.016
-15.29 -8.236 -1.658
-16.01 -9.378 -1.222
-15.99 -9.385 -1.226
-16.01 -9.375 -1.231
-16.01 -9.378 -1.24
-16 -9.383 -1.24
-1.522 -2.27 -4.918
-2.105 -1.082 -4.684
-2.827 -1.989 -4.812
-1.513 -2.262 -4.935
-2.29 -1.536 -5.749
-4.562 -0.3933 -4.75
-4.55 -0.6204 -5.878
-6.395 0.9227 -5.432
-5.655 1.852 -5.302
-5.844 1.387 -6.393
-6.877 2.279 -5.776
-6.863 1.957 -5.773
-6.821 2.118 -6.051
-7.747 1.346 -5.408
-7.335 0.9683 -5.641
-7.947 1.724 -6.372
-7.536 1.346 -6.605
-9.347 -0.1982 -5.543
-9.085 -0.1982 -7.025
-8.702 -0.7393 -6.193
-11.08 -1.528 -6.095
-10.49 -2.11 -6.206
-10.91 -1.528 -7.101
-10.39 -2.11 -6.794
-11.59 -2.509 -6.689
-11.57 -2.523 -6.691
-11.58 -2.509 -6.715
-11.57 -2.523 -6.707
-12.52 -3.546 -6.495
-12.01 -3.852 -6.559
-12.39 -3.546 -7.217
-13.09 -4.803 -6.326
-12.47 -5.09 -7.18
-13.38 -4.516 -7.341
-13.24 -6.264 -6.637
-14.89 -6.803 -6.96
-14.27 -7.092 -7.819
-15.42 -8.042 -7.159
-14.8 -8.43 -7.051
-15 -8.236 -7.738
-15.78 -9.378 -7.432
-15.77 -9.385 -7.434
-15.78 -9.375 -7.442
-15.78 -9.378 -7.45
-15.77 -9.383 -7.448
1.522 -2.27 -4.918
1.511 -2.258 -4.926
1.513 -2.262 -4.935
2.828 -1.989 -4.812
2.105 -1.082 -4.684
2.29 -1.536 -5.749
4.55 -0.6204 -5.878
4.562 -0.3933 -4.75
6.395 0.9227 -5.432
5.655 1.852 -5.302
5.844 1.387 -6.393
6.877 2.279 -5.776
6.863 1.957 -5.773
6.821 2.118 -6.051
7.335 0.9683 -5.641
7.747 1.346 -5.408
7.947 1.724 -6.372
7.536 1.346 -6.605
9.347 -0.1982 -5.543
9.086 -0.1982 -7.025
8.702 -0.7393 -6.193
11.08 -1.528 -6.095
10.49 -2.11 -6.206
10.91 -1.528 -7.101
10.39 -2.11 -6.794
11.59 -2.509 -6.689
11.57 -2.523 -6.691
11.58 -2.509 -6.715
11.57 -2.523 -6.707
12.52 -3.546 -6.495
12.01 -3.852 -6.559
12.39 -3.546 -7.217
12.47 -5.09 -7.18
13.09 -4.803 -6.326
13.38 -4.516 -7.341
13.24 -6.264 -6.637
14.89 -6.803 -6.96
14.27 -7.092 -7.819
15.42 -8.042 -7.159
14.8 -8.43 -7.051
15 -8.236 -7.738
15.78 -9.378 -7.432
15.77 -9.385 -7.434
15.78 -9.375 -7.442
15.78 -9.378 -7.45
15.77 -9.383 -7.448
-0.9592 -0.9547 10.35
0.007813 0.3928 11.6
-0.7324 1.062 10.63
0.007813 -1.855 11.37
0.007813 -2.459 10.63
0.007813 0.3928 9.662
-0.3928 1.509 10.63
0.7327 1.062 10.63
-0.007813 0.3928 11.6
0.9595 -0.9547 10.35
-0.007813 -1.855 11.37
-0.007813 -2.459 10.63
-0.007813 0.3928 9.662
0.3931 1.509 10.63
1.513 -2.262 2.988
1.511 -2.258 2.979
1.516 -2.262 2.97
1.522 -2.27 2.971
1.52 -2.27 2.989
1.987 -1.082 3.408
2.524 -1.536 2.471
2.933 -0.4963 3.919
3.168 -0.4963 2.581
3.786 -1.333 2.977
5.429 0.1257 4.074
5.534 1.852 4.042
6.274 0.9227 4.173
6.085 1.387 3.082
6.863 1.957 3.827
6.844 2.279 4.015
6.886 2.118 3.737
7.229 0.9683 4.298
7.947 1.724 4.425
7.747 1.346 3.46
8.57 0.8371 4.859
9.726 0.269 4.042
8.838 -0.6654 3.885
10.39 -2.11 4.847
10.37 -0.523 4.909
11.09 -1.375 4.97
10.89 -1.742 4.032
11.59 -2.506 4.763
11.57 -2.523 4.76
11.58 -2.514 4.739
12.55 -3.466 5.142
11.93 -3.852 5.034
12.35 -3.659 4.459
12.58 -5.09 4.606
12.87 -4.803 5.622
13.49 -4.516 4.767
13.11 -6.264 5.38
14.78 -6.803 5.643
14.49 -7.092 4.622
15.35 -8.042 5.637
14.73 -8.43 5.528
15.15 -8.236 4.95
15.78 -9.378 5.503
15.77 -9.385 5.497
15.78 -9.375 5.495
15.78 -9.378 5.486
15.77 -9.383 5.484
1.529 -2.27 -1.222
1.519 -2.258 -1.231
1.522 -2.262 -1.24
2.795 -1.989 -0.8906
2.062 -1.082 -0.8906
2.428 -1.536 -1.907
4.677 -0.6204 -1.642
4.493 -0.3933 -0.5283
6.417 0.9227 -0.8818
5.665 1.852 -0.8818
6.041 1.387 -1.924
6.951 2.279 -1.137
6.937 1.957 -1.137
6.944 2.118 -1.418
7.379 0.9683 -0.9246
7.743 1.346 -0.623
8.108 1.724 -1.538
7.743 1.346 -1.84
9.343 -0.1982 -0.4792
9.343 -0.1982 -1.983
8.82 -0.7393 -1.231
11.15 -1.528 -0.7207
10.59 -2.11 -0.9326
11.15 -1.528 -1.742
10.59 -2.11 -1.53
11.75 -2.509 -1.218
11.73 -2.523 -1.223
11.75 -2.509 -1.245
11.73 -2.523 -1.239
12.63 -3.546 -0.8647
12.14 -3.852 -1.017
12.63 -3.546 -1.598
12.7 -5.09 -1.55
13.16 -4.803 -0.6001
13.62 -4.516 -1.55
13.36 -6.264 -0.8804
15.05 -6.803 -0.9111
14.58 -7.092 -1.866
15.6 -8.042 -1.016
14.98 -8.43 -1.016
15.29 -8.236 -1.658
16.01 -9.378 -1.222
15.99 -9.385 -1.226
16.01 -9.375 -1.231
16.01 -9.378 -1.24
16 -9.383 -1.24
-0.7932 4.462 -7.734
-0.3843 1.974 -5.495
1.95 3.241 -7.348
1.167 0.6428 -6.109
3.808 0.1871 -9.572
3.644 1.688 -11.88
0.07617 4.961 -10.12
3.28 -0.5704 -14.15
0.2488 -1.848 -16.78
-0.9744 -2.686 -16.57
0.7307 -3.159 -16.47
-2.678 2.963 -8.185
-2.616 -2.779 -12.24
-1.159 -1.533 -8.922
3 0 1 2
3 1 3 2
3 2 4 5
3 4 6 5
3 5 6 7
3 7 6 8
3 2 3 9
3 2 9 4
3 4 9 6
3 6 9 8
3 5 0 2
3 5 7 0
3 8 10 7
3 7 10 0
3 0 10 1
3 1 10 11
3 1 11 3
3 10 12 11
3 11 12 3
3 3 12 9
3 10 8 12
3 12 8 9
3 13 14 15
3 15 14 16
3 17 15 16
3 18 19 14
3 14 19 16
3 19 20 16
3 15 17 21
3 15 21 13
3 14 13 18
3 21 22 13
3 13 22 18
3 21 23 22
3 21 24 23
3 23 25 22
3 22 25 18
3 18 25 20
3 18 20 19
3 23 26 25
3 25 26 20
3 23 24 26
3 26 24 27
3 26 27 20
3 20 27 16
3 24 21 27
3 27 21 17
3 27 17 16
3 28 29 30
3 31 32 29
3 29 32 30
3 32 33 30
3 30 33 28
3 28 33 34
3 28 34 35
3 35 34 36
3 28 35 29
3 35 36 29
3 29 36 31
3 36 37 31
3 31 37 32
3 37 38 32
3 32 38 33
3 36 34 37
3 37 34 38
3 38 34 33
3 39 40 41
3 42 43 40
3 40 43 41
3 43 44 41
3 41 44 39
3 39 44 45
3 39 45 46
3 46 45 47
3 39 46 40
3 46 47 40
3 40 47 42
3 47 48 42
3 42 48 43
3 48 49 43
3 43 49 44
3 47 45 48
3 48 45 49
3 49 45 44
3 50 51 52
3 50 52 53
3 51 54 55
3 51 55 52
3 54 56 57
3 54 57 55
3 56 58 59
3 56 59 57
3 58 60 61
3 58 61 59
3 60 50 53
3 60 53 61
3 53 52 62
3 53 62 63
3 52 55 64
3 52 64 62
3 55 57 65
3 55 65 64
3 57 59 66
3 57 66 65
3 59 61 67
3 59 67 66
3 61 53 63
3 61 63 67
3 63 62 68
3 63 68 69
3 62 64 70
3 62 70 68
3 64 65 71
3 64 71 70
3 65 66 72
3 65 72 71
3 66 67 73
3 66 73 72
3 67 63 69
3 67 69 73
3 69 68 74
3 69 74 75
3 68 70 76
3 68 76 74
3 70 71 77
3 70 77 76
3 71 72 78
3 71 78 77
3 72 73 79
3 72 79 78
3 73 69 75
3 73 75 79
3 75 74 80
3 75 80 81
3 74 76 82
3 74 82 80
3 76 77 83
3 76 83 82
3 77 78 84
3 77 84 83
3 78 79 85
3 78 85 84
3 79 75 81
3 79 81 85
3 81 80 86
3 81 86 87
3 80 82 88
3 80 88 86
3 82 83 89
3 82 89 88
3 83 84 90
3 83 90 89
3 84 85 91
3 84 91 90
3 85 81 87
3 85 87 91
3 87 86 92
3 87 92 93
3 86 88 94
3 86 94 92
3 88 89 95
3 88 95 94
3 89 90 96
3 89 96 95
3 90 91 97
3 90 97 96
3 91 87 93
3 91 93 97
3 93 92 98
3 93 98 99
3 92 94 100
3 92 100 98
3 94 95 101
3 94 101 100
3 95 96 102
3 95 102 101
3 96 97 103
3 96 103 102
3 97 93 99
3 97 99 103
3 99 98 104
3 99 104 105
3 98 100 106
3 98 106 104
3 100 101 107
3 100 107 106
3 101 102 108
3 101 108 107
3 102 103 109
3 102 109 108
3 103 99 105
3 103 105 109
3 105 104 110
3 105 110 111
3 104 106 112
3 104 112 110
3 106 107 113
3 106 113 112
3 107 108 114
3 107 114 113
3 108 109 115
3 108 115 114
3 109 105 111
3 109 111 115
3 54 51 50
3 56 54 50
3 58 56 50
3 60 58 50
3 112 113 110
3 113 114 110
3 114 115 110
3 115 111 110
3 116 117 118
3 119 116 118
3 120 121 117
3 116 120 117
3 122 123 121
3 120 122 121
3 124 125 123
3 122 124 123
3 126 127 125
3 124 126 125
3 119 118 127
3 126 119 127
3 128 116 119
3 129 128 119
3 130 120 116
3 128 130 116
3 131 122 120
3 130 131 120
3 132 124 122
3 131 132 122
3 133 126 124
3 132 133 124
3 129 119 126
3 133 129 126
3 134 128 129
3 135 134 129
3 136 130 128
3 134 136 128
3 137 131 130
3 136 137 130
3 138 132 131
3 137 138 131
3 139 133 132
3 138 139 132
3 135 129 133
3 139 135 133
3 140 134 135
3 141 140 135
3 142 136 134
3 140 142 134
3 143 137 136
3 142 143 136
3 144 138 137
3 143 144 137
3 145 139 138
3 144 145 138
3 141 135 139

View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -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"}
}
}

View File

@ -167,11 +167,11 @@ def process_dir(d, outfile_results, zipin, result):
print("Processing directory " + d)
for f in sorted(os.listdir(d)):
fullpath = os.path.join(d, f)
if os.path.isdir(fullpath) and not f == ".svn":
if os.path.isdir(fullpath) and not f[:1] == '.':
process_dir(fullpath, outfile_results, zipin, result)
continue
if f in settings.files_to_ignore:
if f in settings.files_to_ignore or os.path.splitext(f)[1] in settings.exclude_extensions:
print("Ignoring " + f)
continue
@ -190,32 +190,26 @@ def process_dir(d, outfile_results, zipin, result):
"regression database? Use gen_db.zip to re-generate.")
continue
# Ignore extensions via settings.py configured list
# todo: Fix for multi dot extensions like .skeleton.xml
ext = os.path.splitext(fullpath)[1].lower()
if ext != "" and ext in settings.exclude_extensions:
continue
print("-"*60 + "\n " + os.path.realpath(fullpath) + " pp: " + pppreset)
outfile_actual = prepare_output_dir(fullpath, filehash, "ACTUAL")
outfile_expect = prepare_output_dir(fullpath, filehash, "EXPECT")
outfile_results.write("assimp dump "+"-"*80+"\n")
outfile_results.flush()
command = [assimp_bin_path,
"dump",
fullpath, outfile_actual, "-b", "-s", "-l" ] +\
pppreset.split()
r = subprocess.call(command, **shellparams)
print(r)
outfile_results.flush()
if r and not failure:
result.fail(fullpath, outfile_expect, pppreset, IMPORT_FAILURE, r)
outfile_results.write("Failed to import\n")
continue
elif failure and not r:
result.fail(fullpath, outfile_expect, pppreset, EXPECTED_FAILURE_NOT_MET)
outfile_results.write("Expected import to fail\n")
continue
with open(outfile_expect, "wb") as s:
@ -227,21 +221,24 @@ def process_dir(d, outfile_results, zipin, result):
except IOError:
continue
outfile_results.write("Expected data length: {0}\n".format(len(input_expected)))
outfile_results.write("Actual data length: {0}\n".format(len(input_actual)))
failed = False
if len(input_expected) != len(input_actual):
result.fail(fullpath, outfile_expect, pppreset, DATABASE_LENGTH_MISMATCH,
len(input_expected), len(input_actual))
continue
# Still compare the dumps to see what the difference is
failed = True
outfile_results.write("assimp cmpdump "+"-"*80+"\n")
outfile_results.flush()
command = [ assimp_bin_path, 'cmpdump', outfile_actual, outfile_expect ]
if subprocess.call(command, **shellparams) != 0:
if not failed:
result.fail(fullpath, outfile_expect, pppreset, DATABASE_VALUE_MISMATCH)
continue
result.ok(fullpath, pppreset, COMPARE_SUCCESS,
len(input_expected))
result.ok(fullpath, pppreset, COMPARE_SUCCESS, len(input_expected))
# -------------------------------------------------------------------------------
def del_folder_with_contents(folder):

View File

@ -62,7 +62,7 @@ files_to_ignore = ["pond.0.ply"]
exclude_extensions = [
".lws", ".assbin", ".assxml", ".txt", ".md",
".jpeg", ".jpg", ".png", ".gif", ".tga", ".bmp",
".skeleton", ".skeleton.xml"
".skeleton", ".skeleton.xml", ".license"
]
# -------------------------------------------------------------------------------

View File

@ -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} )
SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES
OUTPUT_NAME assimp
)

View File

@ -257,16 +257,32 @@ private:
/* read from both streams simult.*/
template <typename T> void read(T& filla,T& fille) {
if(1 != fread(&filla,sizeof(T),1,actual)) {
throw compare_fails_exception("Unexpected EOF reading ACTUAL");
EOFActual();
}
if(1 != fread(&fille,sizeof(T),1,expect)) {
throw compare_fails_exception("Unexpected EOF reading EXPECT");
EOFExpect();
}
}
private:
void EOFActual() {
std::stringstream ss;
throw compare_fails_exception((ss
<< "Unexpected EOF reading ACTUAL.\nCurrent position in scene hierarchy is "
<< print_hierarchy(),ss.str().c_str()
));
}
void EOFExpect() {
std::stringstream ss;
throw compare_fails_exception((ss
<< "Unexpected EOF reading EXPECT.\nCurrent position in scene hierarchy is "
<< print_hierarchy(),ss.str().c_str()
));
}
FILE *const actual, *const expect;
typedef std::map<std::string,unsigned int> PerChunkCounter;
@ -290,10 +306,10 @@ template <> void comparer_context :: read<aiString>(aiString& filla,aiString& fi
read(lena,lene);
if(lena && 1 != fread(&filla.data,lena,1,actual)) {
throw compare_fails_exception("Unexpected EOF reading ACTUAL");
EOFActual();
}
if(lene && 1 != fread(&fille.data,lene,1,expect)) {
throw compare_fails_exception("Unexpected EOF reading ACTUAL");
EOFExpect();
}
fille.data[fille.length=static_cast<unsigned int>(lene)] = '\0';
@ -487,7 +503,7 @@ private:
res|=fread(&actual.second,4,1,ctx.get_actual()) <<3u;
if(res!=0xf) {
ctx.failure("I/OError reading chunk head, dumps are not well-defined","<ChunkHead>");
ctx.failure("IO Error reading chunk head, dumps are malformed","<ChunkHead>");
}
if (current.first != actual.first) {
@ -504,7 +520,7 @@ private:
if (current.first != actual.first) {
std::stringstream ss;
ctx.failure((ss
<<"Chunk lenghts do not match. EXPECT: "
<<"Chunk lengths do not match. EXPECT: "
<<current.second
<<" ACTUAL: "
<< actual.second,

View File

@ -0,0 +1,124 @@
LOCAL_PATH := $(call my-dir)/../../../
include $(CLEAR_VARS)
LOCAL_MODULE := assimp_static
ASSIMP_SRC_DIR = code
FILE_LIST := $(wildcard $(LOCAL_PATH)/$(ASSIMP_SRC_DIR)/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/contrib/openddlparser/code/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/contrib/unzip/*.c)
FILE_LIST += $(wildcard $(LOCAL_PATH)/contrib/poly2tri/poly2tri/*/*.cc)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_SRC_FILES += contrib/clipper/clipper.cpp \
contrib/ConvertUTF/ConvertUTF.c \
contrib/irrXML/irrXML.cpp
# enables -frtti and -fexceptions
LOCAL_CPP_FEATURES := exceptions
# identifier 'nullptr' will become a keyword in C++0x [-Wc++0x-compat]
# but next breaks blender and other importer
# LOCAL_CFLAGS += -std=c++11
# cant be disabled? rudamentary function?
# -DASSIMP_BUILD_NO_FLIPWINDING_PROCESS \
#
DontBuildProcess = \
-DASSIMP_BUILD_NO_FLIPUVS_PROCESS \
-DASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS \
-DASSIMP_BUILD_NO_CALCTANGENTS_PROCESS \
-DASSIMP_BUILD_NO_DEBONE_PROCESS \
-DASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS \
-DASSIMP_BUILD_NO_FINDINSTANCES_PROCESS \
-DASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS \
-DASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS \
-DASSIMP_BUILD_NO_GENFACENORMALS_PROCESS \
-DASSIMP_BUILD_NO_GENUVCOORDS_PROCESS \
-DASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS \
-DASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS \
-DASSIMP_BUILD_NO_JOINVERTICES_PROCESS \
-DASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS \
-DASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS \
-DASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS \
-DASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS \
-DASSIMP_BUILD_NO_REMOVEVC_PROCESS \
-DASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS \
-DASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS \
-DASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS \
-DASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS \
-DASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS \
-DASSIMP_BUILD_NO_TRIANGULATE_PROCESS \
-DASSIMP_BUILD_NO_VALIDATEDS_PROCESS
DontBuildImporters = \
-DASSIMP_BUILD_NO_X_IMPORTER \
-DASSIMP_BUILD_NO_3DS_IMPORTER \
-DASSIMP_BUILD_NO_MD3_IMPORTER \
-DASSIMP_BUILD_NO_MDL_IMPORTER \
-DASSIMP_BUILD_NO_MD2_IMPORTER \
-DASSIMP_BUILD_NO_PLY_IMPORTER \
-DASSIMP_BUILD_NO_ASE_IMPORTER \
-DASSIMP_BUILD_NO_HMP_IMPORTER \
-DASSIMP_BUILD_NO_SMD_IMPORTER \
-DASSIMP_BUILD_NO_MDC_IMPORTER \
-DASSIMP_BUILD_NO_MD5_IMPORTER \
-DASSIMP_BUILD_NO_STL_IMPORTER \
-DASSIMP_BUILD_NO_LWO_IMPORTER \
-DASSIMP_BUILD_NO_DXF_IMPORTER \
-DASSIMP_BUILD_NO_NFF_IMPORTER \
-DASSIMP_BUILD_NO_RAW_IMPORTER \
-DASSIMP_BUILD_NO_OFF_IMPORTER \
-DASSIMP_BUILD_NO_AC_IMPORTER \
-DASSIMP_BUILD_NO_BVH_IMPORTER \
-DASSIMP_BUILD_NO_IRRMESH_IMPORTER \
-DASSIMP_BUILD_NO_IRR_IMPORTER \
-DASSIMP_BUILD_NO_Q3D_IMPORTER \
-DASSIMP_BUILD_NO_B3D_IMPORTER \
-DASSIMP_BUILD_NO_COLLADA_IMPORTER \
-DASSIMP_BUILD_NO_TERRAGEN_IMPORTER \
-DASSIMP_BUILD_NO_CSM_IMPORTER \
-DASSIMP_BUILD_NO_3D_IMPORTER \
-DASSIMP_BUILD_NO_LWS_IMPORTER \
-DASSIMP_BUILD_NO_OGRE_IMPORTER \
-DASSIMP_BUILD_NO_MS3D_IMPORTER \
-DASSIMP_BUILD_NO_COB_IMPORTER \
-DASSIMP_BUILD_NO_Q3BSP_IMPORTER \
-DASSIMP_BUILD_NO_NDO_IMPORTER \
-DASSIMP_BUILD_NO_IFC_IMPORTER \
-DASSIMP_BUILD_NO_XGL_IMPORTER \
-DASSIMP_BUILD_NO_FBX_IMPORTER \
-DASSIMP_BUILD_NO_C4D_IMPORTER \
-DASSIMP_BUILD_NO_OPENGEX_IMPORTER \
-DASSIMP_BUILD_NO_ASSBIN_IMPORTER
# -DASSIMP_BUILD_NO_BLEND_IMPORTER \
# -DASSIMP_BUILD_NO_GEO_IMPORTER
# -DASSIMP_BUILD_NO_OBJ_IMPORTER \
#
DontBuildImporters := -DASSIMP_BUILD_NO_IFC_IMPORTER -DASSIMP_BUILD_NO_IRRMESH_IMPORTER -DASSIMP_BUILD_NO_IRR_IMPORTER -DASSIMP_BUILD_NO_C4D_IMPORTER
ASSIMP_FLAGS_3_0 = -DASSIMP_BUILD_DLL_EXPORT -DASSIMP_BUILD_NO_OWN_ZLIB -DASSIMP_BUILD_BOOST_WORKAROUND -Dassimp_EXPORTS -fPIC -fvisibility=hidden -Wall
ASSIMP_FLAGS_3_1 = $(ASSIMP_FLAGS_3_0) # -DASSIMP_BUILD_BLENDER_DEBUG
LOCAL_CFLAGS += $(ASSIMP_FLAGS_3_1) -DASSIMP_BUILD_NO_EXPORT -DOPENDDL_NO_USE_CPP11 $(DontBuildImporters) # $(DontBuildProcess)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include $(LOCAL_PATH)/$(ASSIMP_SRC_DIR)/BoostWorkaround $(LOCAL_PATH)/contrib/openddlparser/include ./
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/$(ASSIMP_SRC_DIR)/BoostWorkaround
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := assimp
LOCAL_CFLAGS += -UASSIMP_BUILD_DLL_EXPORT
LOCAL_WHOLE_STATIC_LIBRARIES = assimp_static
LOCAL_LDLIBS := -lz
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/$(ASSIMP_SRC_DIR)/BoostWorkaround
include $(BUILD_SHARED_LIBRARY)
-include $(LOCAL_PATH)/assimp_cmd.mk
# let it on original place
include $(LOCAL_PATH)/port/jassimp/jassimp-native/Android.mk

View File

@ -0,0 +1,8 @@
ifeq ($(CC),clang)
NDK_TOOLCHAIN_VERSION := $(CC)
$(info "Use llvm Compiler")
endif
APP_ABI := armeabi-v7a
APP_STL := stlport_static