Merge pull request #13 from assimp/master

Update fork
pull/1350/head
Madrich 2017-07-17 09:07:41 +02:00 committed by GitHub
commit ae0850b88c
95 changed files with 5077 additions and 902 deletions

View File

@ -2,7 +2,7 @@ sudo: required
language: cpp
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install cmake python3 homebrew/x11/freeglut; fi
- 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
# install latest LCOV (1.9 was failing)
@ -16,6 +16,7 @@ osx_image: xcode8.3
env:
global:
# COVERITY_SCAN_TOKEN
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
matrix:
@ -23,11 +24,7 @@ env:
- LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF
- LINUX=1 SHARED_BUILD=ON ENABLE_COVERALLS=OFF
- LINUX=1 SHARED_BUILD=OFF ENABLE_COVERALLS=OFF
#exclude:
# - os: linux
# compiler: clang
# - os: osx
# compiler: gcc
compiler:
- gcc
- clang

View File

@ -78,12 +78,10 @@ OPTION ( ASSIMP_COVERALLS
"Eańable this to measure test coverage."
OFF
)
option ( SYSTEM_IRRXML
"Use system installed Irrlicht/IrrXML library."
OFF
)
OPTION ( BUILD_DOCS
"Build documentation using Doxygen."
OFF

View File

@ -1,6 +1,6 @@
Open Asset Import Library (assimp)
==================================
### Current build status ###
[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
<a href="https://scan.coverity.com/projects/5607">
@ -9,22 +9,19 @@ Open Asset Import Library (assimp)
</a>
<span class="badge-patreon"><a href="https://www.patreon.com/assimp" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<br>
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
This is the development trunk containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories.
The current build status is:
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
Gitter chat: [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
And we also have an IRC-channel at freenode: #assetimporterlib . You can easily join us via: [KiwiIRC/freenote](https://kiwiirc.com/client/irc.freenode.net), choose your nickname and type
> /join #assetimporterlib
One-off donations via PayPal:
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
<br>
__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
@ -100,6 +97,9 @@ Take a look into the `INSTALL` file. Our build system is CMake, if you used CMak
* [Pascal](port/AssimpPascal/Readme.md)
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
### Other tools ###
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
#### Repository structure ####
Open Asset Import Library is implemented in C++. The directory structure is:

View File

@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "3DSExporter.h"
#include "3DSLoader.h"
#include "3DSHelper.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "SplitLargeMeshes.h"
#include "StringComparison.h"
#include <assimp/IOSystem.hpp>

View File

@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter.hpp"
// Header files, Assimp.
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "StandardShapes.h"
#include "StringUtils.h"

View File

@ -46,6 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// internal headers
#include "ASELoader.h"
#include "StringComparison.h"
@ -1320,4 +1322,6 @@ bool ASEImporter::GenerateNormals(ASE::Mesh& mesh) {
return false;
}
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER

View File

@ -53,6 +53,7 @@ struct aiNode;
namespace Assimp {
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// --------------------------------------------------------------------------------
/** Importer class for the 3DS ASE ASCII format.
@ -63,9 +64,6 @@ public:
ASEImporter();
~ASEImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
@ -201,6 +199,9 @@ protected:
bool noSkeletonMesh;
};
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
} // end of namespace Assimp
#endif // AI_3DSIMPORTER_H_INC

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// internal headers
#include "TextureTransform.h"
@ -2151,4 +2152,6 @@ void Parser::ParseLV4MeshLong(unsigned int& iOut)
iOut = strtoul10(filePtr,&filePtr);
}
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER

View File

@ -49,6 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/mesh.h>
#include <assimp/anim.h>
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// for some helper routines like IsSpace()
#include "ParsingUtils.h"
#include "qnan.h"
@ -662,4 +664,6 @@ public:
} // Namespace ASE
} // Namespace ASSIMP
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // !! include guard

View File

@ -325,10 +325,13 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
{
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );
size_t nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
Write<aiString>(&chunk,node->mName);
Write<aiMatrix4x4>(&chunk,node->mTransformation);
Write<unsigned int>(&chunk,node->mNumChildren);
Write<unsigned int>(&chunk,node->mNumMeshes);
Write<unsigned int>(&chunk,nb_metadata);
for (unsigned int i = 0; i < node->mNumMeshes;++i) {
Write<unsigned int>(&chunk,node->mMeshes[i]);
@ -337,6 +340,39 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
for (unsigned int i = 0; i < node->mNumChildren;++i) {
WriteBinaryNode( &chunk, node->mChildren[i] );
}
for (unsigned int i = 0; i < nb_metadata; ++i) {
const aiString& key = node->mMetaData->mKeys[i];
aiMetadataType type = node->mMetaData->mValues[i].mType;
void* value = node->mMetaData->mValues[i].mData;
Write<aiString>(&chunk, key);
Write<uint16_t>(&chunk, type);
switch (type) {
case AI_BOOL:
Write<bool>(&chunk, *((bool*) value));
break;
case AI_INT32:
Write<int32_t>(&chunk, *((int32_t*) value));
break;
case AI_UINT64:
Write<uint64_t>(&chunk, *((uint64_t*) value));
break;
case AI_FLOAT:
Write<float>(&chunk, *((float*) value));
break;
case AI_DOUBLE:
Write<double>(&chunk, *((double*) value));
break;
case AI_AISTRING:
Write<aiString>(&chunk, *((aiString*) value));
break;
case AI_AIVECTOR3D:
Write<aiVector3D>(&chunk, *((aiVector3D*) value));
break;
}
}
}
// -----------------------------------------------------------------------------------

View File

@ -210,6 +210,8 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
(*node)->mTransformation = Read<aiMatrix4x4>(stream);
(*node)->mNumChildren = Read<unsigned int>(stream);
(*node)->mNumMeshes = Read<unsigned int>(stream);
unsigned int nb_metadata = Read<unsigned int>(stream);
if(parent)
{
(*node)->mParent = parent;
@ -231,6 +233,41 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
}
}
if (nb_metadata)
{
(*node)->mMetaData = aiMetadata::Alloc(nb_metadata);
for (unsigned int i = 0; i < nb_metadata; ++i) {
(*node)->mMetaData->mKeys[i] = Read<aiString>(stream);
(*node)->mMetaData->mValues[i].mType = (aiMetadataType) Read<uint16_t>(stream);
void* data = NULL;
switch ((*node)->mMetaData->mValues[i].mType) {
case AI_BOOL:
data = new bool(Read<bool>(stream));
break;
case AI_INT32:
data = new int32_t(Read<int32_t>(stream));
break;
case AI_UINT64:
data = new uint64_t(Read<uint64_t>(stream));
break;
case AI_FLOAT:
data = new float(Read<float>(stream));
break;
case AI_DOUBLE:
data = new double(Read<double>(stream));
break;
case AI_AISTRING:
data = new aiString(Read<aiString>(stream));
break;
case AI_AIVECTOR3D:
data = new aiVector3D(Read<aiVector3D>(stream));
break;
}
(*node)->mMetaData->mValues[i].mData = data;
}
}
}
// -----------------------------------------------------------------------------------

View File

@ -45,8 +45,9 @@ Assimp C export interface. See Exporter.cpp for some notes.
*/
#ifndef ASSIMP_BUILD_NO_EXPORT
#include "CInterfaceIOWrapper.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "ScenePrivate.h"
#include <assimp/Exporter.hpp>

View File

@ -337,7 +337,6 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
DefaultLogger::get()->debug("Found UTF-32 BOM ...");
const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
std::vector<char> output;
int *ptr = (int*)&data[ 0 ];
int *end = ptr + ( data.size() / sizeof(int) ) +1;
@ -358,11 +357,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
if(*((uint16_t*)&data.front()) == 0xFEFF) {
DefaultLogger::get()->debug("Found UTF-16 BOM ...");
const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
std::vector<unsigned char> output;
int16_t *ptr = (int16_t*) &data[ 0 ];
int16_t *end = ptr + (data.size() / sizeof(int)) + 1;
utf8::utf16to8(data.begin(), data.end(), back_inserter(output));
return;
}

View File

@ -253,10 +253,7 @@ public:
* a compiler complain is the result.
* @param dest Destination value to be written
* @param db File database, including input stream. */
template <typename T> inline void Convert (T& dest,
const FileDatabase& db) const;
template <typename T> inline void Convert (T& dest, const FileDatabase& db) const;
// --------------------------------------------------------
// generic converter

View File

@ -43,10 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of some blender modifiers (i.e subdivision, mirror).
*/
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
#include "BlenderModifier.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "Subdivision.h"
#include <assimp/scene.h>
#include <memory>
@ -266,7 +266,7 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
std::bind1st(std::plus< unsigned int >(),out.mNumMeshes));
[&out](unsigned int n) { return out.mNumMeshes + n; });
delete[] out.mMeshes;
out.mMeshes = nind;

View File

@ -96,6 +96,7 @@ SET( PUBLIC_HEADERS
${HEADER_PATH}/Exporter.hpp
${HEADER_PATH}/DefaultIOStream.h
${HEADER_PATH}/DefaultIOSystem.h
${HEADER_PATH}/SceneCombiner.h
)
SET( Core_SRCS
@ -148,7 +149,6 @@ SET( Common_SRCS
SpatialSort.cpp
SpatialSort.h
SceneCombiner.cpp
SceneCombiner.h
ScenePreprocessor.cpp
ScenePreprocessor.h
SkeletonMeshBuilder.cpp
@ -647,6 +647,9 @@ ADD_ASSIMP_IMPORTER(X3D
X3DImporter_Rendering.cpp
X3DImporter_Shape.cpp
X3DImporter_Texturing.cpp
FIReader.hpp
FIReader.cpp
X3DVocabulary.cpp
)
ADD_ASSIMP_IMPORTER( GLTF
@ -732,10 +735,12 @@ SET ( openddl_parser_SRCS
../contrib/openddlparser/code/OpenDDLCommon.cpp
../contrib/openddlparser/code/OpenDDLExport.cpp
../contrib/openddlparser/code/Value.cpp
../contrib/openddlparser/code/OpenDDLStream.cpp
../contrib/openddlparser/include/openddlparser/OpenDDLParser.h
../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
../contrib/openddlparser/include/openddlparser/OpenDDLExport.h
../contrib/openddlparser/include/openddlparser/OpenDDLStream.h
../contrib/openddlparser/include/openddlparser/DDLNode.h
../contrib/openddlparser/include/openddlparser/Value.h
)

View File

@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ColladaExporter.h"
#include "Bitmap.h"
#include "fast_atof.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "StringUtils.h"
#include "XMLTools.h"
#include <assimp/DefaultIOSystem.h>

View File

@ -132,7 +132,6 @@ void ColladaLoader::SetupProperties(const Importer* pImp)
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION,0) != 0;
}
// ------------------------------------------------------------------------------------------------
// Get file extension list
const aiImporterDesc* ColladaLoader::GetInfo () const
@ -1904,14 +1903,13 @@ const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, c
}
// ------------------------------------------------------------------------------------------------
// Finds a proper name for a node derived from the collada-node's properties
// Finds a proper unique name for a node derived from the collada-node's properties.
// The name must be unique for proper node-bone association.
std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode)
{
// now setup the name of the node. We take the name if not empty, otherwise the collada ID
// FIX: Workaround for XSI calling the instanced visual scene 'untitled' by default.
if (!pNode->mName.empty() && pNode->mName != "untitled")
return pNode->mName;
else if (!pNode->mID.empty())
// Now setup the name of the assimp node. The collada name might not be
// unique, so we use the collada ID.
if (!pNode->mID.empty())
return pNode->mID;
else if (!pNode->mSID.empty())
return pNode->mSID;

View File

@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the Collada parser helper
*/
#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
#include <sstream>
@ -1866,7 +1865,7 @@ void ColladaParser::ReadMesh( Mesh* pMesh)
ReadIndexData( pMesh);
} else
{
// ignore the rest
// ignore the restf
SkipElement();
}
}
@ -2216,8 +2215,9 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
else if (IsElement("extra"))
{
SkipElement("extra");
} else
{
} else if ( IsElement("ph")) {
SkipElement("ph");
} else {
ThrowException( format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <" << elementName << ">" );
}
}

View File

@ -54,7 +54,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
#ifndef ASSIMP_BUILD_NO_EXPORT
#include "BlobIOSystem.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "BaseProcess.h"
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
@ -172,8 +172,10 @@ public:
GetPostProcessingStepInstanceList(mPostProcessingSteps);
// grab all built-in exporters
mExporters.resize(ASSIMP_NUM_EXPORTERS);
std::copy(gExporters,gExporters+ASSIMP_NUM_EXPORTERS,mExporters.begin());
if ( 0 != ( ASSIMP_NUM_EXPORTERS ) ) {
mExporters.resize( ASSIMP_NUM_EXPORTERS );
std::copy( gExporters, gExporters + ASSIMP_NUM_EXPORTERS, mExporters.begin() );
}
}
~ExporterPimpl()
@ -187,7 +189,6 @@ public:
}
public:
aiExportDataBlob* blob;
std::shared_ptr< Assimp::IOSystem > mIOSystem;
bool mIsDefaultIOHandler;
@ -408,6 +409,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
ASSIMP_END_EXCEPTION_REGION(aiReturn);
return AI_FAILURE;
}
@ -492,7 +494,6 @@ ExportProperties::ExportProperties(const ExportProperties &other)
// empty
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
bool ExportProperties::SetPropertyInteger(const char* szName, int iValue) {

View File

@ -161,8 +161,7 @@ uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
}
// ------------------------------------------------------------------------------------------------
uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
{
uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end) {
const size_t k_to_read = sizeof(uint64_t);
if(Offset(cursor, end) < k_to_read) {
TokenizeError("cannot ReadDoubleWord, out of bounds",input, cursor);
@ -176,7 +175,6 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
return dword;
}
// ------------------------------------------------------------------------------------------------
uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
{
@ -447,8 +445,9 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
const uint32_t flags = ReadWord(input, cursor, input + length);
const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused
(void) padding_0;
const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused
(void) padding_1;
while (cursor < input + length)
{
if(!ReadScope(output_tokens, input, cursor, input + length, flags)) {

View File

@ -436,6 +436,19 @@ private:
aiScene* const out;
const FBX::Document& doc;
bool FindTextureIndexByFilename(const Video& video, unsigned int& index) {
index = 0;
const char* videoFileName = video.FileName().c_str();
for (auto texture = textures_converted.begin(); texture != textures_converted.end(); ++texture)
{
if (!strcmp(texture->first->FileName().c_str(), videoFileName)) {
return true;
}
index++;
}
return false;
}
};
Converter::Converter( aiScene* out, const Document& doc )
@ -1749,7 +1762,7 @@ unsigned int Converter::ConvertVideo( const Video& video )
out_tex->mWidth = static_cast<unsigned int>( video.ContentLength() ); // total data size
out_tex->mHeight = 0; // fixed to 0
// steal the data from the Video to avoid an additional copy
// steal the data from the Video to avoid an additional copy
out_tex->pcData = reinterpret_cast<aiTexel*>( const_cast<Video&>( video ).RelinquishContent() );
// try to extract a hint from the file extension
@ -1783,22 +1796,32 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
path.Set( tex->RelativeFilename() );
const Video* media = tex->Media();
if ( media != 0 && media->ContentLength() > 0 ) {
unsigned int index;
if (media != 0) {
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
unsigned int index;
VideoMap::const_iterator it = textures_converted.find( media );
if ( it != textures_converted.end() ) {
index = ( *it ).second;
}
else {
index = ConvertVideo( *media );
textures_converted[ media ] = index;
}
VideoMap::const_iterator it = textures_converted.find(media);
if (it != textures_converted.end()) {
index = (*it).second;
textureReady = true;
}
else {
if (media->ContentLength() > 0) {
index = ConvertVideo(*media);
textures_converted[media] = index;
textureReady = true;
}
else if (doc.Settings().searchEmbeddedTextures) { //try to find the texture on the already-loaded textures by the filename, if the flag is on
textureReady = FindTextureIndexByFilename(*media, index);
}
}
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
path.data[ 0 ] = '*';
path.length = 1 + ASSIMP_itoa10( path.data + 1, MAXLEN - 1, index );
}
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
if (textureReady) {
path.data[0] = '*';
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
}
}
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );

View File

@ -565,7 +565,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id,
temp.push_back((*it).second);
}
std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare));
std::sort(temp.begin(), temp.end(), std::mem_fn(&Connection::Compare));
return temp; // NRVO should handle this
}
@ -617,7 +617,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
temp.push_back((*it).second);
}
std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare));
std::sort(temp.begin(), temp.end(), std::mem_fn(&Connection::Compare));
return temp; // NRVO should handle this
}

View File

@ -63,6 +63,7 @@ struct ImportSettings
, readWeights(true)
, preservePivots(true)
, optimizeEmptyAnimationCurves(true)
, searchEmbeddedTextures(false)
{}
@ -137,6 +138,10 @@ struct ImportSettings
* values matching the corresponding node transformation.
* The default value is true. */
bool optimizeEmptyAnimationCurves;
/** search for embedded loaded textures, where no embedded texture data is provided.
* The default value is false. */
bool searchEmbeddedTextures;
};

View File

@ -131,6 +131,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false);
}
// ------------------------------------------------------------------------------------------------

View File

@ -281,7 +281,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
const Scope& sc = GetRequiredScope(element);
const Element* const Type = sc["Type"];
const Element* const FileName = sc["FileName"];
const Element* const FileName = sc.FindElementCaseInsensitive("FileName"); //some files retain the information as "Filename", others "FileName", who knows
const Element* const RelativeFilename = sc["RelativeFilename"];
const Element* const Content = sc["Content"];
@ -291,35 +291,40 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
if(FileName) {
fileName = ParseTokenAsString(GetRequiredToken(*FileName,0));
}
}
if(RelativeFilename) {
relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0));
}
if(Content) {
const Token& token = GetRequiredToken(*Content, 0);
const char* data = token.begin();
if(!token.IsBinary()) {
DOMWarning("video content is not binary data, ignoring", &element);
}
else if(static_cast<size_t>(token.end() - data) < 5) {
DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
}
else if(*data != 'R') {
DOMWarning("video content is not raw binary data, ignoring", &element);
}
else {
// read number of elements
uint32_t len = 0;
::memcpy(&len, data + 1, sizeof(len));
AI_SWAP4(len);
//this field is ommited when the embedded texture is already loaded, let's ignore if it´s not found
try {
const Token& token = GetRequiredToken(*Content, 0);
const char* data = token.begin();
if (!token.IsBinary()) {
DOMWarning("video content is not binary data, ignoring", &element);
}
else if (static_cast<size_t>(token.end() - data) < 5) {
DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
}
else if (*data != 'R') {
DOMWarning("video content is not raw binary data, ignoring", &element);
}
else {
// read number of elements
uint32_t len = 0;
::memcpy(&len, data + 1, sizeof(len));
AI_SWAP4(len);
contentLength = len;
contentLength = len;
content = new uint8_t[len];
::memcpy(content, data + 5, len);
}
content = new uint8_t[len];
::memcpy(content, data + 5, len);
}
} catch (runtime_error runtimeError) {
//we don´t need the content data for contents that has already been loaded
}
}
props = GetPropertyTable(doc,"Video.FbxVideo",element,sc);

View File

@ -357,7 +357,7 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
// avoids losing the material if there are more material layers
// coming of which at least one contains actual data (did observe
// that with one test file).
const size_t count_neg = std::count_if(temp_materials.begin(),temp_materials.end(),std::bind2nd(std::less<int>(),0));
const size_t count_neg = std::count_if(temp_materials.begin(),temp_materials.end(),[](int n) { return n < 0; });
if(count_neg == temp_materials.size()) {
FBXImporter::LogWarn("ignoring dummy material layer (all entries -1)");
return;

View File

@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map>
#include <memory>
#include "LogAux.h"
#include "fast_atof.h"
#include "FBXCompileConfig.h"
#include "FBXTokenizer.h"
@ -137,6 +138,17 @@ public:
return it == elements.end() ? NULL : (*it).second;
}
const Element* FindElementCaseInsensitive(const std::string& elementName) const {
const char* elementNameCStr = elementName.c_str();
for (auto element = elements.begin(); element != elements.end(); ++element)
{
if (!ASSIMP_strincmp(element->first.c_str(), elementNameCStr, MAXLEN)) {
return element->second;
}
}
return NULL;
}
ElementCollection GetCollection(const std::string& index) const {
return elements.equal_range(index);
}

1818
code/FIReader.cpp 100755

File diff suppressed because it is too large Load Diff

172
code/FIReader.hpp 100644
View File

@ -0,0 +1,172 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2017, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/// \file FIReader.hpp
/// \brief Reader for Fast Infoset encoded binary XML files.
/// \date 2017
/// \author Patrick Daehne
#ifndef INCLUDED_AI_FI_READER_H
#define INCLUDED_AI_FI_READER_H
#include <irrXML.h>
#include <memory>
#include <string>
#include <vector>
#include <cstdint>
namespace Assimp {
struct FIValue {
virtual const std::string &toString() const = 0;
};
struct FIStringValue: public FIValue {
std::string value;
static std::shared_ptr<FIStringValue> create(std::string &&value);
};
struct FIByteValue: public FIValue {
std::vector<uint8_t> value;
};
struct FIHexValue: public FIByteValue {
static std::shared_ptr<FIHexValue> create(std::vector<uint8_t> &&value);
};
struct FIBase64Value: public FIByteValue {
static std::shared_ptr<FIBase64Value> create(std::vector<uint8_t> &&value);
};
struct FIShortValue: public FIValue {
std::vector<int16_t> value;
static std::shared_ptr<FIShortValue> create(std::vector<int16_t> &&value);
};
struct FIIntValue: public FIValue {
std::vector<int32_t> value;
static std::shared_ptr<FIIntValue> create(std::vector<int32_t> &&value);
};
struct FILongValue: public FIValue {
std::vector<int64_t> value;
static std::shared_ptr<FILongValue> create(std::vector<int64_t> &&value);
};
struct FIBoolValue: public FIValue {
std::vector<bool> value;
static std::shared_ptr<FIBoolValue> create(std::vector<bool> &&value);
};
struct FIFloatValue: public FIValue {
std::vector<float> value;
static std::shared_ptr<FIFloatValue> create(std::vector<float> &&value);
};
struct FIDoubleValue: public FIValue {
std::vector<double> value;
static std::shared_ptr<FIDoubleValue> create(std::vector<double> &&value);
};
struct FIUUIDValue: public FIByteValue {
static std::shared_ptr<FIUUIDValue> create(std::vector<uint8_t> &&value);
};
struct FICDATAValue: public FIStringValue {
static std::shared_ptr<FICDATAValue> create(std::string &&value);
};
struct FIDecoder {
virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) = 0;
};
struct FIQName {
const char *name;
const char *prefix;
const char *uri;
};
struct FIVocabulary {
const char **restrictedAlphabetTable;
size_t restrictedAlphabetTableSize;
const char **encodingAlgorithmTable;
size_t encodingAlgorithmTableSize;
const char **prefixTable;
size_t prefixTableSize;
const char **namespaceNameTable;
size_t namespaceNameTableSize;
const char **localNameTable;
size_t localNameTableSize;
const char **otherNCNameTable;
size_t otherNCNameTableSize;
const char **otherURITable;
size_t otherURITableSize;
const std::shared_ptr<const FIValue> *attributeValueTable;
size_t attributeValueTableSize;
const std::shared_ptr<const FIValue> *charactersTable;
size_t charactersTableSize;
const std::shared_ptr<const FIValue> *otherStringTable;
size_t otherStringTableSize;
const FIQName *elementNameTable;
size_t elementNameTableSize;
const FIQName *attributeNameTable;
size_t attributeNameTableSize;
};
class IOStream;
class FIReader: public irr::io::IIrrXMLReader<char, irr::io::IXMLBase> {
public:
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const = 0;
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char *name) const = 0;
virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr<FIDecoder> decoder) = 0;
virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) = 0;
static std::unique_ptr<FIReader> create(IOStream *stream);
};// class IFIReader
}// namespace Assimp
#endif // INCLUDED_AI_FI_READER_H

View File

@ -66,8 +66,7 @@ namespace MDL {
* \brief Data structure for the HL2 main header
*/
// ---------------------------------------------------------------------------
struct Header_HL2
{
struct Header_HL2 {
//! magic number: "IDST"/"IDSQ"
char ident[4];
@ -139,7 +138,7 @@ struct Header_HL2
//! Number of animation transitions
int32_t numtransitions;
int32_t transitionindex;
} PACK_STRUCT;
} /* PACK_STRUCT */;
#include "./../include/assimp/Compiler/poppack1.h"

View File

@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "fast_atof.h"
#include "GenericProperty.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "StandardShapes.h"
#include "Importer.h"

View File

@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_IRRLOADER_H_INCLUDED
#include "IRRShared.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "Importer.h"
#include "StringUtils.h"
#include <assimp/anim.h>

View File

@ -231,7 +231,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
out.push_back( new MDLImporter());
#endif
#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER)
#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
out.push_back( new ASEImporter());
# endif
#endif
#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER)
out.push_back( new HMPImporter());

View File

@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers
#include "LWOFileData.h"
#include <assimp/anim.h>
using namespace Assimp;
using namespace Assimp::LWO;
@ -163,7 +164,7 @@ void AnimResolver::UpdateAnimRangeSetup()
{
const double start_time = delta - std::fmod(my_first-first,delta);
std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(),(*it).keys.end(),
std::bind1st(std::greater<double>(),start_time)),m;
[start_time](double t) { return start_time > t; }),m;
size_t ofs = 0;
if (n != (*it).keys.end()) {

View File

@ -48,11 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_LWO_ANIMATION_INCLUDED
#define AI_LWO_ANIMATION_INCLUDED
#include <assimp/anim.h>
//
#include <vector>
#include <list>
struct aiNodeAnim;
struct aiVectorKey;
namespace Assimp {
namespace LWO {
@ -166,7 +167,6 @@ struct Envelope
//! Keyframes for this envelope
std::vector<Key> keys;
// temporary data for AnimResolver
size_t old_first,old_last;
};
@ -198,8 +198,7 @@ public:
* @param Output tick rate, per second
* @note The input envelopes are possibly modified.
*/
AnimResolver(std::list<Envelope>& envelopes,
double tick);
AnimResolver(std::list<Envelope>& envelopes, double tick);
public:

View File

@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ParsingUtils.h"
#include "fast_atof.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "GenericProperty.h"
#include "SkeletonMeshBuilder.h"
#include "ConvertToLHProcess.h"

View File

@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_LWSLOADER_H_INCLUDED
#include "LWOFileData.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "BaseImporter.h"
struct aiImporterDesc;

View File

@ -142,14 +142,14 @@ struct Frame
//! name of frame
char name[ AI_MD3_MAXFRAME ];
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------
/** @brief Data structure for the tag header
/**
* @brief Data structure for the tag header
*/
struct Tag
{
struct Tag {
//! name of the tag
char NAME[ AI_MD3_MAXQPATH ];
@ -157,14 +157,13 @@ struct Tag
aiVector3D origin;
ai_real orientation[3][3];
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------
/** @brief Data structure for the surface header
*/
struct Surface
{
struct Surface {
//! magic number
int32_t IDENT;
@ -186,7 +185,6 @@ struct Surface
//! number of triangles in the surface
uint32_t NUM_TRIANGLES;
//! offset to the triangle data
uint32_t OFS_TRIANGLES;
@ -201,19 +199,18 @@ struct Surface
//! offset to the end of the Surface object
int32_t OFS_END;
} PACK_STRUCT;
} /*PACK_STRUCT*/;
// -------------------------------------------------------------------------------
/** @brief Data structure for a shader defined in there
*/
struct Shader
{
struct Shader {
//! filename of the shader
char NAME[ AI_MD3_MAXQPATH ];
//! index of the shader
uint32_t SHADER_INDEX;
} PACK_STRUCT;
} /*PACK_STRUCT*/;
// -------------------------------------------------------------------------------
@ -223,7 +220,7 @@ struct Triangle
{
//! triangle indices
uint32_t INDEXES[3];
} PACK_STRUCT;
} /*PACK_STRUCT*/;
// -------------------------------------------------------------------------------
@ -233,7 +230,7 @@ struct TexCoord
{
//! UV coordinates
ai_real U,V;
} PACK_STRUCT;
} /*PACK_STRUCT*/;
// -------------------------------------------------------------------------------
@ -246,7 +243,7 @@ struct Vertex
//! encoded normal vector
uint16_t NORMAL;
} PACK_STRUCT;
} /*PACK_STRUCT*/;
#include "./../include/assimp/Compiler/poppack1.h"

View File

@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
#include "MD3Loader.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "GenericProperty.h"
#include "RemoveComments.h"
#include "ParsingUtils.h"

View File

@ -157,7 +157,7 @@ struct Frame
//! Name of the frame
char name [ 16 ] ;
} PACK_STRUCT;
} /*PACK_STRUCT*/;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC triangle

View File

@ -53,10 +53,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MDLFILEHELPER_H_INC
#define AI_MDLFILEHELPER_H_INC
#include <assimp/anim.h>
#include <assimp/mesh.h>
#include <assimp/Compiler/pushpack1.h>
#include "ByteSwapper.h"
#include "./../include/assimp/anim.h"
#include "./../include/assimp/mesh.h"
#include "./../include/assimp/Compiler/pushpack1.h"
#include <stdint.h>
#include <vector>
@ -90,7 +90,6 @@ namespace MDL {
#define AI_MDL_MAGIC_NUMBER_BE_GS7 AI_MAKE_MAGIC("MDL7")
#define AI_MDL_MAGIC_NUMBER_LE_GS7 AI_MAKE_MAGIC("7LDM")
// common limitations for Quake1 meshes. The loader does not check them,
// (however it warns) but models should not exceed these limits.
#if (!defined AI_MDL_VERSION)
@ -119,8 +118,7 @@ namespace MDL {
/** \struct Header
* \brief Data structure for the MDL main header
*/
struct Header
{
struct Header {
//! magic number: "IDPO"
uint32_t ident;
@ -166,15 +164,14 @@ struct Header
//! Could be the total size of the file (and not a float)
float size;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct Header_MDL7
* \brief Data structure for the MDL 7 main header
*/
struct Header_MDL7
{
struct Header_MDL7 {
//! magic number: "MDL7"
char ident[4];
@ -226,15 +223,14 @@ struct Header_MDL7
//! Size of the Frame_MDL7 data structure used in the file
uint16_t frame_stc_size;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct Bone_MDL7
* \brief Data structure for a bone in a MDL7 file
*/
struct Bone_MDL7
{
struct Bone_MDL7 {
//! Index of the parent bone of *this* bone. 0xffff means:
//! "hey, I have no parent, I'm an orphan"
uint16_t parent_index;
@ -246,7 +242,7 @@ struct Bone_MDL7
//! Optional name of the bone
char name[1 /* DUMMY SIZE */];
} PACK_STRUCT;
} /* PACK_STRUCT */;
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
@ -268,8 +264,7 @@ struct Bone_MDL7
/** \struct Group_MDL7
* \brief Group in a MDL7 file
*/
struct Group_MDL7
{
struct Group_MDL7 {
//! = '1' -> triangle based Mesh
unsigned char typ;
@ -295,7 +290,7 @@ struct Group_MDL7
//! Number of frames
int32_t numframes;
} PACK_STRUCT;
} /* PACK_STRUCT */;
#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
#define AI_MDL7_SKINTYPE_MATERIAL 0x10
@ -310,41 +305,36 @@ struct Group_MDL7
/** \struct Deformer_MDL7
* \brief Deformer in a MDL7 file
*/
struct Deformer_MDL7
{
struct Deformer_MDL7 {
int8_t deformer_version; // 0
int8_t deformer_typ; // 0 - bones
int8_t _unused_[2];
int32_t group_index;
int32_t elements;
int32_t deformerdata_size;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct DeformerElement_MDL7
* \brief Deformer element in a MDL7 file
*/
struct DeformerElement_MDL7
{
struct DeformerElement_MDL7 {
//! bei deformer_typ==0 (==bones) element_index == bone index
int32_t element_index;
char element_name[AI_MDL7_MAX_BONENAMESIZE];
int32_t weights;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct DeformerWeight_MDL7
* \brief Deformer weight in a MDL7 file
*/
struct DeformerWeight_MDL7
{
struct DeformerWeight_MDL7 {
//! for deformer_typ==0 (==bones) index == vertex index
int32_t index;
float weight;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// don't know why this was in the original headers ...
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
@ -353,17 +343,15 @@ typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
/** \struct ColorValue_MDL7
* \brief Data structure for a color value in a MDL7 file
*/
struct ColorValue_MDL7
{
struct ColorValue_MDL7 {
float r,g,b,a;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct Material_MDL7
* \brief Data structure for a Material in a MDL7 file
*/
struct Material_MDL7
{
struct Material_MDL7 {
//! Diffuse base color of the material
ColorValue_MDL7 Diffuse;
@ -378,15 +366,13 @@ struct Material_MDL7
//! Phong power
float Power;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct Skin
* \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
*/
struct Skin
{
struct Skin {
//! 0 = single (Skin), 1 = group (GroupSkin)
//! For MDL3-5: Defines the type of the skin and there
//! fore the size of the data to skip:
@ -402,7 +388,7 @@ struct Skin
//! Texture data
uint8_t *data;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
@ -410,11 +396,10 @@ struct Skin
* \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
* \see Skin
*/
struct Skin_MDL5
{
struct Skin_MDL5 {
int32_t size, width, height;
uint8_t *data;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// maximum length of texture file name
#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
@ -425,44 +410,40 @@ struct Skin_MDL5
/** \struct Skin_MDL7
* \brief Skin data structure #3 - used by MDL7 and HMP7
*/
struct Skin_MDL7
{
struct Skin_MDL7 {
uint8_t typ;
int8_t _unused_[3];
int32_t width;
int32_t height;
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct RGB565
* \brief Data structure for a RGB565 pixel in a texture
*/
struct RGB565
{
struct RGB565 {
uint16_t r : 5;
uint16_t g : 6;
uint16_t b : 5;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct ARGB4
* \brief Data structure for a ARGB4444 pixel in a texture
*/
struct ARGB4
{
struct ARGB4 {
uint16_t a : 4;
uint16_t r : 4;
uint16_t g : 4;
uint16_t b : 4;
} PACK_STRUCT;
} /*PACK_STRUCT*/;
// -------------------------------------------------------------------------------------
/** \struct GroupSkin
* \brief Skin data structure #2 (group of pictures)
*/
struct GroupSkin
{
struct GroupSkin {
//! 0 = single (Skin), 1 = group (GroupSkin)
int32_t group;
@ -474,14 +455,13 @@ struct GroupSkin
//! Data of each image
uint8_t **data;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct TexCoord
* \brief Texture coordinate data structure used by the Quake1 MDL format
*/
struct TexCoord
{
struct TexCoord {
//! Is the vertex on the noundary between front and back piece?
int32_t onseam;
@ -490,33 +470,31 @@ struct TexCoord
//! Texture coordinate in the ty direction
int32_t t;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct TexCoord_MDL3
* \brief Data structure for an UV coordinate in the 3DGS MDL3 format
*/
struct TexCoord_MDL3
{
struct TexCoord_MDL3 {
//! position, horizontally in range 0..skinwidth-1
int16_t u;
//! position, vertically in range 0..skinheight-1
int16_t v;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct TexCoord_MDL7
* \brief Data structure for an UV coordinate in the 3DGS MDL7 format
*/
struct TexCoord_MDL7
{
struct TexCoord_MDL7 {
//! position, horizontally in range 0..1
float u;
//! position, vertically in range 0..1
float v;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct SkinSet_MDL7
@ -532,7 +510,7 @@ struct SkinSet_MDL7
//! Material index
int32_t material; // size 4
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct Triangle
@ -545,7 +523,7 @@ struct Triangle
//! Vertex indices
int32_t vertex[3];
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct Triangle_MDL3
@ -558,7 +536,7 @@ struct Triangle_MDL3
//! Index of 3 skin vertices in range 0..numskinverts
uint16_t index_uv[3];
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct Triangle_MDL7
@ -571,7 +549,7 @@ struct Triangle_MDL7
//! Two skinsets. The second will be used for multi-texturing
SkinSet_MDL7 skinsets[2];
} PACK_STRUCT;
} /* PACK_STRUCT */;
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
@ -599,7 +577,7 @@ struct Vertex
{
uint8_t v[3];
uint8_t normalIndex;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
@ -625,8 +603,7 @@ struct Vertex_MDL7
uint8_t norm162index;
float norm[3];
};
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct BoneTransform_MDL7
@ -643,12 +620,11 @@ struct BoneTransform_MDL7
//! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
//! THIS STUPID FILE FORMAT!
int8_t _unused_[2];
} PACK_STRUCT;
} /* PACK_STRUCT */;
#define AI_MDL7_MAX_FRAMENAMESIZE 16
// -------------------------------------------------------------------------------------
/** \struct Frame_MDL7
* \brief Frame data structure used by MDL7 files
@ -678,7 +654,7 @@ struct SimpleFrame
//! Vertex list of the frame
Vertex *verts;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct Frame
@ -691,7 +667,7 @@ struct Frame
//! Frame data
SimpleFrame frame;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
@ -708,7 +684,7 @@ struct SimpleFrame_MDLn_SP
//! Vertex list of the frame
Vertex_MDL4 *verts;
} PACK_STRUCT;
} /* PACK_STRUCT */;
// -------------------------------------------------------------------------------------
/** \struct GroupFrame
@ -730,7 +706,7 @@ struct GroupFrame
//! List of single frames
SimpleFrame *frames;
} PACK_STRUCT;
} /* PACK_STRUCT */;
#include "./../include/assimp/Compiler/poppack1.h"
@ -738,8 +714,7 @@ struct GroupFrame
/** \struct IntFace_MDL7
* \brief Internal data structure to temporarily represent a face
*/
struct IntFace_MDL7
{
struct IntFace_MDL7 {
// provide a constructor for our own convenience
IntFace_MDL7()
{

View File

@ -109,28 +109,6 @@ ObjFile::Model *ObjFileParser::GetModel() const {
return m_pModel;
}
/*void ignoreNewLines(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer)
{
auto curPosition = buffer.begin();
do
{
while (*curPosition!='\n'&&*curPosition!='\\')
{
++curPosition;
}
if (*curPosition=='\\')
{
std::vector<char> tempBuf;
do
{
streamBuffer.getNextDataLine(tempBuf, '\\' );
} while (tempBuf[0]=='\n');
*curPosition = ' ';
std::copy(tempBuf.cbegin(), tempBuf.cend(), ++curPosition);
}
} while (*curPosition!='\n');
}*/
void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
// only update every 100KB or it'll be too slow
//const unsigned int updateProgressEveryBytes = 100 * 1024;
@ -201,7 +179,18 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
case 'u': // Parse a material desc. setter
{
getMaterialDesc();
std::string name;
getNameNoSpace(m_DataIt, m_DataItEnd, name);
size_t nextSpace = name.find(" ");
if (nextSpace != std::string::npos)
name = name.substr(0, nextSpace);
if(name == "usemtl")
{
getMaterialDesc();
}
}
break;

View File

@ -91,11 +91,11 @@ static inline std::string &TrimLeft(std::string &s, bool newlines = true)
{
if (!newlines)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(Assimp::IsSpace<char>))));
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpace<char>(c); }));
}
else
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(Assimp::IsSpaceOrNewLine<char>))));
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpaceOrNewLine<char>(c); }));
}
return s;
}
@ -105,11 +105,11 @@ static inline std::string &TrimRight(std::string &s, bool newlines = true)
{
if (!newlines)
{
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(Assimp::IsSpace<char>))).base(),s.end());
s.erase(std::find_if(s.rbegin(), s.rend(), [](char c) { return !Assimp::IsSpace<char>(c); }).base(),s.end());
}
else
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(Assimp::IsSpaceOrNewLine<char>))));
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpaceOrNewLine<char>(c); }));
}
return s;
}

View File

@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "OptimizeGraph.h"
#include "ProcessHelper.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "Exceptional.h"
#include <stdio.h>

View File

@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "OptimizeMeshes.h"
#include "ProcessHelper.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "Exceptional.h"
using namespace Assimp;

View File

@ -159,6 +159,9 @@ void PLYImporter::InternReadFile(const std::string& pFile,
// Get the file-size
size_t fileSize = fileStream->FileSize();
if ( 0 == fileSize ) {
throw DeadlyImportError("File " + pFile + " is empty.");
}
IOStreamBuffer<char> streamedBuffer(1024 * 1024);
streamedBuffer.open(fileStream.get());

View File

@ -935,30 +935,6 @@ bool PLY::PropertyInstance::ParseValue(const char* &pCur,
ai_assert(NULL != out);
//calc element size
unsigned int lsize = 0;
switch (eType)
{
case EDT_Char:
case EDT_UChar:
lsize = 1;
break;
case EDT_UShort:
case EDT_Short:
lsize = 2;
break;
case EDT_UInt:
case EDT_Int:
case EDT_Float:
lsize = 4;
break;
case EDT_Double:
lsize = 8;
break;
}
bool ret = true;
switch (eType)
{
@ -990,6 +966,7 @@ bool PLY::PropertyInstance::ParseValue(const char* &pCur,
out->fDouble = (double)d;
break;
case EDT_INVALID:
default:
ret = false;
break;
@ -1032,6 +1009,10 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
case EDT_Double:
lsize = 8;
break;
case EDT_INVALID:
default:
break;
}
//read the next file block if needed

View File

@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "PretransformVertices.h"
#include "ProcessHelper.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "Exceptional.h"
using namespace Assimp;

View File

@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* OptimizeGraph step.
*/
// ----------------------------------------------------------------------------
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "StringUtils.h"
#include "fast_atof.h"
#include "Hash.h"

View File

@ -43,12 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
#include "StepExporter.h"
#include "ConvertToLHProcess.h"
#include "Bitmap.h"
#include "BaseImporter.h"
#include "fast_atof.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include <iostream>
#include <ctime>
#include <set>

View File

@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Subdivision.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include "SpatialSort.h"
#include "ProcessHelper.h"
#include "Vertex.h"

View File

@ -140,7 +140,7 @@ void X3DExporter::AttrHelper_Col3DArrToString(const aiColor3D* pArray, const siz
AttrHelper_CommaToPoint(pTargetString);
}
void X3DExporter::AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
void X3DExporter::AttrHelper_Color3ToAttrList(std::list<SAttribute>& pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
{
string tstr;
@ -150,7 +150,7 @@ string tstr;
pList.push_back({pName, tstr});
}
void X3DExporter::AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const string& pName, const float pValue, const float pDefaultValue)
void X3DExporter::AttrHelper_FloatToAttrList(std::list<SAttribute>& pList, const string& pName, const float pValue, const float pDefaultValue)
{
string tstr;

View File

@ -134,7 +134,7 @@ private:
/// \fn void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue)
/// \overload void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue);
void AttrHelper_FloatToAttrList(std::list<SAttribute> &pList, const std::string& pName, const float pValue, const float pDefaultValue);
/// \fn void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
/// Add attribute to list if value not equal to default.
@ -142,7 +142,7 @@ private:
/// \param [in] pName - name of new attribute.
/// \param [in] pValue - value of the new attribute.
/// \param [in] pDefaultValue - default value for checking: if pValue is equal to pDefaultValue then attribute will not be added.
void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue);
void AttrHelper_Color3ToAttrList(std::list<SAttribute> &pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue);
/// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
/// Begin new XML-node element.

View File

@ -52,10 +52,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Header files, Assimp.
#include <assimp/DefaultIOSystem.h>
#include "fast_atof.h"
#include "FIReader.hpp"
// Header files, stdlib.
#include <memory>
#include <string>
#include <iterator>
namespace Assimp {
@ -66,14 +68,53 @@ const aiImporterDesc X3DImporter::Description = {
"smalcom",
"",
"See documentation in source code. Chapter: Limitations.",
aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
0,
0,
0,
0,
"x3d"
"x3d x3db"
};
//const std::regex X3DImporter::pattern_nws(R"([^, \t\r\n]+)");
//const std::regex X3DImporter::pattern_true(R"(^\s*(?:true|1)\s*$)", std::regex::icase);
struct WordIterator: public std::iterator<std::input_iterator_tag, const char*> {
static const char *whitespace;
const char *start_, *end_;
WordIterator(const char *start, const char *end): start_(start), end_(end) {
start_ = start + strspn(start, whitespace);
if (start_ >= end_) {
start_ = 0;
}
}
WordIterator(): start_(0), end_(0) {}
WordIterator(const WordIterator &other): start_(other.start_), end_(other.end_) {}
WordIterator &operator=(const WordIterator &other) {
start_ = other.start_;
end_ = other.end_;
return *this;
}
bool operator==(WordIterator &other) const { return start_ == other.start_; }
bool operator!=(WordIterator &other) const { return start_ != other.start_; }
WordIterator &operator++() {
start_ += strcspn(start_, whitespace);
start_ += strspn(start_, whitespace);
if (start_ >= end_) {
start_ = 0;
}
return *this;
}
WordIterator operator++(int) {
WordIterator result(*this);
++(*this);
return result;
}
const char *operator*() const { return start_; }
};
const char *WordIterator::whitespace = ", \t\r\n";
X3DImporter::X3DImporter()
: NodeElement_Cur( nullptr )
, mReader( nullptr ) {
@ -81,7 +122,6 @@ X3DImporter::X3DImporter()
}
X3DImporter::~X3DImporter() {
delete mReader;
// Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
Clear();
}
@ -241,7 +281,7 @@ void X3DImporter::XML_CheckNode_MustBeEmpty()
void X3DImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
{
static const size_t Uns_Skip_Len = 190;
static const size_t Uns_Skip_Len = 192;
const char* Uns_Skip[ Uns_Skip_Len ] = {
// CAD geometry component
"CADAssembly", "CADFace", "CADLayer", "CADPart", "IndexedQuadSet", "QuadSet",
@ -276,7 +316,7 @@ void X3DImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeNa
// Navigation component
"Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup",
// Networking component
"Anchor", "LoadSensor",
"EXPORT", "IMPORT", "Anchor", "LoadSensor",
// NURBS component
"Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface",
"NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate",
@ -368,38 +408,65 @@ bool X3DImporter::XML_SearchNode(const std::string& pNodeName)
bool X3DImporter::XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
{
std::string val(mReader->getAttributeValue(pAttrIdx));
auto boolValue = std::dynamic_pointer_cast<const FIBoolValue>(mReader->getAttributeEncodedValue(pAttrIdx));
if (boolValue) {
if (boolValue->value.size() == 1) {
return boolValue->value.front();
}
throw DeadlyImportError("Invalid bool value");
}
else {
std::string val(mReader->getAttributeValue(pAttrIdx));
if(val == "false")
return false;
else if(val == "true")
return true;
else
throw DeadlyImportError("Bool attribute value can contain \"false\" or \"true\" not the \"" + val + "\"");
if(val == "false")
return false;
else if(val == "true")
return true;
else
throw DeadlyImportError("Bool attribute value can contain \"false\" or \"true\" not the \"" + val + "\"");
}
}
float X3DImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
{
std::string val;
float tvalf;
auto floatValue = std::dynamic_pointer_cast<const FIFloatValue>(mReader->getAttributeEncodedValue(pAttrIdx));
if (floatValue) {
if (floatValue->value.size() == 1) {
return floatValue->value.front();
}
throw DeadlyImportError("Invalid float value");
}
else {
std::string val;
float tvalf;
ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val);
fast_atoreal_move(val.c_str(), tvalf, false);
ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val);
fast_atoreal_move(val.c_str(), tvalf, false);
return tvalf;
return tvalf;
}
}
int32_t X3DImporter::XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx)
{
return strtol10(mReader->getAttributeValue(pAttrIdx));
auto intValue = std::dynamic_pointer_cast<const FIIntValue>(mReader->getAttributeEncodedValue(pAttrIdx));
if (intValue) {
if (intValue->value.size() == 1) {
return intValue->value.front();
}
throw DeadlyImportError("Invalid int value");
}
else {
return strtol10(mReader->getAttributeValue(pAttrIdx));
}
}
void X3DImporter::XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue)
{
std::list<float> tlist;
std::list<float>::iterator it;
std::vector<float> tlist;
std::vector<float>::iterator it;
XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);
XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);
if(tlist.size() != 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
it = tlist.begin();
@ -410,10 +477,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D&
void X3DImporter::XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue)
{
std::list<float> tlist;
std::list<float>::iterator it;
std::vector<float> tlist;
std::vector<float>::iterator it;
XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);
XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);
if(tlist.size() != 2) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
it = tlist.begin();
@ -423,10 +490,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D
void X3DImporter::XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue)
{
std::list<float> tlist;
std::list<float>::iterator it;
std::vector<float> tlist;
std::vector<float>::iterator it;
XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);
XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);
if(tlist.size() != 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
it = tlist.begin();
@ -435,181 +502,95 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D
pValue.z = *it;
}
void X3DImporter::XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list<bool>& pValue)
{
// make copy of attribute value - string with list of bool values. Also all bool values is strings.
size_t tok_str_len = strlen(mReader->getAttributeValue(pAttrIdx));
if ( 0 == tok_str_len ) {
Throw_IncorrectAttrValue( mReader->getAttributeName( pAttrIdx ) );
}
tok_str_len++;// take in account terminating '\0'.
char *tok_str = new char[tok_str_len];
strcpy(tok_str, mReader->getAttributeValue(pAttrIdx));
// change all spacebars to symbol '\0'. That is needed for parsing.
for(size_t i = 0; i < tok_str_len; i++)
{
if(tok_str[i] == ' ') tok_str[i] = 0;
}
// at now check what current token is
for(char *tok_cur = tok_str, *tok_end = (tok_str + tok_str_len); tok_cur < tok_end;)
{
if(strncmp(tok_cur, "true", 4) == 0)
{
pValue.push_back(true);
tok_cur += 5;// five, not four. Because '\0' must be skipped too.
}
else if(strncmp(tok_cur, "false", 5) == 0)
{
pValue.push_back(true);
tok_cur += 6;// six, not five. Because '\0' must be skipped too.
}
else
{
Throw_IncorrectAttrValue(mReader->getAttributeName(pAttrIdx));
}
}// for(char* tok_cur = tok_str, tok_end = (tok_str + tok_str_len); tok_cur < tok_end;)
// delete temporary string
delete [] tok_str;
}
void X3DImporter::XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector<bool>& pValue)
{
std::list<bool> tlist;
auto boolValue = std::dynamic_pointer_cast<const FIBoolValue>(mReader->getAttributeEncodedValue(pAttrIdx));
if (boolValue) {
pValue = boolValue->value;
}
else {
const char *val = mReader->getAttributeValue(pAttrIdx);
pValue.clear();
XML_ReadNode_GetAttrVal_AsListB(pAttrIdx, tlist);// read as list
// and copy to array
if(tlist.size() > 0)
{
pValue.reserve(tlist.size());
for(std::list<bool>::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it);
}
}
//std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws);
//const std::cregex_iterator wordItEnd;
//std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::regex_match(match.str(), pattern_true); });
void X3DImporter::XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list<int32_t>& pValue)
{
const char* tstr = mReader->getAttributeValue(pAttrIdx);
const char* tstr_end = tstr + strlen(tstr);
do
{
const char* ostr;
int32_t tval32;
tval32 = strtol10(tstr, &ostr);
if(ostr == tstr) break;
while((ostr < tstr_end) && (*ostr == ' ')) ostr++;// skip spaces between values.
tstr = ostr;
pValue.push_back(tval32);
} while(tstr < tstr_end);
WordIterator wordItBegin(val, val + strlen(val));
WordIterator wordItEnd;
std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return (::tolower(match[0]) == 't') || (match[0] == '1'); });
}
}
void X3DImporter::XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector<int32_t>& pValue)
{
std::list<int32_t> tlist;
auto intValue = std::dynamic_pointer_cast<const FIIntValue>(mReader->getAttributeEncodedValue(pAttrIdx));
if (intValue) {
pValue = intValue->value;
}
else {
const char *val = mReader->getAttributeValue(pAttrIdx);
pValue.clear();
XML_ReadNode_GetAttrVal_AsListI32(pAttrIdx, tlist);// read as list
// and copy to array
if(tlist.size() > 0)
{
pValue.reserve(tlist.size());
for(std::list<int32_t>::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it);
}
}
//std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws);
//const std::cregex_iterator wordItEnd;
//std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stoi(match.str()); });
void X3DImporter::XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list<float>& pValue)
{
std::string str_fixed;
// at first check string values like '.xxx'.
ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), str_fixed);
if(!str_fixed.size()) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
// and convert all values and place it in list.
const char* pstr = str_fixed.c_str();
const char* pstr_end = pstr + str_fixed.size();
do
{
float tvalf;
while((*pstr == ' ') && (pstr < pstr_end)) pstr++;// skip spaces between values.
if(pstr < pstr_end)// additional check, because attribute value can be ended with spaces.
{
pstr = fast_atoreal_move(pstr, tvalf, false);
pValue.push_back(tvalf);
}
} while(pstr < pstr_end);
WordIterator wordItBegin(val, val + strlen(val));
WordIterator wordItEnd;
std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atoi(match); });
}
}
void X3DImporter::XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector<float>& pValue)
{
std::list<float> tlist;
auto floatValue = std::dynamic_pointer_cast<const FIFloatValue>(mReader->getAttributeEncodedValue(pAttrIdx));
if (floatValue) {
pValue = floatValue->value;
}
else {
const char *val = mReader->getAttributeValue(pAttrIdx);
pValue.clear();
XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list
// and copy to array
if(tlist.size() > 0)
{
pValue.reserve(tlist.size());
for(std::list<float>::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it);
}
}
//std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws);
//const std::cregex_iterator wordItEnd;
//std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stof(match.str()); });
void X3DImporter::XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list<double>& pValue)
{
std::string str_fixed;
// at first check string values like '.xxx'.
ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), str_fixed);
if(!str_fixed.size()) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
// and convert all values and place it in list.
const char* pstr = str_fixed.c_str();
const char* pstr_end = pstr + str_fixed.size();
do
{
double tvald;
while((*pstr == ' ') && (pstr < pstr_end)) pstr++;// skip spaces between values.
if(pstr < pstr_end)// additional check, because attribute value can be ended with spaces.
{
pstr = fast_atoreal_move(pstr, tvald, false);
pValue.push_back(tvald);
}
} while(pstr < pstr_end);
WordIterator wordItBegin(val, val + strlen(val));
WordIterator wordItEnd;
std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atof(match); });
}
}
void X3DImporter::XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector<double>& pValue)
{
std::list<double> tlist;
auto doubleValue = std::dynamic_pointer_cast<const FIDoubleValue>(mReader->getAttributeEncodedValue(pAttrIdx));
if (doubleValue) {
pValue = doubleValue->value;
}
else {
const char *val = mReader->getAttributeValue(pAttrIdx);
pValue.clear();
XML_ReadNode_GetAttrVal_AsListD(pAttrIdx, tlist);// read as list
// and copy to array
if(tlist.size() > 0)
{
pValue.reserve(tlist.size());
for(std::list<double>::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it);
}
//std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws);
//const std::cregex_iterator wordItEnd;
//std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stod(match.str()); });
WordIterator wordItBegin(val, val + strlen(val));
WordIterator wordItEnd;
std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atof(match); });
}
}
void X3DImporter::XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list<aiColor3D>& pValue)
{
std::list<float> tlist;
std::vector<float> tlist;
XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list
XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list
if(tlist.size() % 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
// copy data to array
for(std::list<float>::iterator it = tlist.begin(); it != tlist.end();)
for(std::vector<float>::iterator it = tlist.begin(); it != tlist.end();)
{
aiColor3D tcol;
@ -635,13 +616,13 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::ve
void X3DImporter::XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list<aiColor4D>& pValue)
{
std::list<float> tlist;
std::vector<float> tlist;
XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list
XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list
if(tlist.size() % 4) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
// copy data to array
for(std::list<float>::iterator it = tlist.begin(); it != tlist.end();)
for(std::vector<float>::iterator it = tlist.begin(); it != tlist.end();)
{
aiColor4D tcol;
@ -671,16 +652,16 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::ve
void X3DImporter::XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list<aiVector2D>& pValue)
{
std::list<float> tlist;
std::vector<float> tlist;
XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list
XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list
if ( tlist.size() % 2 )
{
Throw_ConvertFail_Str2ArrF( mReader->getAttributeValue( pAttrIdx ) );
}
// copy data to array
for(std::list<float>::iterator it = tlist.begin(); it != tlist.end();)
for(std::vector<float>::iterator it = tlist.begin(); it != tlist.end();)
{
aiVector2D tvec;
@ -708,16 +689,16 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::ve
void X3DImporter::XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list<aiVector3D>& pValue)
{
std::list<float> tlist;
std::vector<float> tlist;
XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list
XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list
if ( tlist.size() % 3 )
{
Throw_ConvertFail_Str2ArrF( mReader->getAttributeValue( pAttrIdx ) );
}
// copy data to array
for(std::list<float>::iterator it = tlist.begin(); it != tlist.end();)
for(std::vector<float>::iterator it = tlist.begin(); it != tlist.end();)
{
aiVector3D tvec;
@ -907,9 +888,9 @@ void X3DImporter::GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSi
#undef MESH_RectParallelepiped_CREATE_VERT
void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::list<int32_t>& pCoordIdx, std::vector<aiFace>& pFaces, unsigned int& pPrimitiveTypes) const
void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::vector<int32_t>& pCoordIdx, std::vector<aiFace>& pFaces, unsigned int& pPrimitiveTypes) const
{
std::list<int32_t> f_data(pCoordIdx);
std::vector<int32_t> f_data(pCoordIdx);
std::vector<unsigned int> inds;
unsigned int prim_type = 0;
@ -922,7 +903,7 @@ void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::list<int32_t>&
pFaces.reserve(f_data.size() / 3);
inds.reserve(4);
//PrintVectorSet("build. ci", pCoordIdx);
for(std::list<int32_t>::iterator it = f_data.begin(); it != f_data.end(); it++)
for(std::vector<int32_t>::iterator it = f_data.begin(); it != f_data.end(); it++)
{
// when face is got count how many indices in it.
if(*it == (-1))
@ -1014,7 +995,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
}// if(pColorPerVertex) else
}
void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pColorIdx,
void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const
{
std::list<aiColor4D> tcol;
@ -1029,7 +1010,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
MeshGeometry_AddColor(pMesh, pCoordIdx, pColorIdx, tcol, pColorPerVertex);
}
void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pColorIdx,
void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const
{
std::vector<aiColor4D> col_tgt_arr;
@ -1060,7 +1041,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
}
// create list with colors for every vertex.
col_tgt_arr.resize(pMesh.mNumVertices);
for(std::list<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++)
for(std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++)
{
if ( *colidx_it == ( -1 ) )
{
@ -1108,7 +1089,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
// create list with colors for every vertex using faces indices.
col_tgt_arr.resize(pMesh.mNumFaces);
std::list<int32_t>::const_iterator colidx_it = pColorIdx.begin();
std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin();
for(size_t fi = 0; fi < pMesh.mNumFaces; fi++)
{
if((unsigned int)*colidx_it > pMesh.mNumFaces) throw DeadlyImportError("MeshGeometry_AddColor2. Face idx is out of range.");
@ -1138,7 +1119,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex);
}
void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pNormalIdx,
void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pNormalIdx,
const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const
{
std::vector<size_t> tind;
@ -1153,35 +1134,36 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<int32_t>
if(pNormalPerVertex)
{
const std::list<int32_t>* srcidx;
if(pNormalIdx.size() > 0)
{
// check indices array count.
if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal.");
srcidx = &pNormalIdx;
tind.reserve(pNormalIdx.size());
for(std::vector<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++)
{
if(*it != (-1)) tind.push_back(*it);
}
// copy normals to mesh
pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
for(size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++)
{
if(tind[i] >= norm_arr_copy.size())
throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + to_string(tind[i]) +
") is out of range. Normals count: " + to_string(norm_arr_copy.size()) + ".");
pMesh.mNormals[i] = norm_arr_copy[tind[i]];
}
}
else
{
srcidx = &pCoordIdx;
}
if(pNormals.size() != pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddNormal. Normals and vertices count must be equal.");
tind.reserve(srcidx->size());
for(std::list<int32_t>::const_iterator it = srcidx->begin(); it != srcidx->end(); it++)
{
if(*it != (-1)) tind.push_back(*it);
}
// copy normals to mesh
pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
for(size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++)
{
if(tind[i] >= norm_arr_copy.size())
throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + to_string(tind[i]) +
") is out of range. Normals count: " + to_string(norm_arr_copy.size()) + ".");
pMesh.mNormals[i] = norm_arr_copy[tind[i]];
// copy normals to mesh
pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
std::list<aiVector3D>::const_iterator norm_it = pNormals.begin();
for(size_t i = 0; i < pMesh.mNumVertices; i++) pMesh.mNormals[i] = *norm_it++;
}
}// if(pNormalPerVertex)
else
@ -1190,7 +1172,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<int32_t>
{
if(pMesh.mNumFaces != pNormalIdx.size()) throw DeadlyImportError("Normals faces count must be equal to mesh faces count.");
std::list<int32_t>::const_iterator normidx_it = pNormalIdx.begin();
std::vector<int32_t>::const_iterator normidx_it = pNormalIdx.begin();
tind.reserve(pNormalIdx.size());
for(size_t i = 0, i_e = pNormalIdx.size(); i < i_e; i++) tind.push_back(*normidx_it++);
@ -1243,7 +1225,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<aiVector
}// if(pNormalPerVertex) else
}
void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pTexCoordIdx,
void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pTexCoordIdx,
const std::list<aiVector2D>& pTexCoords) const
{
std::vector<aiVector3D> texcoord_arr_copy;
@ -1316,7 +1298,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVect
}
}
aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::list<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const
aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::vector<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const
{
std::vector<aiFace> faces;
unsigned int prim_type = 0;
@ -1419,9 +1401,12 @@ void X3DImporter::ParseHelper_FixTruncatedFloatString(const char* pInStr, std::s
}
}
extern FIVocabulary X3D_vocabulary_3_2;
extern FIVocabulary X3D_vocabulary_3_3;
void X3DImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler)
{
irr::io::IrrXMLReader* OldReader = mReader;// store current XMLreader.
std::unique_ptr<FIReader> OldReader = std::move(mReader);// store current XMLreader.
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
@ -1429,19 +1414,18 @@ void X3DImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler)
{
throw DeadlyImportError( "Failed to open X3D file " + pFile + "." );
}
// generate a XML reader for it
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
mReader = FIReader::create(file.get());
if ( !mReader )
{
throw DeadlyImportError( "Failed to create XML reader for file" + pFile + "." );
}
mReader->registerVocabulary("urn:web3d:x3d:fi-vocabulary-3.2", &X3D_vocabulary_3_2);
mReader->registerVocabulary("urn:web3d:x3d:fi-vocabulary-3.3", &X3D_vocabulary_3_3);
// start reading
ParseNode_Root();
delete mReader;
// restore old XMLreader
mReader = OldReader;
mReader = std::move(OldReader);
}
void X3DImporter::ParseNode_Root()
@ -1655,7 +1639,7 @@ bool X3DImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool p
{
const std::string extension = GetExtension(pFile);
if(extension == "x3d") return true;
if((extension == "x3d") || (extension == "x3db")) return true;
if(!extension.length() || pCheckSig)
{
@ -1670,6 +1654,7 @@ bool X3DImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool p
void X3DImporter::GetExtensionList(std::set<std::string>& pExtensionList)
{
pExtensionList.insert("x3d");
pExtensionList.insert("x3db");
}
const aiImporterDesc* X3DImporter::GetInfo () const
@ -1679,9 +1664,13 @@ const aiImporterDesc* X3DImporter::GetInfo () const
void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
{
mpIOHandler = pIOHandler;
Clear();// delete old graph.
mFileDir = DefaultIOSystem::absolutePath(pFile);
std::string::size_type slashPos = pFile.find_last_of("\\/");
pIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : pFile.substr(0, slashPos + 1));
ParseFile(pFile, pIOHandler);
pIOHandler->PopDirectory();
//
// Assimp use static arrays of objects for fast speed of rendering. That's good, but need some additional operations/
// We know that geometry objects(meshes) are stored in <Shape>, also in <Shape>-><Appearance> materials(in Assimp logical view)

View File

@ -56,6 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h>
#include "BaseImporter.h"
#include "irrXMLWrapper.h"
#include "FIReader.hpp"
//#include <regex>
namespace Assimp {
@ -101,7 +103,7 @@ namespace Assimp {
/// Navigation component:
/// "Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup"
/// Networking component:
/// "Anchor", "LoadSensor"
/// "EXPORT", "IMPORT", "Anchor", "LoadSensor"
/// NURBS component:
/// "Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface",
/// "NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate",
@ -449,33 +451,21 @@ private:
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list<bool>& pValue);
/// \overload void XML_ReadNode_GetAttrVal_AsListBool(const int pAttrIdx, std::list<bool>& pValue)
void XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector<bool>& pValue);
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list<int32_t>& pValue);
/// \overload void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list<int32_t>& pValue)
void XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector<int32_t>& pValue);
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list<float>& pValue);
/// \overload void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list<float>& pValue)
void XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector<float>& pValue);
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list<double>& pValue);
/// \overload void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list<double>& pValue)
void XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector<double>& pValue);
/// Read attribute value.
@ -554,7 +544,7 @@ private:
/// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
/// \param [in] pFaces - created faces array.
/// \param [in] pPrimitiveTypes - type of primitives in faces.
void GeometryHelper_CoordIdxStr2FacesArr(const std::list<int32_t>& pCoordIdx, std::vector<aiFace>& pFaces, unsigned int& pPrimitiveTypes) const;
void GeometryHelper_CoordIdxStr2FacesArr(const std::vector<int32_t>& pCoordIdx, std::vector<aiFace>& pFaces, unsigned int& pPrimitiveTypes) const;
/// Add colors to mesh.
/// a. If colorPerVertex is FALSE, colours are applied to each face, as follows:
@ -573,11 +563,11 @@ private:
/// then pColorIdx contain color indices for every faces and must not contain delimiter "-1".
/// \param [in] pColors - defined colors.
/// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face.
void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pColorIdx,
void MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const;
/// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pColorIdx, const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const;
void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pColorIdx,
void MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const;
/// Add colors to mesh.
@ -590,14 +580,14 @@ private:
void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const;
/// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor;
void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pNormalIdx,
void MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pNormalIdx,
const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const;
/// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor;
void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const;
/// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor;
void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pTexCoordIdx,
void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pTexCoordIdx,
const std::list<aiVector2D>& pTexCoords) const;
/// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor;
@ -607,7 +597,7 @@ private:
/// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
/// \param [in] pVertices - vertices of mesh.
/// \return created mesh.
aiMesh* GeometryHelper_MakeMesh(const std::list<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const;
aiMesh* GeometryHelper_MakeMesh(const std::vector<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const;
/***********************************************/
/******** Functions: parse set private *********/
@ -826,13 +816,16 @@ private:
/****************** Constants ******************/
/***********************************************/
static const aiImporterDesc Description;
//static const std::regex pattern_nws;
//static const std::regex pattern_true;
/***********************************************/
/****************** Variables ******************/
/***********************************************/
CX3DImporter_NodeElement* NodeElement_Cur;///< Current element.
irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
std::string mFileDir;
std::unique_ptr<FIReader> mReader;///< Pointer to XML-reader object
IOSystem *mpIOHandler;
};// class X3DImporter
}// namespace Assimp

View File

@ -285,7 +285,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid()
bool ccw = true;
bool colorPerVertex = true;
float creaseAngle = 0;
std::list<float> height;
std::vector<float> height;
bool normalPerVertex = true;
bool solid = true;
int32_t xDimension = 0;
@ -301,7 +301,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid()
MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat);
MACRO_ATTRREAD_CHECK_REF("height", height, XML_ReadNode_GetAttrVal_AsListF);
MACRO_ATTRREAD_CHECK_REF("height", height, XML_ReadNode_GetAttrVal_AsArrF);
MACRO_ATTRREAD_CHECK_RET("xDimension", xDimension, XML_ReadNode_GetAttrVal_AsI32);
MACRO_ATTRREAD_CHECK_RET("xSpacing", xSpacing, XML_ReadNode_GetAttrVal_AsFloat);
MACRO_ATTRREAD_CHECK_RET("zDimension", zDimension, XML_ReadNode_GetAttrVal_AsI32);
@ -326,7 +326,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid()
CX3DImporter_NodeElement_ElevationGrid& grid_alias = *((CX3DImporter_NodeElement_ElevationGrid*)ne);// create alias for conveience
{// create grid vertices list
std::list<float>::const_iterator he_it = height.begin();
std::vector<float>::const_iterator he_it = height.begin();
for(int32_t zi = 0; zi < zDimension; zi++)// rows
{
@ -863,29 +863,29 @@ void X3DImporter::ParseNode_Geometry3D_IndexedFaceSet()
{
std::string use, def;
bool ccw = true;
std::list<int32_t> colorIndex;
std::vector<int32_t> colorIndex;
bool colorPerVertex = true;
bool convex = true;
std::list<int32_t> coordIndex;
std::vector<int32_t> coordIndex;
float creaseAngle = 0;
std::list<int32_t> normalIndex;
std::vector<int32_t> normalIndex;
bool normalPerVertex = true;
bool solid = true;
std::list<int32_t> texCoordIndex;
std::vector<int32_t> texCoordIndex;
CX3DImporter_NodeElement* ne( nullptr );
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("convex", convex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat);
MACRO_ATTRREAD_CHECK_REF("normalIndex", normalIndex, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("normalIndex", normalIndex, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("texCoordIndex", texCoordIndex, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("texCoordIndex", texCoordIndex, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_LOOPEND;
// if "USE" defined then find already defined element.

View File

@ -123,14 +123,14 @@ void X3DImporter::ParseNode_MetadataBoolean()
{
std::string def, use;
std::string name, reference;
std::list<bool> value;
std::vector<bool> value;
CX3DImporter_NodeElement* ne( nullptr );
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListB);
MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrB);
MACRO_ATTRREAD_LOOPEND;
MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaBoolean, "MetadataBoolean", ENET_MetaBoolean);
@ -147,14 +147,14 @@ void X3DImporter::ParseNode_MetadataDouble()
{
std::string def, use;
std::string name, reference;
std::list<double> value;
std::vector<double> value;
CX3DImporter_NodeElement* ne( nullptr );
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListD);
MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrD);
MACRO_ATTRREAD_LOOPEND;
MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaDouble, "MetadataDouble", ENET_MetaDouble);
@ -171,14 +171,14 @@ void X3DImporter::ParseNode_MetadataFloat()
{
std::string def, use;
std::string name, reference;
std::list<float> value;
std::vector<float> value;
CX3DImporter_NodeElement* ne( nullptr );
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListF);
MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrF);
MACRO_ATTRREAD_LOOPEND;
MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaFloat, "MetadataFloat", ENET_MetaFloat);
@ -195,14 +195,14 @@ void X3DImporter::ParseNode_MetadataInteger()
{
std::string def, use;
std::string name, reference;
std::list<int32_t> value;
std::vector<int32_t> value;
CX3DImporter_NodeElement* ne( nullptr );
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_LOOPEND;
MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaInteger, "MetadataInteger", ENET_MetaInteger);

View File

@ -51,9 +51,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Header files, Assimp.
#include <assimp/DefaultIOSystem.h>
//#include <regex>
namespace Assimp
{
//static std::regex pattern_parentDir(R"((^|/)[^/]+/../)");
static std::string parentDir("/../");
// <Inline
// DEF="" ID
// USE="" IDREF
@ -89,12 +94,30 @@ void X3DImporter::ParseNode_Networking_Inline()
if(load && (url.size() > 0))
{
DefaultIOSystem io_handler;
std::string full_path;
std::string full_path = mpIOHandler->CurrentDirectory() + url.front();
full_path = mFileDir + "/" + url.front();
//full_path = std::regex_replace(full_path, pattern_parentDir, "$1");
for (std::string::size_type pos = full_path.find(parentDir); pos != std::string::npos; pos = full_path.find(parentDir, pos)) {
if (pos > 0) {
std::string::size_type pos2 = full_path.rfind('/', pos - 1);
if (pos2 != std::string::npos) {
full_path.erase(pos2, pos - pos2 + 3);
pos = pos2;
}
else {
full_path.erase(0, pos + 4);
pos = 0;
}
}
else {
pos += 3;
}
}
// Attribute "url" can contain list of strings. But we need only one - first.
ParseFile(full_path, &io_handler);
std::string::size_type slashPos = full_path.find_last_of("\\/");
mpIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : full_path.substr(0, slashPos + 1));
ParseFile(full_path, mpIOHandler);
mpIOHandler->PopDirectory();
}
// check for X3DMetadataObject childs.

View File

@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Header files, stdlib.
#include <list>
#include <vector>
#include <string>
/// \class CX3DImporter_NodeElement
@ -264,7 +265,7 @@ public:
/// This struct describe metavalue of type boolean.
struct CX3DImporter_NodeElement_MetaBoolean : public CX3DImporter_NodeElement_Meta
{
std::list<bool> Value;///< Stored value.
std::vector<bool> Value;///< Stored value.
/// \fn CX3DImporter_NodeElement_MetaBoolean(CX3DImporter_NodeElement* pParent)
/// Constructor
@ -279,7 +280,7 @@ struct CX3DImporter_NodeElement_MetaBoolean : public CX3DImporter_NodeElement_Me
/// This struct describe metavalue of type double.
struct CX3DImporter_NodeElement_MetaDouble : public CX3DImporter_NodeElement_Meta
{
std::list<double> Value;///< Stored value.
std::vector<double> Value;///< Stored value.
/// \fn CX3DImporter_NodeElement_MetaDouble(CX3DImporter_NodeElement* pParent)
/// Constructor
@ -294,7 +295,7 @@ struct CX3DImporter_NodeElement_MetaDouble : public CX3DImporter_NodeElement_Met
/// This struct describe metavalue of type float.
struct CX3DImporter_NodeElement_MetaFloat : public CX3DImporter_NodeElement_Meta
{
std::list<float> Value;///< Stored value.
std::vector<float> Value;///< Stored value.
/// \fn CX3DImporter_NodeElement_MetaFloat(CX3DImporter_NodeElement* pParent)
/// Constructor
@ -309,7 +310,7 @@ struct CX3DImporter_NodeElement_MetaFloat : public CX3DImporter_NodeElement_Meta
/// This struct describe metavalue of type integer.
struct CX3DImporter_NodeElement_MetaInteger : public CX3DImporter_NodeElement_Meta
{
std::list<int32_t> Value;///< Stored value.
std::vector<int32_t> Value;///< Stored value.
/// \fn CX3DImporter_NodeElement_MetaInteger(CX3DImporter_NodeElement* pParent)
/// Constructor
@ -508,7 +509,7 @@ public:
/// If the angle between the geometric normals of two adjacent faces is less than the crease angle, normals shall be calculated so that the faces are
/// shaded smoothly across the edge; otherwise, normals shall be calculated so that a lighting discontinuity across the edge is produced.
float CreaseAngle;
std::list<int32_t> CoordIdx;///< Coordinates list by faces. In X3D format: "-1" - delimiter for faces.
std::vector<int32_t> CoordIdx;///< Coordinates list by faces. In X3D format: "-1" - delimiter for faces.
/***********************************************/
/****************** Functions ******************/
@ -554,21 +555,21 @@ public:
/// direction. If normals are not generated but are supplied using a Normal node, and the orientation of the normals does not match the setting of the
/// ccw field, results are undefined.
bool CCW;
std::list<int32_t> ColorIndex;///< Field to specify the polygonal faces by indexing into the <Color> or <ColorRGBA>.
std::vector<int32_t> ColorIndex;///< Field to specify the polygonal faces by indexing into the <Color> or <ColorRGBA>.
bool ColorPerVertex;///< If true then colors are defined for every vertex, else for every face(line).
/// \var Convex
/// The convex field indicates whether all polygons in the shape are convex (TRUE). A polygon is convex if it is planar, does not intersect itself,
/// and all of the interior angles at its vertices are less than 180 degrees. Non planar and self intersecting polygons may produce undefined results
/// even if the convex field is FALSE.
bool Convex;
std::list<int32_t> CoordIndex;///< Field to specify the polygonal faces by indexing into the <Coordinate>.
std::vector<int32_t> CoordIndex;///< Field to specify the polygonal faces by indexing into the <Coordinate>.
/// \var CreaseAngle
/// If the angle between the geometric normals of two adjacent faces is less than the crease angle, normals shall be calculated so that the faces are
/// shaded smoothly across the edge; otherwise, normals shall be calculated so that a lighting discontinuity across the edge is produced.
float CreaseAngle;
std::list<int32_t> NormalIndex;///< Field to specify the polygonal faces by indexing into the <Normal>.
std::vector<int32_t> NormalIndex;///< Field to specify the polygonal faces by indexing into the <Normal>.
bool NormalPerVertex;///< If true then normals are defined for every vertex, else for every face(line).
std::list<int32_t> TexCoordIndex;///< Field to specify the polygonal faces by indexing into the <TextureCoordinate>.
std::vector<int32_t> TexCoordIndex;///< Field to specify the polygonal faces by indexing into the <TextureCoordinate>.
/***********************************************/
/****************** Functions ******************/
@ -616,10 +617,10 @@ public:
bool CCW;
bool ColorPerVertex;///< If true then colors are defined for every vertex, else for every face(line).
bool NormalPerVertex;///< If true then normals are defined for every vertex, else for every face(line).
std::list<int32_t> CoordIndex;///< Field to specify the polygonal faces by indexing into the <Coordinate>.
std::list<int32_t> NormalIndex;///< Field to specify the polygonal faces by indexing into the <Normal>.
std::list<int32_t> TexCoordIndex;///< Field to specify the polygonal faces by indexing into the <TextureCoordinate>.
std::list<int32_t> VertexCount;///< Field describes how many vertices are to be used in each polyline(polygon) from the <Coordinate> field.
std::vector<int32_t> CoordIndex;///< Field to specify the polygonal faces by indexing into the <Coordinate>.
std::vector<int32_t> NormalIndex;///< Field to specify the polygonal faces by indexing into the <Normal>.
std::vector<int32_t> TexCoordIndex;///< Field to specify the polygonal faces by indexing into the <TextureCoordinate>.
std::vector<int32_t> VertexCount;///< Field describes how many vertices are to be used in each polyline(polygon) from the <Coordinate> field.
/***********************************************/
/****************** Functions ******************/

View File

@ -180,16 +180,16 @@ void X3DImporter::ParseNode_Rendering_Coordinate()
void X3DImporter::ParseNode_Rendering_IndexedLineSet()
{
std::string use, def;
std::list<int32_t> colorIndex;
std::vector<int32_t> colorIndex;
bool colorPerVertex = true;
std::list<int32_t> coordIndex;
std::vector<int32_t> coordIndex;
CX3DImporter_NodeElement* ne( nullptr );
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_LOOPEND;
// if "USE" defined then find already defined element.
@ -256,7 +256,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
std::string use, def;
bool ccw = true;
bool colorPerVertex = true;
std::list<int32_t> index;
std::vector<int32_t> index;
bool normalPerVertex = true;
bool solid = true;
CX3DImporter_NodeElement* ne( nullptr );
@ -265,7 +265,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_LOOPEND;
@ -288,9 +288,46 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
ne_alias.CCW = ccw;
ne_alias.ColorPerVertex = colorPerVertex;
ne_alias.CoordIndex = index;
ne_alias.NormalPerVertex = normalPerVertex;
ne_alias.Solid = solid;
ne_alias.CoordIndex.clear();
int counter = 0;
int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
{
idx[2] = *idx_it;
if (idx[2] < 0)
{
counter = 0;
}
else
{
if (counter >= 2)
{
if(ccw)
{
ne_alias.CoordIndex.push_back(idx[0]);
ne_alias.CoordIndex.push_back(idx[1]);
ne_alias.CoordIndex.push_back(idx[2]);
}
else
{
ne_alias.CoordIndex.push_back(idx[0]);
ne_alias.CoordIndex.push_back(idx[2]);
ne_alias.CoordIndex.push_back(idx[1]);
}
ne_alias.CoordIndex.push_back(-1);
idx[1] = idx[2];
}
else
{
idx[counter] = idx[2];
}
++counter;
}
}// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
// check for child nodes
if(!mReader->isEmptyElement())
{
@ -337,7 +374,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
std::string use, def;
bool ccw = true;
bool colorPerVertex = true;
std::list<int32_t> index;
std::vector<int32_t> index;
bool normalPerVertex = true;
bool solid = true;
CX3DImporter_NodeElement* ne( nullptr );
@ -346,7 +383,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_LOOPEND;
@ -369,9 +406,34 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
ne_alias.CCW = ccw;
ne_alias.ColorPerVertex = colorPerVertex;
ne_alias.CoordIndex = index;
ne_alias.NormalPerVertex = normalPerVertex;
ne_alias.Solid = solid;
ne_alias.CoordIndex.clear();
int counter = 0;
int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
{
idx[counter++] = *idx_it;
if (counter > 2)
{
counter = 0;
if(ccw)
{
ne_alias.CoordIndex.push_back(idx[0]);
ne_alias.CoordIndex.push_back(idx[1]);
ne_alias.CoordIndex.push_back(idx[2]);
}
else
{
ne_alias.CoordIndex.push_back(idx[0]);
ne_alias.CoordIndex.push_back(idx[2]);
ne_alias.CoordIndex.push_back(idx[1]);
}
ne_alias.CoordIndex.push_back(-1);
}
}// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
// check for child nodes
if(!mReader->isEmptyElement())
{
@ -418,7 +480,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
std::string use, def;
bool ccw = true;
bool colorPerVertex = true;
std::list<int32_t> index;
std::vector<int32_t> index;
bool normalPerVertex = true;
bool solid = true;
CX3DImporter_NodeElement* ne( nullptr );
@ -427,7 +489,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_LOOPEND;
@ -450,9 +512,42 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
ne_alias.CCW = ccw;
ne_alias.ColorPerVertex = colorPerVertex;
ne_alias.CoordIndex = index;
ne_alias.NormalPerVertex = normalPerVertex;
ne_alias.Solid = solid;
ne_alias.CoordIndex.clear();
int counter = 0;
int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
{
idx[2] = *idx_it;
if (idx[2] < 0)
{
counter = 0;
}
else
{
if (counter >= 2)
{
if(ccw)
{
ne_alias.CoordIndex.push_back(idx[0]);
ne_alias.CoordIndex.push_back(idx[1]);
ne_alias.CoordIndex.push_back(idx[2]);
}
else
{
ne_alias.CoordIndex.push_back(idx[0]);
ne_alias.CoordIndex.push_back(idx[2]);
ne_alias.CoordIndex.push_back(idx[1]);
}
ne_alias.CoordIndex.push_back(-1);
}
idx[counter & 1] = idx[2];
++counter;
}
}// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
// check for child nodes
if(!mReader->isEmptyElement())
{
@ -492,12 +587,12 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
void X3DImporter::ParseNode_Rendering_LineSet()
{
std::string use, def;
std::list<int32_t> vertexCount;
std::vector<int32_t> vertexCount;
CX3DImporter_NodeElement* ne( nullptr );
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_REF("vertexCount", vertexCount, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("vertexCount", vertexCount, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_LOOPEND;
// if "USE" defined then find already defined element.
@ -521,7 +616,7 @@ void X3DImporter::ParseNode_Rendering_LineSet()
size_t coord_num = 0;
ne_alias.CoordIndex.clear();
for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
{
if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two.");
@ -627,7 +722,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet()
std::string use, def;
bool ccw = true;
bool colorPerVertex = true;
std::list<int32_t> fanCount;
std::vector<int32_t> fanCount;
bool normalPerVertex = true;
bool solid = true;
CX3DImporter_NodeElement* ne( nullptr );
@ -636,7 +731,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet()
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("fanCount", fanCount, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("fanCount", fanCount, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_LOOPEND;
@ -669,7 +764,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet()
// assign indices for first triangle
coord_num_first = 0;
coord_num_prev = 1;
for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
{
if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three.");
@ -818,7 +913,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet()
std::string use, def;
bool ccw = true;
bool colorPerVertex = true;
std::list<int32_t> stripCount;
std::vector<int32_t> stripCount;
bool normalPerVertex = true;
bool solid = true;
CX3DImporter_NodeElement* ne( nullptr );
@ -827,7 +922,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet()
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_REF("stripCount", stripCount, XML_ReadNode_GetAttrVal_AsListI32);
MACRO_ATTRREAD_CHECK_REF("stripCount", stripCount, XML_ReadNode_GetAttrVal_AsArrI32);
MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
MACRO_ATTRREAD_LOOPEND;
@ -860,7 +955,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet()
ne_alias.CoordIndex.clear();
coord_num_sb = 0;
for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
{
if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three.");

File diff suppressed because it is too large Load Diff

View File

@ -43,12 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
#include "XFileExporter.h"
#include "ConvertToLHProcess.h"
#include "Bitmap.h"
#include "BaseImporter.h"
#include "fast_atof.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include <assimp/DefaultIOSystem.h>
#include <ctime>
#include <set>

View File

@ -237,8 +237,9 @@ aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFil
// Creates the meshes for the given node.
void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vector<XFile::Mesh*>& pMeshes)
{
if( pMeshes.size() == 0)
if (pMeshes.empty()) {
return;
}
// create a mesh for each mesh-material combination in the source node
std::vector<aiMesh*> meshes;

View File

@ -466,15 +466,12 @@ void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
pMesh->mPosFaces.resize( numPosFaces);
for( unsigned int a = 0; a < numPosFaces; a++)
{
unsigned int numIndices = ReadInt();
if( numIndices < 3) {
ThrowException( format() << "Invalid index count " << numIndices << " for face " << a << "." );
}
// read indices
unsigned int numIndices = ReadInt();
Face& face = pMesh->mPosFaces[a];
for( unsigned int b = 0; b < numIndices; b++)
face.mIndices.push_back( ReadInt());
for (unsigned int b = 0; b < numIndices; b++) {
face.mIndices.push_back( ReadInt() );
}
TestForSeparator();
}

View File

@ -48,8 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ByteSwapper.h"
#include "SplitLargeMeshes.h"
#include "SceneCombiner.h"
#include <assimp/SceneCombiner.h>
#include <assimp/version.h>
#include <assimp/IOSystem.hpp>
#include <assimp/Exporter.hpp>
@ -185,8 +185,11 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
unsigned int bytesPerComp = ComponentTypeSize(compType);
size_t offset = buffer->byteLength;
// make sure offset is correctly byte-aligned, as required by spec
size_t padding = offset % bytesPerComp;
offset += padding;
size_t length = count * numCompsOut * bytesPerComp;
buffer->Grow(length);
buffer->Grow(length + padding);
// bufferView
Ref<BufferView> bv = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));

View File

@ -3,18 +3,40 @@ 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 ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} )
SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
option( DDL_USE_CPP11 "Set to ON to use C++11 features ( always on on windows )." ON )
option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF )
option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON )
option( COVERALLS "Generate coveralls data" OFF )
if ( DDL_USE_CPP11 )
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
set( OPENDDL_CXXFLAGS -std=c++0x )
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set( OPENDDL_CXXFLAGS --std=c++11 )
endif()
else( DDL_USE_CPP11 )
add_definitions( -DOPENDDL_NO_USE_CPP11 )
endif( DDL_USE_CPP11)
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
find_package(Threads)
else()
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
endif()
if ( DDL_STATIC_LIBRARY )
add_definitions( -DOPENDDL_STATIC_LIBARY )
endif()
add_definitions( -DOPENDDLPARSER_BUILD )
add_definitions( -DOPENDDL_NO_USE_CPP11 )
add_definitions( -D_VARIADIC_MAX=10 )
add_definitions( -DGTEST_HAS_PTHREAD=0 )
if ( DDL_DEBUG_OUTPUT )
add_definitions( -DDDL_DEBUG_HEADER_NAME)
endif()
INCLUDE_DIRECTORIES(
./
@ -24,9 +46,10 @@ INCLUDE_DIRECTORIES(
)
link_directories(
./
${CMAKE_HOME_DIRECTORY}/lib
)
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake )
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 )
@ -40,18 +63,38 @@ if( WIN32 AND NOT CYGWIN )
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")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS}")
elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS} -Wwrite-strings")
endif()
if (COVERALLS)
include(Coveralls)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
endif()
# Include the doc component.
FIND_PACKAGE( doxygen )
IF ( DOXYGEN_FOUND )
CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY )
ADD_CUSTOM_TARGET( doc ALL ${DOXYGEN_EXECUTABLE} doc/doxygenfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen" VERBATIM )
ENDIF ( DOXYGEN_FOUND )
SET ( openddl_parser_src
code/OpenDDLCommon.cpp
code/OpenDDLExport.cpp
code/OpenDDLParser.cpp
code/OpenDDLStream.cpp
code/DDLNode.cpp
code/Value.cpp
include/openddlparser/OpenDDLCommon.h
include/openddlparser/OpenDDLExport.h
include/openddlparser/OpenDDLParser.h
include/openddlparser/OpenDDLParserUtils.h
include/openddlparser/OpenDDLCommon.h
include/openddlparser/OpenDDLStream.h
include/openddlparser/DDLNode.h
include/openddlparser/Value.h
README.md
@ -59,6 +102,69 @@ SET ( openddl_parser_src
SOURCE_GROUP( code FILES ${openddl_parser_src} )
ADD_LIBRARY( openddl_parser SHARED
${openddl_parser_src}
if ( DDL_STATIC_LIBRARY )
ADD_LIBRARY( openddl_parser STATIC
${openddl_parser_src}
)
else()
ADD_LIBRARY( openddl_parser SHARED
${openddl_parser_src}
)
endif()
SET ( GTEST_PATH contrib/gtest-1.7.0 )
SET ( gtest_src
${GTEST_PATH}/src/gtest-death-test.cc
${GTEST_PATH}/src/gtest-filepath.cc
${GTEST_PATH}/src/gtest-internal-inl.h
${GTEST_PATH}/src/gtest-port.cc
${GTEST_PATH}/src/gtest-printers.cc
${GTEST_PATH}/src/gtest-test-part.cc
${GTEST_PATH}/src/gtest-typed-test.cc
${GTEST_PATH}/src/gtest.cc
${GTEST_PATH}/src/gtest_main.cc
)
SET( openddl_parser_unittest_src
test/UnitTestCommon.h
test/DDLNodeTest.cpp
test/OpenDDLCommonTest.cpp
test/OpenDDLExportTest.cpp
test/OpenDDLParserTest.cpp
test/OpenDDLParserUtilsTest.cpp
test/OpenDDLStreamTest.cpp
test/OpenDDLIntegrationTest.cpp
test/ValueTest.cpp
test/OpenDDLDefectsTest.cpp
)
SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} )
SOURCE_GROUP( gtest FILES ${gtest_src} )
ADD_EXECUTABLE( openddl_parser_unittest
${gtest_src}
${openddl_parser_unittest_src}
)
target_link_libraries( openddl_parser_unittest openddl_parser ${CMAKE_THREAD_LIBS_INIT} )
SET( openddl_parser_demo_src
demo/main.cpp
)
if (COVERALLS)
set(COVERAGE_SRCS ${gtest_src} ${openddl_parser_unittest_src} )
# Create the coveralls target.
coveralls_setup(
"${COVERAGE_SRCS}" # The source files.
ON # If we should upload.
"${PROJECT_SOURCE_DIR}/cmake/") # (Optional) Alternate project cmake module path.
endif()
ADD_EXECUTABLE( openddl_parser_demo
${openddl_parser_demo_src}
)
target_link_libraries( openddl_parser_demo openddl_parser )

View File

@ -12,5 +12,8 @@ Improvements value interface, serveral bugfixes.
- Henry Read ( henrya2 ):
Static build option, Interface improvements
- (wise86-android)
fix several mem-leaks
- Paul Holland ( pkholland ):
Bugfixes.

View File

@ -11,7 +11,7 @@ Current coverity check status:
<img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/5606/badge.svg"/>
</a>
Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls)
Get the source code
===================
You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
@ -25,7 +25,7 @@ After installing it you can open a console and enter:
> cmake CMakeLists.txt
This command will generate a build environment for your installed build enrironment ( for Visual-Studio-users the project files will be generated, for gcc-users the makefiles will be generated ).
This command will generate a build environment for your preferred build tool ( for Visual-Studio-users the project files will be generated, for gcc-users 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

View File

@ -68,8 +68,8 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx,
}
DDLNode::~DDLNode() {
releaseDataType<Property>( m_properties );
releaseDataType<Value>( m_value );
delete m_properties;
delete m_value;
releaseReferencedNames( m_references );
delete m_dtArrayList;
@ -77,6 +77,9 @@ DDLNode::~DDLNode() {
if( s_allocatedNodes[ m_idx ] == this ) {
s_allocatedNodes[ m_idx ] = ddl_nullptr;
}
for ( size_t i = 0; i<m_children.size(); i++ ){
delete m_children[ i ];
}
}
void DDLNode::attachParent( DDLNode *parent ) {
@ -91,9 +94,8 @@ void DDLNode::attachParent( DDLNode *parent ) {
}
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( ddl_nullptr != m_parent ) {
DDLNodeIt 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 );
}
@ -126,6 +128,8 @@ const std::string &DDLNode::getName() const {
}
void DDLNode::setProperties( Property *prop ) {
if(m_properties!=ddl_nullptr)
delete m_properties;
m_properties = prop;
}
@ -187,6 +191,10 @@ Reference *DDLNode::getReferences() const {
return m_references;
}
void DDLNode::dump(IOStreamBase &stream) {
// Todo!
}
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 );
@ -197,7 +205,7 @@ DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLN
void DDLNode::releaseNodes() {
if( s_allocatedNodes.size() > 0 ) {
for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
for( DDLNodeIt it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
if( *it ) {
delete *it;
}

View File

@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#include <openddlparser/OpenDDLCommon.h>
#include <openddlparser/DDLNode.h>
#include <openddlparser/Value.h>
BEGIN_ODDLPARSER_NS
@ -84,7 +85,14 @@ Name::~Name() {
m_id = ddl_nullptr;
}
Reference::Reference()
Name::Name( const Name &name ){
m_type=name.m_type;
m_id=new Text(name.m_id->m_buffer,name.m_id->m_len);
}
Reference::Reference()
: m_numRefs( 0 )
, m_referencedName( ddl_nullptr ) {
// empty
@ -96,8 +104,16 @@ Reference::Reference( size_t numrefs, Name **names )
if ( numrefs > 0 ) {
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;
m_referencedName[ i ] = names[i];
}
}
}
Reference::Reference(const Reference &ref) {
m_numRefs=ref.m_numRefs;
if(m_numRefs!=0){
m_referencedName = new Name*[m_numRefs];
for ( size_t i = 0; i < m_numRefs; i++ ) {
m_referencedName[i] = new Name(*ref.m_referencedName[i]);
}
}
}
@ -107,6 +123,7 @@ Reference::~Reference() {
delete m_referencedName[ i ];
}
m_numRefs = 0;
delete [] m_referencedName;
m_referencedName = ddl_nullptr;
}
@ -135,21 +152,30 @@ Property::Property( Text *id )
}
Property::~Property() {
m_key = ddl_nullptr;
m_value = ddl_nullptr;
m_ref = ddl_nullptr;;
m_next = ddl_nullptr;;
delete m_key;
if(m_value!=ddl_nullptr)
delete m_value;
if(m_ref!=ddl_nullptr)
delete(m_ref);
if(m_next!=ddl_nullptr)
delete m_next;
}
DataArrayList::DataArrayList()
: m_numItems( 0 )
, m_dataList( ddl_nullptr )
, m_next( ddl_nullptr ) {
, m_next( ddl_nullptr )
, m_refs(ddl_nullptr)
, m_numRefs(0){
// empty
}
DataArrayList::~DataArrayList() {
// empty
delete m_dataList;
if(m_next!=ddl_nullptr)
delete m_next;
if(m_refs!=ddl_nullptr)
delete m_refs;
}
size_t DataArrayList::size() {

View File

@ -29,60 +29,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BEGIN_ODDLPARSER_NS
StreamFormatterBase::StreamFormatterBase() {
}
StreamFormatterBase::~StreamFormatterBase() {
}
std::string StreamFormatterBase::format( const std::string &statement ) {
std::string tmp( statement );
return tmp;
}
IOStreamBase::IOStreamBase( StreamFormatterBase *formatter )
: m_formatter( formatter )
, m_file( ddl_nullptr ) {
if (ddl_nullptr == m_formatter) {
m_formatter = new StreamFormatterBase;
}
}
IOStreamBase::~IOStreamBase() {
delete m_formatter;
m_formatter = ddl_nullptr;
}
bool IOStreamBase::open( const std::string &name ) {
m_file = ::fopen( name.c_str(), "a" );
if (m_file == ddl_nullptr) {
return false;
}
return true;
}
bool IOStreamBase::close() {
if (ddl_nullptr == m_file) {
return false;
}
::fclose( m_file );
m_file = ddl_nullptr;
return true;
}
size_t IOStreamBase::write( const std::string &statement ) {
if (ddl_nullptr == m_file) {
return 0;
}
std::string formatStatement = m_formatter->format( statement );
return ::fwrite( formatStatement.c_str(), sizeof( char ), formatStatement.size(), m_file );
}
struct DDLNodeIterator {
const DDLNode::DllNodeList &m_childs;
size_t m_idx;
@ -280,7 +226,7 @@ bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std:
statement += "[";
char buffer[ 256 ];
::memset( buffer, '\0', 256 * sizeof( char ) );
sprintf( buffer, "%d", int(numItems) );
sprintf( buffer, "%d", static_cast<int>( numItems ) );
statement += buffer;
statement += "]";
}

View File

@ -36,7 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BEGIN_ODDLPARSER_NS
static const char *Version = "0.3.0";
static const char *Version = "0.4.0";
namespace Grammar {
static const char *OpenBracketToken = "{";
@ -49,7 +49,7 @@ namespace Grammar {
static const char *BoolFalse = "false";
static const char *CommaSeparator = ",";
static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
static const char *PrimitiveTypeToken[ Value::ddl_types_max ] = {
"bool",
"int8",
"int16",
@ -74,8 +74,8 @@ const char *getTypeToken( Value::ValueType type ) {
static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
std::stringstream stream;
stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl;
std::string full(in);
std::string part(full.substr(0,50));
std::string full( in );
std::string part( full.substr( 0, 50 ) );
stream << part;
callback( ddl_error_msg, stream.str() );
}
@ -85,6 +85,7 @@ static bool isIntegerType( Value::ValueType integerType ) {
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
return false;
}
return true;
}
@ -193,10 +194,11 @@ size_t OpenDDLParser::getBufferSize() const {
void OpenDDLParser::clear() {
m_buffer.resize( 0 );
if( ddl_nullptr != m_context ) {
m_context->m_root = ddl_nullptr;
delete m_context;
m_context=ddl_nullptr;
}
DDLNode::releaseNodes();
// DDLNode::releaseNodes();
}
bool OpenDDLParser::parse() {
@ -212,11 +214,11 @@ bool OpenDDLParser::parse() {
// do the main parsing
char *current( &m_buffer[ 0 ] );
char *end( &m_buffer[ m_buffer.size() - 1 ] + 1 );
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 );
if(current==ddl_nullptr) {
if ( current == ddl_nullptr ) {
return false;
}
pos = current - &m_buffer[ 0 ];
@ -245,7 +247,7 @@ static void dumpId( Identifier *id ) {
if( ddl_nullptr != id ) {
if ( ddl_nullptr != id->m_text.m_buffer ) {
std::cout << id->m_text.m_buffer << std::endl;
}
}
}
}
#endif
@ -271,14 +273,17 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
} else {
std::cerr << "nullptr returned by creating DDLNode." << std::endl;
}
delete id;
Name *name(ddl_nullptr);
in = OpenDDLParser::parseName(in, end, &name);
if( ddl_nullptr != name && ddl_nullptr != node ) {
const std::string nodeName( name->m_id->m_buffer );
node->setName( nodeName );
delete name;
}
Property *first(ddl_nullptr);
in = lookForNextToken(in, end);
if (*in == Grammar::OpenPropertyToken[0]) {
@ -303,7 +308,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
prev = prop;
}
}
in++;
++in;
}
// set the properties
@ -322,17 +327,17 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
bool error( false );
in = lookForNextToken( in, end );
if( *in == '{' ) {
if( *in == *Grammar::OpenBracketToken) {
// loop over all children ( data and nodes )
do {
in = parseStructureBody( in, end, error );
if(in == ddl_nullptr){
return ddl_nullptr;
}
} while ( *in != '}' );
in++;
} while ( *in != *Grammar::CloseBracketToken);
++in;
} else {
in++;
++in;
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
error = true;
return ddl_nullptr;
@ -373,7 +378,7 @@ static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayLi
char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
if( !isNumeric( *in ) && !isCharacter( *in ) ) {
in++;
++in;
}
in = lookForNextToken( in, end );
@ -431,7 +436,6 @@ DDLNode *OpenDDLParser::popNode() {
DDLNode *topNode( top() );
m_stack.pop_back();
return topNode;
}
@ -467,7 +471,14 @@ void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
char *c( &buffer[readIdx] );
// check for a comment
if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
if (isCommentOpenTag(c, end)) {
++readIdx;
while (!isCommentCloseTag(&buffer[readIdx], end)) {
++readIdx;
}
++readIdx;
++readIdx;
} else if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
newBuffer.push_back( buffer[ readIdx ] );
} else {
if( isComment<char>( c, end ) ) {
@ -529,14 +540,17 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Text **id ) {
// get size of id
size_t idLen( 0 );
char *start( in );
while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != Grammar::OpenPropertyToken[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] && *in != '$' ) {
while( !isSeparator( *in ) &&
!isNewLine( *in ) && ( in != end ) &&
*in != Grammar::OpenPropertyToken[ 0 ] &&
*in != Grammar::ClosePropertyToken[ 0 ] &&
*in != '$' ) {
++in;
++idLen;
}
const size_t len( idLen );
Text *newId = new Text( start, len );
*id = newId;
*id = new Text( start, len );
return in;
}
@ -552,7 +566,7 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
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;
type = static_cast<Value::ValueType>( i );
break;
}
}
@ -567,14 +581,14 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
bool ok( true );
if( *in == Grammar::OpenArrayToken[ 0 ] ) {
ok = false;
in++;
++in;
char *start( in );
while ( in != end ) {
in++;
++in;
if( *in == Grammar::CloseArrayToken[ 0 ] ) {
len = ::atoi( start );
ok = true;
in++;
++in;
break;
}
}
@ -623,10 +637,10 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean )
char *start( in );
size_t len( 0 );
while( !isSeparator( *in ) && in != end ) {
in++;
len++;
++in;
++len;
}
len++;
++len;
int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
if( 0 != res ) {
res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
@ -657,7 +671,7 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
in = lookForNextToken( in, end );
char *start( in );
while( !isSeparator( *in ) && in != end ) {
in++;
++in;
}
if( isNumeric( *start ) ) {
@ -671,29 +685,29 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
*integer = ValueAllocator::allocPrimData( integerType );
switch( integerType ) {
case Value::ddl_int8:
( *integer )->setInt8( (int8) value );
break;
( *integer )->setInt8( (int8) value );
break;
case Value::ddl_int16:
( *integer )->setInt16( ( int16 ) value );
break;
( *integer )->setInt16( ( int16 ) value );
break;
case Value::ddl_int32:
( *integer )->setInt32( ( int32 ) value );
break;
( *integer )->setInt32( ( int32 ) value );
break;
case Value::ddl_int64:
( *integer )->setInt64( ( int64 ) value );
break;
( *integer )->setInt64( ( int64 ) value );
break;
case Value::ddl_unsigned_int8:
( *integer )->setUnsignedInt8( (uint8) uvalue );
break;
( *integer )->setUnsignedInt8( (uint8) uvalue );
break;
case Value::ddl_unsigned_int16:
( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
break;
( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
break;
case Value::ddl_unsigned_int32:
( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
break;
( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
break;
case Value::ddl_unsigned_int64:
( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
break;
( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
break;
default:
break;
}
@ -711,7 +725,7 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
in = lookForNextToken( in, end );
char *start( in );
while( !isSeparator( *in ) && in != end ) {
in++;
++in;
}
// parse the float value
@ -732,8 +746,7 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
}
if( ok ) {
if(floatType == Value::ddl_double)
{
if ( floatType == Value::ddl_double ) {
const double value( atof( start ) );
*floating = ValueAllocator::allocPrimData( Value::ddl_double );
( *floating )->setDouble( value );
@ -757,17 +770,17 @@ char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData
size_t len( 0 );
char *start( in );
if( *start == '\"' ) {
start++;
in++;
++start;
++in;
while( *in != '\"' && in != end ) {
in++;
len++;
++in;
++len;
}
*stringData = ValueAllocator::allocPrimData( Value::ddl_string, len );
::strncpy( ( char* ) ( *stringData )->m_data, start, len );
( *stringData )->m_data[len] = '\0';
in++;
++in;
}
return in;
@ -791,12 +804,12 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
return in;
}
in++;
++in;
if( *in != 'x' && *in != 'X' ) {
return in;
}
in++;
++in;
bool ok( true );
char *start( in );
int pos( 0 );
@ -805,8 +818,8 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
ok = false;
break;
}
pos++;
in++;
++pos;
++in;
}
if( !ok ) {
@ -816,9 +829,9 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
int value( 0 );
while( pos > 0 ) {
int v = hex2Decimal( *start );
pos--;
--pos;
value = ( value << 4 ) | v;
start++;
++start;
}
*data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 );
@ -841,7 +854,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
if( ddl_nullptr != id ) {
in = lookForNextToken( in, end );
if( *in == '=' ) {
in++;
++in;
in = getNextToken( in, end );
Value *primData( ddl_nullptr );
if( isInteger( in, end ) ) {
@ -862,6 +875,8 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
( *prop )->m_ref = ref;
}
}
} else {
delete id;
}
}
@ -878,7 +893,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
in = lookForNextToken( in, end );
if( *in == '{' ) {
in++;
++in;
Value *current( ddl_nullptr ), *prev( ddl_nullptr );
while( '}' != *in ) {
current = ddl_nullptr;
@ -934,7 +949,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
prev->setNext( current );
prev = current;
}
numValues++;
++numValues;
}
in = getNextSeparator( in, end );
@ -942,7 +957,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
break;
}
}
in++;
++in;
}
return in;
@ -972,7 +987,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType ty
in = lookForNextToken( in, end );
if( *in == Grammar::OpenBracketToken[ 0 ] ) {
in++;
++in;
Value *currentValue( ddl_nullptr );
Reference *refs( ddl_nullptr );
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
@ -995,7 +1010,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType ty
}
} while( Grammar::CommaSeparator[ 0 ] == *in && in != end );
in = lookForNextToken( in, end );
in++;
++in;
}
return in;

View File

@ -0,0 +1,96 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014-2015 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/OpenDDLStream.h>
BEGIN_ODDLPARSER_NS
StreamFormatterBase::StreamFormatterBase() {
// empty
}
StreamFormatterBase::~StreamFormatterBase() {
// empty
}
std::string StreamFormatterBase::format(const std::string &statement) {
std::string tmp(statement);
return tmp;
}
IOStreamBase::IOStreamBase(StreamFormatterBase *formatter)
: m_formatter(formatter)
, m_file(ddl_nullptr) {
if (ddl_nullptr == m_formatter) {
m_formatter = new StreamFormatterBase;
}
}
IOStreamBase::~IOStreamBase() {
delete m_formatter;
m_formatter = ddl_nullptr;
}
bool IOStreamBase::open(const std::string &name) {
m_file = ::fopen(name.c_str(), "a");
if (m_file == ddl_nullptr) {
return false;
}
return true;
}
bool IOStreamBase::close() {
if (ddl_nullptr == m_file) {
return false;
}
::fclose(m_file);
m_file = ddl_nullptr;
return true;
}
bool IOStreamBase::isOpen() const {
return ( ddl_nullptr != m_file );
}
size_t IOStreamBase::read( size_t sizeToRead, std::string &statement ) {
if (ddl_nullptr == m_file) {
return 0;
}
statement.resize(sizeToRead);
const size_t readBytes = ::fread( &statement[0], 1, sizeToRead, m_file );
return readBytes;
}
size_t IOStreamBase::write(const std::string &statement) {
if (ddl_nullptr == m_file) {
return 0;
}
std::string formatStatement = m_formatter->format(statement);
return ::fwrite(formatStatement.c_str(), sizeof(char), formatStatement.size(), m_file);
}
END_ODDLPARSER_NS

View File

@ -110,7 +110,17 @@ Value::Value( ValueType type )
}
Value::~Value() {
// empty
if(m_data!=ddl_nullptr) {
if (m_type == ddl_ref ) {
Reference *tmp = (Reference *) m_data;
if (tmp != ddl_nullptr)
delete tmp;
}else
delete[] m_data;
}
if(m_next!=ddl_nullptr)
delete m_next;
}
void Value::setBool( bool value ) {
@ -273,13 +283,7 @@ void Value::setRef( Reference *ref ) {
delete [] m_data;
}
m_data = new unsigned char[ sizeof( Reference ) ];
Reference *myRef = ( Reference * ) m_data;
myRef->m_numRefs = ref->m_numRefs;
myRef->m_referencedName = new Name *[ myRef->m_numRefs ];
for ( size_t i = 0; i < myRef->m_numRefs; i++ ) {
myRef->m_referencedName[ i ] = new Name( ref->m_referencedName[ i ]->m_type, ref->m_referencedName[ i ]->m_id );
}
m_data = (unsigned char*) new Reference(*ref);
}
}
}
@ -290,7 +294,7 @@ Reference *Value::getRef() const {
return (Reference*) m_data;
}
void Value::dump() {
void Value::dump( IOStreamBase &stream ) {
switch( m_type ) {
case ddl_none:
std::cout << "None" << std::endl;
@ -350,7 +354,7 @@ Value *Value::getNext() const {
return m_next;
}
size_t Value::size(){
size_t Value::size() const{
size_t result=1;
Value *n=m_next;
while( n!=ddl_nullptr) {
@ -366,7 +370,6 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
}
Value *data = new Value( type );
data->m_type = type;
switch( type ) {
case Value::ddl_bool:
data->m_size = sizeof( bool );
@ -405,10 +408,10 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
data->m_size = sizeof( double );
break;
case Value::ddl_string:
data->m_size = sizeof( char );
data->m_size = sizeof( char )*(len+1);
break;
case Value::ddl_ref:
data->m_size = sizeof( char );
data->m_size = 0;
break;
case Value::ddl_none:
case Value::ddl_types_max:
@ -417,12 +420,8 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
}
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 ];
::memset(data->m_data,0,data->m_size);
}
return data;

View File

@ -29,6 +29,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BEGIN_ODDLPARSER_NS
// Forward declarations
class IOStreamBase;
class Value;
class OpenDDLParser;
@ -53,6 +55,9 @@ public:
/// @brief The child-node-list type.
typedef std::vector<DDLNode*> DllNodeList;
/// @brief The child-node-list iterator.
typedef std::vector<DDLNode*>::iterator DDLNodeIt;
public:
/// @brief The class destructor.
~DDLNode();
@ -81,7 +86,7 @@ public:
const std::string &getType() const;
/// Set the name of the DDLNode instance.
/// @param type [in] The name.
/// @param name [in] The name.
void setName( const std::string &name );
/// @brief Returns the name of the DDLNode instance.
@ -89,7 +94,7 @@ public:
const std::string &getName() const;
/// @brief Set a new property set.
/// @param prop [in] The first element of the property set.
/// @param prop [in] The first element of the property set.
void setProperties( Property *prop );
/// @brief Returns the first element of the assigned property set.
@ -97,7 +102,7 @@ public:
Property *getProperties() const;
/// @brief Looks for a given property.
/// @param name [in] The name for the property to look for.
/// @param name [in] The name for the property to look for.
/// @return true, if a corresponding property is assigned to the node, false if not.
bool hasProperty( const std::string &name );
@ -106,12 +111,12 @@ public:
bool hasProperties() const;
/// @brief Search for a given property and returns it. Will return ddl_nullptr if no property was found.
/// @param name [in] The name for the property to look for.
/// @param name [in] The name for the property to look for.
/// @return The property or ddl_nullptr if no property was found.
Property *findPropertyByName( const std::string &name );
/// @brief Set a new value set.
/// @param val [in] The first value instance of the value set.
/// @param val [in] The first value instance of the value set.
void setValue( Value *val );
/// @brief Returns the first element of the assigned value set.
@ -119,7 +124,7 @@ public:
Value *getValue() const;
/// @brief Set a new DataArrayList.
/// @param val [in] The DataArrayList instance.
/// @param dtArrayList [in] The DataArrayList instance.
void setDataArrayList( DataArrayList *dtArrayList );
/// @brief Returns the DataArrayList.
@ -127,17 +132,21 @@ public:
DataArrayList *getDataArrayList() const;
/// @brief Set a new Reference set.
/// @param val [in] The first value instance of the Reference set.
/// @param refs [in] The first value instance of the Reference set.
void setReferences( Reference *refs );
/// @brief Returns the first element of the assigned Reference set.
/// @return The first property of the assigned Reference set.
Reference *getReferences() const;
/// @brief Will dump the node into the stream.
/// @param stream [in] The stream to write to.
void dump(IOStreamBase &stream);
/// @brief The creation method.
/// @param type [in] The DDLNode type.
/// @param name [in] The name for the new DDLNode instance.
/// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there.
/// @param type [in] The DDLNode type.
/// @param name [in] The name for the new DDLNode instance.
/// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there.
/// @return The new created node instance.
static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr );

View File

@ -148,12 +148,12 @@ struct DLL_ODDLPARSER_EXPORT Name {
/// @param type [in] The name type.
/// @param id [in] The id.
Name( NameType type, Text *id );
Name( const Name &name );
/// @brief The destructor.
~Name();
private:
Name( const Name & ) ddl_no_copy;
Name &operator = ( const Name& ) ddl_no_copy;
};
@ -164,7 +164,7 @@ struct DLL_ODDLPARSER_EXPORT Reference {
/// @brief The default constructor.
Reference();
Reference( const Reference &ref );
/// @brief The constructor with an array of ref names.
/// @param numrefs [in] The number of ref names.
/// @param names [in] The ref names.
@ -178,7 +178,6 @@ struct DLL_ODDLPARSER_EXPORT Reference {
size_t sizeInBytes();
private:
Reference( const Reference & ) ddl_no_copy;
Reference &operator = ( const Reference & ) ddl_no_copy;
};

View File

@ -23,37 +23,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once
#include <openddlparser/OpenDDLCommon.h>
#include <openddlparser/OpenDDLStream.h>
#include <openddlparser/Value.h>
BEGIN_ODDLPARSER_NS
//-------------------------------------------------------------------------------------------------
/// @ingroup IOStreamBase
/// @brief This class represents the stream to write out.
//-------------------------------------------------------------------------------------------------
class DLL_ODDLPARSER_EXPORT StreamFormatterBase {
public:
StreamFormatterBase();
virtual ~StreamFormatterBase();
virtual std::string format( const std::string &statement );
};
//-------------------------------------------------------------------------------------------------
/// @ingroup IOStreamBase
/// @brief This class represents the stream to write out.
//-------------------------------------------------------------------------------------------------
class DLL_ODDLPARSER_EXPORT IOStreamBase {
public:
IOStreamBase( StreamFormatterBase *formatter = ddl_nullptr );
virtual ~IOStreamBase();
virtual bool open( const std::string &anme );
virtual bool close();
virtual size_t write( const std::string &statement );
private:
StreamFormatterBase *m_formatter;
FILE *m_file;
};
// Forward declarations
class IOStreamBase;
//-------------------------------------------------------------------------------------------------
///

View File

@ -39,6 +39,16 @@ struct Identifier;
struct Reference;
struct Property;
template<class T>
inline
bool isEmbeddedCommentOpenTag( T *in, T *end ) {
if ( in == '/' && in+1 == '*' ) {
return true;
}
return false;
}
/// @brief Utility function to search for the next token or the end of the buffer.
/// @param in [in] The start position in the buffer.
/// @param end [in] The end position in the buffer.
@ -47,7 +57,7 @@ struct Property;
template<class T>
inline
T *lookForNextToken( T *in, T *end ) {
while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
while( ( in != end ) && ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) ) {
in++;
}
return in;

View File

@ -84,7 +84,7 @@ static const unsigned char chartype_table[ 256 ] = {
template<class T>
inline
bool isNumeric( const T in ) {
return ( chartype_table[ static_cast<int>( in ) ] == 1 );
return ( chartype_table[ static_cast<size_t>( in ) ] == 1 );
}
template<class T>
@ -98,7 +98,7 @@ inline
bool isInteger( T *in, T *end ) {
if( in != end ) {
if( *in == '-' ) {
in++;
++in;
}
}
@ -108,7 +108,7 @@ bool isInteger( T *in, T *end ) {
if( !result ) {
break;
}
in++;
++in;
}
return result;
@ -119,7 +119,7 @@ inline
bool isFloat( T *in, T *end ) {
if( in != end ) {
if( *in == '-' ) {
in++;
++in;
}
}
@ -134,12 +134,12 @@ bool isFloat( T *in, T *end ) {
if( !result ) {
return false;
}
in++;
++in;
}
// check for 1<.>0f
if( *in == '.' ) {
in++;
++in;
} else {
return false;
}
@ -150,7 +150,7 @@ bool isFloat( T *in, T *end ) {
if( !result ) {
return false;
}
in++;
++in;
}
return result;
@ -208,7 +208,7 @@ template<class T>
inline
static T *getNextSeparator( T *in, T *end ) {
while( !isSeparator( *in ) || in == end ) {
in++;
++in;
}
return in;
}
@ -250,5 +250,33 @@ bool isComment( T *in, T *end ) {
return false;
}
template<class T>
inline
bool isCommentOpenTag(T *in, T *end ) {
if (*in == '/') {
if (in + 1 != end) {
if (*(in + 1) == '*') {
return true;
}
}
}
return false;
}
template<class T>
inline
bool isCommentCloseTag(T *in, T *end) {
if (*in == '*') {
if (in + 1 != end) {
if (*(in + 1) == '/') {
return true;
}
}
}
return false;
}
END_ODDLPARSER_NS

View File

@ -0,0 +1,89 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014-2015 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
#include <openddlparser/OpenDDLCommon.h>
BEGIN_ODDLPARSER_NS
//-------------------------------------------------------------------------------------------------
/// @ingroup IOStreamBase
/// @brief This class represents the stream to write out.
//-------------------------------------------------------------------------------------------------
class DLL_ODDLPARSER_EXPORT StreamFormatterBase {
public:
/// @brief The class constructor.
StreamFormatterBase();
/// @brief The class destructor, virtual.
virtual ~StreamFormatterBase();
/// @brief Will format the sring and return the new formatted result.
/// @param statement [in] The string to reformat.
/// @return The reformatted result.
virtual std::string format(const std::string &statement);
};
//-------------------------------------------------------------------------------------------------
/// @ingroup IOStreamBase
/// @brief This class represents the stream to write out.
//-------------------------------------------------------------------------------------------------
class DLL_ODDLPARSER_EXPORT IOStreamBase {
public:
/// @brief The class constructor with the formatter.
/// @param formatter [in] The formatter to use.
explicit IOStreamBase(StreamFormatterBase *formatter = ddl_nullptr);
/// @brief The class destructor, virtual.
virtual ~IOStreamBase();
/// @brief Will open the stream.
/// @param name [in] The name for the stream.
/// @return true, if the stream was opened successfully, false if not.
virtual bool open(const std::string &name);
/// @brief Will close the stream.
/// @return true, if the stream was closed successfully, false if not.
virtual bool close();
/// @brief Returns true, if the stream is open.
/// @return true, if the stream is open, false if not.
virtual bool isOpen() const;
/// @brief Will read a string from the stream.
/// @param sizeToRead [in] The size to read in bytes.
/// @param statement [out] The read statements.
/// @return The bytes read from the stream.
virtual size_t read( size_t sizeToRead, std::string &statement );
/// @brief Will write a string into the stream.
/// @param statement [in] The string to write.
/// @return The bytes written into the stream.
virtual size_t write(const std::string &statement);
private:
StreamFormatterBase *m_formatter;
FILE *m_file;
};
END_ODDLPARSER_NS

View File

@ -28,8 +28,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BEGIN_ODDLPARSER_NS
// Forward declarations
struct ValueAllocator;
class IOStreamBase;
///------------------------------------------------------------------------------------------------
/// @brief This class implements a value.
///
@ -213,7 +216,7 @@ public:
double getDouble() const;
/// @brief Assigns a std::string to the value.
/// @param value [in] The value.
/// @param str [in] The value.
void setString( const std::string &str );
/// @brief Returns the std::string value.
@ -229,7 +232,8 @@ public:
Reference *getRef() const;
/// @brief Dumps the value.
void dump();
/// @param stream [in] The stream to write in.
void dump( IOStreamBase &stream );
/// @brief Assigns the next value.
/// @param next [n] The next value.
@ -241,7 +245,7 @@ public:
/// @brief Gets the length of the array.
/// @return The number of items in the array.
size_t size();
size_t size() const;
ValueType m_type;
size_t m_size;

View File

@ -143,7 +143,6 @@ struct NodeAttachmentInfo
*/
#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10
typedef std::pair<aiBone*,unsigned int> BoneSrcIndex;
// ---------------------------------------------------------------------------
@ -153,7 +152,6 @@ struct BoneWithHash : public std::pair<uint32_t,aiString*> {
std::vector<BoneSrcIndex> pSrcBones;
};
// ---------------------------------------------------------------------------
/** @brief Utility for SceneCombiner
*/

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2016, assimp team
Copyright (c) 2006-2017, assimp team
All rights reserved.
@ -632,7 +632,14 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \
"IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will search for embedded loaded textures, where no embedded texture data is provided.
*
* The default value is false (0)
* Property type: bool
*/
#define AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES \
"IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES"
// ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported

View File

@ -48,6 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATERIAL_INL_INC
#define AI_MATERIAL_INL_INC
// ---------------------------------------------------------------------------
inline aiPropertyTypeInfo ai_real_to_property_type_info(float)
{
return aiPTI_Float;
}
inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
{
return aiPTI_Double;
}
// ---------------------------------------------------------------------------
//! @cond never
// ---------------------------------------------------------------------------
@ -223,7 +235,7 @@ inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
{
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiUVTransform),
pKey,type,index,aiPTI_Float); //TODO could be Double ...
pKey,type,index,ai_real_to_property_type_info(pInput->mRotation));
}
// ---------------------------------------------------------------------------
@ -235,7 +247,7 @@ inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
{
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor4D),
pKey,type,index,aiPTI_Float); //TODO could be Double ...
pKey,type,index,ai_real_to_property_type_info(pInput->a));
}
// ---------------------------------------------------------------------------
@ -247,7 +259,7 @@ inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
{
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor3D),
pKey,type,index,aiPTI_Float); //TODO could be Double ...
pKey,type,index,ai_real_to_property_type_info(pInput->b));
}
// ---------------------------------------------------------------------------
@ -259,7 +271,7 @@ inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
{
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiVector3D),
pKey,type,index,aiPTI_Float); //TODO could be Double ...
pKey,type,index,ai_real_to_property_type_info(pInput->x));
}
// ---------------------------------------------------------------------------

View File

@ -679,7 +679,7 @@ class PyAssimp3DViewer:
logger.info("Loading model:" + path + "...")
if postprocess:
self.scene = pyassimp.load(path, postprocess)
self.scene = pyassimp.load(path, processing=postprocess)
else:
self.scene = pyassimp.load(path)
logger.info("Done.")

View File

@ -98,7 +98,7 @@ class GLRenderer():
logger.info("Loading model:" + path + "...")
if postprocess:
self.scene = pyassimp.load(path, postprocess)
self.scene = pyassimp.load(path, processing=postprocess)
else:
self.scene = pyassimp.load(path)
logger.info("Done.")

View File

@ -20,7 +20,7 @@ def recur_node(node,level = 0):
def main(filename=None):
scene = pyassimp.load(filename, pyassimp.postprocess.aiProcess_Triangulate)
scene = pyassimp.load(filename, processing=pyassimp.postprocess.aiProcess_Triangulate)
#the model we load
print("MODEL:" + filename)

View File

@ -7,8 +7,8 @@ SET (CMAKE_SYSTEM_PROCESSOR "arm64")
SET (SDKVER "7.1")
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain")
SET (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDKVER}.sdk")
SET (CC "${DEVROOT}/usr/bin/llvm-gcc")
SET (CXX "${DEVROOT}/usr/bin/llvm-g++")
SET (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)

View File

@ -53,7 +53,11 @@ public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/3DS/fels.3ds", 0 );
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
return nullptr != scene;
#else
return nullptr == scene;
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
}
};

View File

@ -53,7 +53,11 @@ public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/ASE/ThreeCubesGreen.ASE", 0 );
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
return nullptr != scene;
#else
return nullptr == scene;
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
}
};

View File

@ -66,6 +66,7 @@ TEST_F( BatchLoaderTest, createTest ) {
} catch ( ... ) {
ok = false;
}
EXPECT_TRUE( ok );
}
TEST_F( BatchLoaderTest, validateAccessTest ) {

View File

@ -109,8 +109,8 @@ TEST_F( utObjTools, countComponents_TwoLines_Success ) {
buffer.resize( data.size() );
::memcpy( &buffer[ 0 ], &data[ 0 ], data.size() );
test_parser.setBuffer( buffer );
static const size_t Size = 4096UL;
size_t numComps = test_parser.testGetNumComponentsInDataDefinition();
EXPECT_EQ( 3U, numComps );
}

View File

@ -50,10 +50,8 @@ class utglTFImportExport : public AbstractImportExportBase {
public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glFT/TwoBoxes/TwoBoxes.gltf", 0 );
//return nullptr != scene;
return true;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF/TwoBoxes/TwoBoxes.gltf", 0 );
return nullptr != scene;
}
};