diff --git a/.travis.sh b/.travis.sh
index c2852855f..7161fd28d 100755
--- a/.travis.sh
+++ b/.travis.sh
@@ -5,7 +5,8 @@ function generate()
if [ $ANDROID ]; then
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
-else
+fi
+if [ "$TRAVIS_OS_NAME" = "linux" ]; then
generate \
&& make -j4 \
&& sudo make install \
diff --git a/.travis.yml b/.travis.yml
index 2ee456327..a00e0ce70 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,23 +1,52 @@
+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" = "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)
+ - if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz && tar xf lcov_1.11.orig.tar.gz && sudo make -C lcov-1.11/ install && gem install coveralls-lcov && lcov --version && g++ --version ; fi
+
+branches:
+ only:
+ - master
+
+osx_image: xcode8.3
+
env:
global:
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
-
-before_install:
- - sudo apt-get update -qq
- - sudo apt-get install cmake
- - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
-
-language: cpp
+ - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
+ matrix:
+ - LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON
+ - 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
before_script:
- cmake .
+ # init coverage to 0 (optional)
+ - if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --zerocounters ; fi
script:
- make
+ - export COVERALLS_SERVICE_NAME=travis-ci
+ - export COVERALLS_REPO_TOKEN=abc12345
+ - . ./.travis.sh
+os:
+ - linux
+ - osx
+
+after_success:
+ - if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --capture --output-file coverage.info && lcov --remove coverage.info '/usr/*' 'contrib/*' 'test/*' --output-file coverage.info && lcov --list coverage.info && coveralls-lcov --source-encoding=ISO-8859-1 --repo-token=${COVERALLS_TOKEN} coverage.info ; fi
addons:
coverity_scan:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c1804159..3742eb01a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -89,6 +89,10 @@ OPTION ( BUILD_DOCS
OFF
)
+if (WIN32)
+ add_definitions( -DWIN32_LEAN_AND_MEAN )
+endif()
+
IF(MSVC)
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
OPTION( ASSIMP_INSTALL_PDB
@@ -141,6 +145,13 @@ IF(ASSIMP_DOUBLE_PRECISION)
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
ENDIF(ASSIMP_DOUBLE_PRECISION)
+# Check for OpenMP support
+find_package(OpenMP)
+if (OPENMP_FOUND)
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
+endif()
+
configure_file(
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
${CMAKE_CURRENT_BINARY_DIR}/revision.h
@@ -157,7 +168,7 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}/include
)
-SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" )
+LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" )
SET(LIBASSIMP_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}" )
SET(LIBASSIMP-DEV_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}-dev" )
SET(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
@@ -178,7 +189,7 @@ ENDIF( UNIX )
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
# hide all not-exported symbols
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -std=c++0x")
- SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -fPIC)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
SET(LIBSTDC++_LIBRARIES -lstdc++)
ELSEIF(MSVC)
# enable multi-core compilation with MSVC
diff --git a/Readme.md b/Readme.md
index 2dc024a52..1e8e66b92 100644
--- a/Readme.md
+++ b/Readme.md
@@ -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)
@@ -9,22 +9,19 @@ Open Asset Import Library (assimp)
[![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)
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)
-
-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:
+
[![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)
-__[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:
diff --git a/code/3DSExporter.cpp b/code/3DSExporter.cpp
index 4be83355a..642f7dc57 100644
--- a/code/3DSExporter.cpp
+++ b/code/3DSExporter.cpp
@@ -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
#include "SplitLargeMeshes.h"
#include "StringComparison.h"
#include
diff --git a/code/AMFImporter_Postprocess.cpp b/code/AMFImporter_Postprocess.cpp
index 3a48d3b42..085336c51 100644
--- a/code/AMFImporter_Postprocess.cpp
+++ b/code/AMFImporter_Postprocess.cpp
@@ -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
#include "StandardShapes.h"
#include "StringUtils.h"
diff --git a/code/Assimp.cpp b/code/Assimp.cpp
index 11dd5b939..9269f905e 100644
--- a/code/Assimp.cpp
+++ b/code/Assimp.cpp
@@ -66,8 +66,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------
using namespace Assimp;
-namespace Assimp
-{
+namespace Assimp {
// underlying structure for aiPropertyStore
typedef BatchLoader::PropertyMap PropertyMap;
@@ -110,12 +109,11 @@ static std::mutex gLogStreamMutex;
// ------------------------------------------------------------------------------------------------
// Custom LogStream implementation for the C-API
-class LogToCallbackRedirector : public LogStream
-{
+class LogToCallbackRedirector : public LogStream {
public:
explicit LogToCallbackRedirector(const aiLogStream& s)
- : stream (s) {
- ai_assert(NULL != s.callback);
+ : stream (s) {
+ ai_assert(NULL != s.callback);
}
~LogToCallbackRedirector() {
@@ -146,8 +144,7 @@ private:
};
// ------------------------------------------------------------------------------------------------
-void ReportSceneNotFoundError()
-{
+void ReportSceneNotFoundError() {
DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
"The C-API does not accept scenes produced by the C++ API and vice versa");
@@ -156,22 +153,18 @@ void ReportSceneNotFoundError()
// ------------------------------------------------------------------------------------------------
// Reads the given file and returns its content.
-const aiScene* aiImportFile( const char* pFile, unsigned int pFlags)
-{
+const aiScene* aiImportFile( const char* pFile, unsigned int pFlags) {
return aiImportFileEx(pFile,pFlags,NULL);
}
// ------------------------------------------------------------------------------------------------
-const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS)
-{
+const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS) {
return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
}
// ------------------------------------------------------------------------------------------------
-const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
- aiFileIO* pFS,
- const aiPropertyStore* props)
-{
+const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
+ aiFileIO* pFS, const aiPropertyStore* props) {
ai_assert(NULL != pFile);
const aiScene* scene = NULL;
@@ -190,7 +183,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
pimpl->mMatrixProperties = pp->matrices;
}
// setup a custom IO system if necessary
- if (pFS) {
+ if (pFS) {
imp->SetIOHandler( new CIOSystemWrapper (pFS) );
}
@@ -201,8 +194,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
if( scene) {
ScenePrivateData* priv = const_cast( ScenePriv(scene) );
priv->mOrigImporter = imp;
- }
- else {
+ } else {
// if failed, extract error code and destroy the import
gLastErrorString = imp->GetErrorString();
delete imp;
@@ -210,6 +202,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
// return imported data. If the import failed the pointer is NULL anyways
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+
return scene;
}
diff --git a/code/AssimpCExport.cpp b/code/AssimpCExport.cpp
index d3c3d3298..b8d3264a1 100644
--- a/code/AssimpCExport.cpp
+++ b/code/AssimpCExport.cpp
@@ -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
#include "ScenePrivate.h"
#include
diff --git a/code/BaseImporter.cpp b/code/BaseImporter.cpp
index e8d547783..9598e8e9a 100644
--- a/code/BaseImporter.cpp
+++ b/code/BaseImporter.cpp
@@ -303,24 +303,13 @@ void BaseImporter::GetExtensionList(std::set& extensions)
return false;
}
-#include "../contrib/ConvertUTF/ConvertUTF.h"
-
-// ------------------------------------------------------------------------------------------------
-void ReportResult(ConversionResult res)
-{
- if(res == sourceExhausted) {
- DefaultLogger::get()->error("Source ends with incomplete character sequence, transformation to UTF-8 fails");
- }
- else if(res == sourceIllegal) {
- DefaultLogger::get()->error("Source contains illegal character sequence, transformation to UTF-8 fails");
- }
-}
+#include "../contrib/utf8cpp/source/utf8.h"
// ------------------------------------------------------------------------------------------------
// Convert to UTF8 data
void BaseImporter::ConvertToUTF8(std::vector& data)
{
- ConversionResult result;
+ //ConversionResult result;
if(data.size() < 8) {
throw DeadlyImportError("File is too small");
}
@@ -333,7 +322,8 @@ void BaseImporter::ConvertToUTF8(std::vector& data)
data.resize(data.size()-3);
return;
}
-
+
+
// UTF 32 BE with BOM
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
@@ -347,21 +337,10 @@ void BaseImporter::ConvertToUTF8(std::vector& 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;
- char* dstart,*dend;
std::vector output;
- do {
- output.resize(output.size()?output.size()*3/2:data.size()/2);
- dstart = &output.front(),dend = &output.back()+1;
-
- result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
- } while(result == targetExhausted);
-
- ReportResult(result);
-
- // copy to output buffer.
- const size_t outlen = (size_t)(dstart-&output.front());
- data.assign(output.begin(),output.begin()+outlen);
+ int *ptr = (int*)&data[ 0 ];
+ int *end = ptr + ( data.size() / sizeof(int) ) +1;
+ utf8::utf32to8( ptr, end, back_inserter(output));
return;
}
@@ -378,21 +357,9 @@ void BaseImporter::ConvertToUTF8(std::vector& 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);
- char* dstart,*dend;
- std::vector output;
- do {
- output.resize(output.size()?output.size()*3/2:data.size()*3/4);
- dstart = &output.front(),dend = &output.back()+1;
-
- result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
- } while(result == targetExhausted);
-
- ReportResult(result);
-
- // copy to output buffer.
- const size_t outlen = (size_t)(dstart-&output.front());
- data.assign(output.begin(),output.begin()+outlen);
+ std::vector output;
+ int16_t *ptr = (int16_t*) &data[ 0 ];
+ utf8::utf16to8(data.begin(), data.end(), back_inserter(output));
return;
}
}
diff --git a/code/BaseImporter.h b/code/BaseImporter.h
index 06ed0691f..cee54c1ad 100644
--- a/code/BaseImporter.h
+++ b/code/BaseImporter.h
@@ -61,7 +61,6 @@ class BaseProcess;
class SharedPostProcessInfo;
class IOStream;
-
// utility to do char4 to uint32 in a portable manner
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
(string[1] << 16) + (string[2] << 8) + string[3]))
@@ -194,14 +193,11 @@ public:
const Importer* pImp
);
-
// -------------------------------------------------------------------
/** Called by #Importer::GetImporterInfo to get a description of
* some loader features. Importers must provide this information. */
virtual const aiImporterDesc* GetInfo() const = 0;
-
-
// -------------------------------------------------------------------
/** Called by #Importer::GetExtensionList for each loaded importer.
* Take the extension list contained in the structure returned by
@@ -317,7 +313,7 @@ public: // static utilities
* @param Size of one token, in bytes. Maximally 16 bytes.
* @return true if one of the given tokens was found
*
- * @note For convinence, the check is also performed for the
+ * @note For convenience, the check is also performed for the
* byte-swapped variant of all tokens (big endian). Only for
* tokens of size 2,4.
*/
diff --git a/code/BlenderModifier.cpp b/code/BlenderModifier.cpp
index d71ae5098..161028b6b 100644
--- a/code/BlenderModifier.cpp
+++ b/code/BlenderModifier.cpp
@@ -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
#include "Subdivision.h"
#include
#include
diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt
index de515ba94..82497467a 100644
--- a/code/CMakeLists.txt
+++ b/code/CMakeLists.txt
@@ -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
@@ -695,11 +695,6 @@ SET( Extra_SRCS
)
SOURCE_GROUP( Extra FILES ${Extra_SRCS})
-SET( ConvertUTF_SRCS
- ../contrib/ConvertUTF/ConvertUTF.h
- ../contrib/ConvertUTF/ConvertUTF.c
-)
-SOURCE_GROUP( ConvertUTF FILES ${ConvertUTF_SRCS})
SET( Clipper_SRCS
../contrib/clipper/clipper.hpp
@@ -737,10 +732,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
)
@@ -835,7 +832,6 @@ SET( assimp_src
# Third-party libraries
${IrrXML_SRCS}
- ${ConvertUTF_SRCS}
${unzip_compile_SRCS}
${Poly2Tri_SRCS}
${Clipper_SRCS}
diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp
index 1b8a60883..d701f905a 100644
--- a/code/ColladaExporter.cpp
+++ b/code/ColladaExporter.cpp
@@ -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
#include "StringUtils.h"
#include "XMLTools.h"
#include
diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp
index 457b62c20..5cec0a0c6 100644
--- a/code/ColladaLoader.cpp
+++ b/code/ColladaLoader.cpp
@@ -1726,6 +1726,8 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
const Collada::Effect& pEffect, const std::string& pName)
{
+ aiString result;
+
// recurse through the param references until we end up at an image
std::string name = pName;
while( 1)
@@ -1744,11 +1746,17 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
if( imIt == pParser.mImageLibrary.end())
{
- throw DeadlyImportError( format() <<
- "Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
- }
+ //missing texture should not stop the conversion
+ //throw DeadlyImportError( format() <<
+ // "Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
- aiString result;
+ DefaultLogger::get()->warn("Collada: Unable to resolve effect texture entry \"" + pName + "\", ended up at ID \"" + name + "\".");
+
+ //set default texture file name
+ result.Set(name + ".jpg");
+ ConvertPath(result);
+ return result;
+ }
// if this is an embedded texture image setup an aiTexture for it
if (imIt->second.mFileName.empty())
diff --git a/code/Exporter.cpp b/code/Exporter.cpp
index 5f0e75200..bae4d7f80 100644
--- a/code/Exporter.cpp
+++ b/code/Exporter.cpp
@@ -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
#include "BaseProcess.h"
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
diff --git a/code/HalfLifeFileData.h b/code/HalfLifeFileData.h
index 9a498d14c..3a36d2422 100644
--- a/code/HalfLifeFileData.h
+++ b/code/HalfLifeFileData.h
@@ -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"
diff --git a/code/IFCLoader.cpp b/code/IFCLoader.cpp
index 24c5452b2..463803ab3 100644
--- a/code/IFCLoader.cpp
+++ b/code/IFCLoader.cpp
@@ -882,6 +882,7 @@ void ProcessSpatialStructures(ConversionData& conv)
}
}
+ std::vector nodes;
for(const STEP::LazyObject* lz : *range) {
const IfcSpatialStructureElement* const prod = lz->ToPtr();
@@ -890,20 +891,19 @@ void ProcessSpatialStructures(ConversionData& conv)
}
IFCImporter::LogDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType? " which is of type " + prod->ObjectType.Get():""));
- // the primary site is referenced by an IFCRELAGGREGATES element which assigns it to the IFCPRODUCT
+ // the primary sites are referenced by an IFCRELAGGREGATES element which assigns them to the IFCPRODUCT
const STEP::DB::RefMap& refs = conv.db.GetRefs();
- STEP::DB::RefMapRange range = refs.equal_range(conv.proj.GetID());
- for(;range.first != range.second; ++range.first) {
- if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr()) {
+ STEP::DB::RefMapRange ref_range = refs.equal_range(conv.proj.GetID());
+ for(; ref_range.first != ref_range.second; ++ref_range.first) {
+ if(const IfcRelAggregates* const aggr = conv.db.GetObject((*ref_range.first).second)->ToPtr()) {
for(const IfcObjectDefinition& def : aggr->RelatedObjects) {
// comparing pointer values is not sufficient, we would need to cast them to the same type first
// as there is multiple inheritance in the game.
if (def.GetID() == prod->GetID()) {
IFCImporter::LogDebug("selecting this spatial structure as root structure");
- // got it, this is the primary site.
- conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
- return;
+ // got it, this is one primary site.
+ nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
}
}
@@ -911,19 +911,42 @@ void ProcessSpatialStructures(ConversionData& conv)
}
}
+ size_t nb_nodes = nodes.size();
- IFCImporter::LogWarn("failed to determine primary site element, taking the first IfcSite");
- for(const STEP::LazyObject* lz : *range) {
- const IfcSpatialStructureElement* const prod = lz->ToPtr();
- if(!prod) {
- continue;
- }
+ if (nb_nodes == 0) {
+ IFCImporter::LogWarn("failed to determine primary site element, taking all the IfcSite");
+ for (const STEP::LazyObject* lz : *range) {
+ const IfcSpatialStructureElement* const prod = lz->ToPtr();
+ if (!prod) {
+ continue;
+ }
- conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
- return;
- }
+ nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
+ }
- IFCImporter::ThrowException("failed to determine primary site element");
+ nb_nodes = nodes.size();
+ }
+
+ if (nb_nodes == 1) {
+ conv.out->mRootNode = nodes[0];
+ }
+ else if (nb_nodes > 1) {
+ conv.out->mRootNode = new aiNode("Root");
+ conv.out->mRootNode->mParent = NULL;
+ conv.out->mRootNode->mNumChildren = static_cast(nb_nodes);
+ conv.out->mRootNode->mChildren = new aiNode*[conv.out->mRootNode->mNumChildren];
+
+ for (size_t i = 0; i < nb_nodes; ++i) {
+ aiNode* node = nodes[i];
+
+ node->mParent = conv.out->mRootNode;
+
+ conv.out->mRootNode->mChildren[i] = node;
+ }
+ }
+ else {
+ IFCImporter::ThrowException("failed to determine primary site element");
+ }
}
// ------------------------------------------------------------------------------------------------
diff --git a/code/IOStreamBuffer.h b/code/IOStreamBuffer.h
index d8c7d00ab..6ca37b6eb 100644
--- a/code/IOStreamBuffer.h
+++ b/code/IOStreamBuffer.h
@@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include "ParsingUtils.h"
+#include
+
namespace Assimp {
// ---------------------------------------------------------------------------
@@ -69,8 +71,8 @@ public:
/// @return true if successful.
bool close();
- /// @brief Returns the filesize.
- /// @return The filesize.
+ /// @brief Returns the file-size.
+ /// @return The file-size.
size_t size() const;
/// @brief Returns the cache size.
@@ -96,7 +98,17 @@ public:
/// @brief Will read the next line.
/// @param buffer The buffer for the next line.
/// @return true if successful.
- bool getNextLine( std::vector &buffer );
+ bool getNextDataLine( std::vector &buffer, T continuationToken );
+
+ /// @brief Will read the next line ascii or binary end line char.
+ /// @param buffer The buffer for the next line.
+ /// @return true if successful.
+ bool getNextLine(std::vector &buffer);
+
+ /// @brief Will read the next block.
+ /// @param buffer The buffer for the next block.
+ /// @return true if successful.
+ bool getNextBlock( std::vector &buffer );
private:
IOStream *m_stream;
@@ -227,15 +239,35 @@ size_t IOStreamBuffer::getFilePos() const {
template
inline
-bool IOStreamBuffer::getNextLine( std::vector &buffer ) {
+bool IOStreamBuffer::getNextDataLine( std::vector &buffer, T continuationToken ) {
buffer.resize( m_cacheSize );
if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
if ( !readNextBlock() ) {
return false;
}
}
+
+ bool continuationFound( false ), endOfDataLine( false );
size_t i = 0;
- while ( !IsLineEnd( m_cache[ m_cachePos ] ) ) {
+ while ( !endOfDataLine ) {
+ if ( continuationToken == m_cache[ m_cachePos ] ) {
+ continuationFound = true;
+ ++m_cachePos;
+ }
+ if ( IsLineEnd( m_cache[ m_cachePos ] ) ) {
+ if ( !continuationFound ) {
+ // the end of the data line
+ break;
+ } else {
+ // skip line end
+ while ( m_cache[m_cachePos] != '\n') {
+ ++m_cachePos;
+ }
+ ++m_cachePos;
+ continuationFound = false;
+ }
+ }
+
buffer[ i ] = m_cache[ m_cachePos ];
m_cachePos++;
i++;
@@ -245,10 +277,63 @@ bool IOStreamBuffer::getNextLine( std::vector &buffer ) {
}
}
}
+
buffer[ i ] = '\n';
m_cachePos++;
return true;
}
+template
+inline
+bool IOStreamBuffer::getNextLine(std::vector &buffer) {
+ buffer.resize(m_cacheSize);
+ if (m_cachePos == m_cacheSize || 0 == m_filePos) {
+ if (!readNextBlock()) {
+ return false;
+ }
+ }
+
+ if (IsLineEnd(m_cache[m_cachePos])) {
+ // skip line end
+ while (m_cache[m_cachePos] != '\n') {
+ ++m_cachePos;
+ }
+ ++m_cachePos;
+ }
+
+ size_t i = 0;
+ while (!IsLineEnd(m_cache[m_cachePos])) {
+ buffer[i] = m_cache[m_cachePos];
+ m_cachePos++;
+ i++;
+ if (m_cachePos >= m_cacheSize) {
+ if (!readNextBlock()) {
+ return false;
+ }
+ }
+ }
+ buffer[i] = '\n';
+ m_cachePos++;
+
+ return true;
+}
+
+template
+inline
+bool IOStreamBuffer::getNextBlock( std::vector &buffer) {
+ //just return the last blockvalue if getNextLine was used before
+ if ( m_cachePos != 0) {
+ buffer = std::vector(m_cache.begin() + m_cachePos, m_cache.end());
+ m_cachePos = 0;
+ }
+ else {
+ if ( !readNextBlock() )
+ return false;
+
+ buffer = std::vector(m_cache.begin(), m_cache.end());
+ }
+ return true;
+}
+
} // !ns Assimp
diff --git a/code/IRRLoader.cpp b/code/IRRLoader.cpp
index 0a1edf253..8cc4acaad 100644
--- a/code/IRRLoader.cpp
+++ b/code/IRRLoader.cpp
@@ -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
#include "StandardShapes.h"
#include "Importer.h"
diff --git a/code/IRRLoader.h b/code/IRRLoader.h
index b8f0df918..d07199c0b 100644
--- a/code/IRRLoader.h
+++ b/code/IRRLoader.h
@@ -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
#include "Importer.h"
#include "StringUtils.h"
#include
diff --git a/code/LWOAnimation.cpp b/code/LWOAnimation.cpp
index cbd12fe1a..4862876fc 100644
--- a/code/LWOAnimation.cpp
+++ b/code/LWOAnimation.cpp
@@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers
#include "LWOFileData.h"
+#include
using namespace Assimp;
using namespace Assimp::LWO;
diff --git a/code/LWOAnimation.h b/code/LWOAnimation.h
index 11f71bd93..f0c578ad9 100644
--- a/code/LWOAnimation.h
+++ b/code/LWOAnimation.h
@@ -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
+//
#include
#include
struct aiNodeAnim;
+struct aiVectorKey;
namespace Assimp {
namespace LWO {
@@ -166,7 +167,6 @@ struct Envelope
//! Keyframes for this envelope
std::vector 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& envelopes,
- double tick);
+ AnimResolver(std::list& envelopes, double tick);
public:
diff --git a/code/LWSLoader.cpp b/code/LWSLoader.cpp
index aa05d63c9..302228556 100644
--- a/code/LWSLoader.cpp
+++ b/code/LWSLoader.cpp
@@ -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
#include "GenericProperty.h"
#include "SkeletonMeshBuilder.h"
#include "ConvertToLHProcess.h"
diff --git a/code/LWSLoader.h b/code/LWSLoader.h
index 28b4495df..e36d27b77 100644
--- a/code/LWSLoader.h
+++ b/code/LWSLoader.h
@@ -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
#include "BaseImporter.h"
struct aiImporterDesc;
diff --git a/code/MD3FileData.h b/code/MD3FileData.h
index 262d75322..19740c30e 100644
--- a/code/MD3FileData.h
+++ b/code/MD3FileData.h
@@ -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"
diff --git a/code/MD3Loader.cpp b/code/MD3Loader.cpp
index 8047b82ba..f6a3a85dd 100644
--- a/code/MD3Loader.cpp
+++ b/code/MD3Loader.cpp
@@ -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
#include "GenericProperty.h"
#include "RemoveComments.h"
#include "ParsingUtils.h"
diff --git a/code/MDCFileData.h b/code/MDCFileData.h
index 2ce96db5a..9ea3d8f5e 100644
--- a/code/MDCFileData.h
+++ b/code/MDCFileData.h
@@ -157,7 +157,7 @@ struct Frame
//! Name of the frame
char name [ 16 ] ;
-} PACK_STRUCT;
+} /*PACK_STRUCT*/;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC triangle
diff --git a/code/MDLFileData.h b/code/MDLFileData.h
index 6ba5b5aa2..a691851be 100644
--- a/code/MDLFileData.h
+++ b/code/MDLFileData.h
@@ -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
+#include
+#include
#include "ByteSwapper.h"
-#include "./../include/assimp/anim.h"
-#include "./../include/assimp/mesh.h"
-#include "./../include/assimp/Compiler/pushpack1.h"
#include
#include
@@ -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()
{
diff --git a/code/MMDCpp14.h b/code/MMDCpp14.h
index ad112de0f..f6f81f827 100644
--- a/code/MMDCpp14.h
+++ b/code/MMDCpp14.h
@@ -1,3 +1,43 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2017, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
#pragma once
#ifndef MMD_CPP14_H
diff --git a/code/MMDPmdParser.h b/code/MMDPmdParser.h
index 375c323df..44b64585a 100644
--- a/code/MMDPmdParser.h
+++ b/code/MMDPmdParser.h
@@ -1,3 +1,43 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2017, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
#pragma once
#include
diff --git a/code/MMDPmxParser.cpp b/code/MMDPmxParser.cpp
index 352259df5..6a76c2c7f 100644
--- a/code/MMDPmxParser.cpp
+++ b/code/MMDPmxParser.cpp
@@ -1,7 +1,47 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2017, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
#include
#include "MMDPmxParser.h"
+#include "../contrib/utf8cpp/source/utf8.h"
#include "Exceptional.h"
-#include "../contrib/ConvertUTF/ConvertUTF.h"
namespace pmx
{
@@ -60,15 +100,7 @@ namespace pmx
const unsigned int targetSize = size * 3; // enough to encode
char* targetStart = new char[targetSize]();
const char* targetReserved = targetStart;
- ConversionFlags flags = ConversionFlags::lenientConversion;
-
- ConversionResult conversionResult;
- if( ( conversionResult = ConvertUTF16toUTF8(
- (const UTF16**)&sourceStart, (const UTF16*)(sourceStart + size),
- (UTF8**)&targetStart, (UTF8*)(targetStart + targetSize),
- flags) ) != ConversionResult::conversionOK) {
- throw DeadlyImportError( "Convert " + std::string(sourceStart) + " to UTF8 is not valid." );
- }
+ utf8::utf16to8( sourceStart, sourceStart + size, targetStart );
result.assign(targetReserved, targetStart - targetReserved);
delete[] targetReserved;
diff --git a/code/MMDPmxParser.h b/code/MMDPmxParser.h
index 7cb94b9b6..4aff7f8eb 100644
--- a/code/MMDPmxParser.h
+++ b/code/MMDPmxParser.h
@@ -1,3 +1,43 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2017, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
#pragma once
#include
diff --git a/code/MMDVmdParser.h b/code/MMDVmdParser.h
index 380a10c5d..c5057ef47 100644
--- a/code/MMDVmdParser.h
+++ b/code/MMDVmdParser.h
@@ -1,3 +1,43 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2017, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
#pragma once
#include
diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp
index b246dc5e5..bd73a88d9 100644
--- a/code/ObjFileParser.cpp
+++ b/code/ObjFileParser.cpp
@@ -64,7 +64,7 @@ ObjFileParser::ObjFileParser()
, m_uiLine( 0 )
, m_pIO( nullptr )
, m_progress( nullptr )
-, m_originalObjFileName( "" ) {
+, m_originalObjFileName() {
// empty
}
@@ -109,28 +109,6 @@ ObjFile::Model *ObjFileParser::GetModel() const {
return m_pModel;
}
-void ignoreNewLines(IOStreamBuffer &streamBuffer, std::vector &buffer)
-{
- auto curPosition = buffer.begin();
- do
- {
- while (*curPosition!='\n'&&*curPosition!='\\')
- {
- ++curPosition;
- }
- if (*curPosition=='\\')
- {
- std::vector tempBuf;
- do
- {
- streamBuffer.getNextLine(tempBuf);
- } while (tempBuf[0]=='\n');
- *curPosition = ' ';
- std::copy(tempBuf.cbegin(), tempBuf.cend(), ++curPosition);
- }
- } while (*curPosition!='\n');
-}
-
void ObjFileParser::parseFile( IOStreamBuffer &streamBuffer ) {
// only update every 100KB or it'll be too slow
//const unsigned int updateProgressEveryBytes = 100 * 1024;
@@ -142,7 +120,7 @@ void ObjFileParser::parseFile( IOStreamBuffer &streamBuffer ) {
size_t lastFilePos( 0 );
std::vector buffer;
- while ( streamBuffer.getNextLine( buffer ) ) {
+ while ( streamBuffer.getNextDataLine( buffer, '\\' ) ) {
m_DataIt = buffer.begin();
m_DataItEnd = buffer.end();
@@ -154,14 +132,14 @@ void ObjFileParser::parseFile( IOStreamBuffer &streamBuffer ) {
progressCounter++;
m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
}
- //ignoreNewLines(streamBuffer, buffer);
+
// parse line
switch (*m_DataIt) {
case 'v': // Parse a vertex texture coordinate
{
++m_DataIt;
if (*m_DataIt == ' ' || *m_DataIt == '\t') {
- size_t numComponents = getNumComponentsInLine();
+ size_t numComponents = getNumComponentsInDataDefinition();
if (numComponents == 3) {
// read in vertex definition
getVector3(m_pModel->m_Vertices);
@@ -245,7 +223,6 @@ void ObjFileParser::parseFile( IOStreamBuffer &streamBuffer ) {
default:
{
pf_skip_line:
-
m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine );
}
break;
@@ -274,21 +251,44 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
pBuffer[index] = '\0';
}
-size_t ObjFileParser::getNumComponentsInLine() {
+static bool isDataDefinitionEnd( const char *tmp ) {
+ if ( *tmp == '\\' ) {
+ tmp++;
+ if ( IsLineEnd( *tmp ) ) {
+ tmp++;
+ return true;
+ }
+ }
+ return false;
+}
+
+size_t ObjFileParser::getNumComponentsInDataDefinition() {
size_t numComponents( 0 );
const char* tmp( &m_DataIt[0] );
- while( !IsLineEnd( *tmp ) ) {
+ bool end_of_definition = false;
+ while ( !end_of_definition ) {
+ if ( isDataDefinitionEnd( tmp ) ) {
+ tmp += 2;
+ } else if ( IsLineEnd( *tmp ) ) {
+ end_of_definition = true;
+ }
if ( !SkipSpaces( &tmp ) ) {
break;
}
+ const bool isNum( IsNumeric( *tmp ) );
SkipToken( tmp );
- ++numComponents;
+ if ( isNum ) {
+ ++numComponents;
+ }
+ if ( !SkipSpaces( &tmp ) ) {
+ break;
+ }
}
return numComponents;
}
void ObjFileParser::getVector( std::vector &point3d_array ) {
- size_t numComponents = getNumComponentsInLine();
+ size_t numComponents = getNumComponentsInDataDefinition();
ai_real x, y, z;
if( 2 == numComponents ) {
copyNextWord( m_buffer, Buffersize );
@@ -397,10 +397,6 @@ static const std::string DefaultObjName = "defaultobject";
// -------------------------------------------------------------------
// Get values for a new face instance
void ObjFileParser::getFace( aiPrimitiveType type ) {
- //copyNextLine(m_buffer, Buffersize);
- //char *pPtr = m_DataIt;
- //char *pPtr = m_buffer;
- //char *pEnd = &pPtr[Buffersize];
m_DataIt = getNextToken( m_DataIt, m_DataItEnd );
if ( m_DataIt == m_DataItEnd || *m_DataIt == '\0' ) {
return;
@@ -571,14 +567,7 @@ void ObjFileParser::getMaterialDesc() {
// -------------------------------------------------------------------
// Get a comment, values will be skipped
void ObjFileParser::getComment() {
- while (m_DataIt != m_DataItEnd) {
- if ( '\n' == (*m_DataIt)) {
- ++m_DataIt;
- break;
- } else {
- ++m_DataIt;
- }
- }
+ m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine );
}
// -------------------------------------------------------------------
diff --git a/code/ObjFileParser.h b/code/ObjFileParser.h
index ed8e7a032..fa5b3ca31 100644
--- a/code/ObjFileParser.h
+++ b/code/ObjFileParser.h
@@ -91,6 +91,8 @@ protected:
void copyNextWord(char *pBuffer, size_t length);
/// Method to copy the new line.
// void copyNextLine(char *pBuffer, size_t length);
+ /// Get the number of components in a line.
+ size_t getNumComponentsInDataDefinition();
/// Stores the vector
void getVector( std::vector &point3d_array );
/// Stores the following 3d vector.
@@ -129,8 +131,6 @@ protected:
bool needsNewMesh( const std::string &rMaterialName );
/// Error report in token
void reportErrorTokenInFace();
- /// Get the number of components in a line.
- size_t getNumComponentsInLine();
private:
// Copy and assignment constructor should be private
@@ -154,9 +154,8 @@ private:
IOSystem *m_pIO;
//! Pointer to progress handler
ProgressHandler* m_progress;
- /// Path to the current model
- // name of the obj file where the buffer comes from
- const std::string& m_originalObjFileName;
+ /// Path to the current model, name of the obj file where the buffer comes from
+ const std::string m_originalObjFileName;
};
} // Namespace Assimp
diff --git a/code/ObjTools.h b/code/ObjTools.h
index 7b0bdcedf..7236cedc0 100644
--- a/code/ObjTools.h
+++ b/code/ObjTools.h
@@ -116,14 +116,16 @@ inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
++it;
}
- if ( it != end )
- {
+
+ if ( it != end ) {
++it;
++uiLine;
}
// fix .. from time to time there are spaces at the beginning of a material line
- while ( it != end && (*it == '\t' || *it == ' ') )
+ while ( it != end && ( *it == '\t' || *it == ' ' ) ) {
++it;
+ }
+
return it;
}
diff --git a/code/OptimizeGraph.cpp b/code/OptimizeGraph.cpp
index 8b3df0820..04971af5e 100644
--- a/code/OptimizeGraph.cpp
+++ b/code/OptimizeGraph.cpp
@@ -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
#include "Exceptional.h"
#include
diff --git a/code/OptimizeMeshes.cpp b/code/OptimizeMeshes.cpp
index efbd51bd0..65a3cadce 100644
--- a/code/OptimizeMeshes.cpp
+++ b/code/OptimizeMeshes.cpp
@@ -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
#include "Exceptional.h"
using namespace Assimp;
diff --git a/code/PlyExporter.h b/code/PlyExporter.h
index ce242692c..d1d4eafbb 100644
--- a/code/PlyExporter.h
+++ b/code/PlyExporter.h
@@ -51,14 +51,12 @@ struct aiScene;
struct aiNode;
struct aiMesh;
-namespace Assimp
-{
+namespace Assimp {
// ------------------------------------------------------------------------------------------------
/** Helper class to export a given scene to a Stanford Ply file. */
// ------------------------------------------------------------------------------------------------
-class PlyExporter
-{
+class PlyExporter {
public:
/// The class constructor for a specific scene to export
PlyExporter(const char* filename, const aiScene* pScene, bool binary = false);
diff --git a/code/PlyLoader.cpp b/code/PlyLoader.cpp
index 7cfa06727..b62b373d5 100644
--- a/code/PlyLoader.cpp
+++ b/code/PlyLoader.cpp
@@ -5,7 +5,6 @@ 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,
@@ -13,18 +12,18 @@ 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.
+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.
+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.
+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
@@ -48,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers
#include "PlyLoader.h"
+#include "IOStreamBuffer.h"
#include "Macros.h"
#include
#include
@@ -57,16 +57,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
static const aiImporterDesc desc = {
- "Stanford Polygon Library (PLY) Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "ply"
+ "Stanford Polygon Library (PLY) Importer",
+ "",
+ "",
+ "",
+ aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportTextFlavour,
+ 0,
+ 0,
+ 0,
+ 0,
+ "ply"
};
@@ -74,1040 +74,984 @@ static const aiImporterDesc desc = {
// Internal stuff
namespace
{
- // ------------------------------------------------------------------------------------------------
- // Checks that property index is within range
- template
- const T &GetProperty(const std::vector &props, int idx)
- {
- if( static_cast< size_t >( idx ) >= props.size() ) {
- throw DeadlyImportError( "Invalid .ply file: Property index is out of range." );
- }
-
- return props[idx];
+ // ------------------------------------------------------------------------------------------------
+ // Checks that property index is within range
+ template
+ const T &GetProperty(const std::vector &props, int idx)
+ {
+ if (static_cast(idx) >= props.size()) {
+ throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
}
+
+ return props[idx];
+ }
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
PLYImporter::PLYImporter()
-: mBuffer()
-, pcDOM(){
- // empty
+ : mBuffer()
+ , pcDOM()
+ , mGeneratedMesh(NULL){
+ // empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
PLYImporter::~PLYImporter() {
- // empty
+ // empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
-bool PLYImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
+bool PLYImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
- const std::string extension = GetExtension(pFile);
+ const std::string extension = GetExtension(pFile);
- if (extension == "ply")
- return true;
- else if (!extension.length() || checkSig)
- {
- if (!pIOHandler)return true;
- const char* tokens[] = {"ply"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
+ if (extension == "ply")
+ return true;
+ else if (!extension.length() || checkSig)
+ {
+ if (!pIOHandler)return true;
+ const char* tokens[] = { "ply" };
+ return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
+ }
+ return false;
}
// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* PLYImporter::GetInfo () const
+const aiImporterDesc* PLYImporter::GetInfo() const
{
- return &desc;
+ return &desc;
}
// ------------------------------------------------------------------------------------------------
-static bool isBigEndian( const char* szMe ) {
- ai_assert( NULL != szMe );
+static bool isBigEndian(const char* szMe) {
+ ai_assert(NULL != szMe);
- // binary_little_endian
- // binary_big_endian
- bool isBigEndian( false );
+ // binary_little_endian
+ // binary_big_endian
+ bool isBigEndian(false);
#if (defined AI_BUILD_BIG_ENDIAN)
- if ( 'l' == *szMe || 'L' == *szMe ) {
- isBigEndian = true;
-}
+ if ( 'l' == *szMe || 'L' == *szMe ) {
+ isBigEndian = true;
+ }
#else
- if ( 'b' == *szMe || 'B' == *szMe ) {
- isBigEndian = true;
- }
+ if ('b' == *szMe || 'B' == *szMe) {
+ isBigEndian = true;
+ }
#endif // ! AI_BUILD_BIG_ENDIAN
- return isBigEndian;
+ return isBigEndian;
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
-void PLYImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
+void PLYImporter::InternReadFile(const std::string& pFile,
+ aiScene* pScene, IOSystem* pIOHandler)
{
- std::unique_ptr file( pIOHandler->Open( pFile));
+ static const std::string mode = "rb";
+ std::unique_ptr fileStream(pIOHandler->Open(pFile, mode));
+ if (!fileStream.get()) {
+ throw DeadlyImportError("Failed to open file " + pFile + ".");
+ }
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open PLY file " + pFile + ".");
+ // Get the file-size
+ size_t fileSize = fileStream->FileSize();
+
+ IOStreamBuffer streamedBuffer(1024 * 1024);
+ streamedBuffer.open(fileStream.get());
+
+ // the beginning of the file must be PLY - magic, magic
+ std::vector headerCheck;
+ streamedBuffer.getNextLine(headerCheck);
+
+ if ((headerCheck.size() >= 3) && (headerCheck[0] != 'P' && headerCheck[0] != 'p') ||
+ (headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
+ (headerCheck[2] != 'Y' && headerCheck[2] != 'y'))
+ {
+ streamedBuffer.close();
+ throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there");
+ }
+
+ std::vector mBuffer2;
+ streamedBuffer.getNextLine(mBuffer2);
+ mBuffer = (unsigned char*)&mBuffer2[0];
+
+ char* szMe = (char*)&this->mBuffer[0];
+ SkipSpacesAndLineEnd(szMe, (const char**)&szMe);
+
+ // determine the format of the file data and construct the aimesh
+ PLY::DOM sPlyDom;
+ this->pcDOM = &sPlyDom;
+
+ if (TokenMatch(szMe, "format", 6)) {
+ if (TokenMatch(szMe, "ascii", 5)) {
+ SkipLine(szMe, (const char**)&szMe);
+ if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this))
+ {
+ if (mGeneratedMesh != NULL)
+ delete(mGeneratedMesh);
+
+ streamedBuffer.close();
+ throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#1)");
+ }
}
+ else if (!::strncmp(szMe, "binary_", 7))
+ {
+ szMe += 7;
+ const bool bIsBE(isBigEndian(szMe));
- // allocate storage and copy the contents of the file to a memory buffer
- std::vector mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- mBuffer = (unsigned char*)&mBuffer2[0];
+ // skip the line, parse the rest of the header and build the DOM
+ if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE))
+ {
+ if (mGeneratedMesh != NULL)
+ delete(mGeneratedMesh);
- // the beginning of the file must be PLY - magic, magic
- if ((mBuffer[0] != 'P' && mBuffer[0] != 'p') ||
- (mBuffer[1] != 'L' && mBuffer[1] != 'l') ||
- (mBuffer[2] != 'Y' && mBuffer[2] != 'y')) {
- throw DeadlyImportError( "Invalid .ply file: Magic number \'ply\' is no there");
- }
-
- char* szMe = (char*)&this->mBuffer[3];
- SkipSpacesAndLineEnd(szMe,(const char**)&szMe);
-
- // determine the format of the file data
- PLY::DOM sPlyDom;
- if (TokenMatch(szMe,"format",6)) {
- if (TokenMatch(szMe,"ascii",5)) {
- SkipLine(szMe,(const char**)&szMe);
- if(!PLY::DOM::ParseInstance(szMe,&sPlyDom))
- throw DeadlyImportError( "Invalid .ply file: Unable to build DOM (#1)");
- } else if (!::strncmp(szMe,"binary_",7))
- {
- szMe += 7;
- const bool bIsBE( isBigEndian( szMe ) );
-
- // skip the line, parse the rest of the header and build the DOM
- SkipLine(szMe,(const char**)&szMe);
- if ( !PLY::DOM::ParseInstanceBinary( szMe, &sPlyDom, bIsBE ) ) {
- throw DeadlyImportError( "Invalid .ply file: Unable to build DOM (#2)" );
- }
- } else {
- throw DeadlyImportError( "Invalid .ply file: Unknown file format" );
- }
+ streamedBuffer.close();
+ throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)");
+ }
}
else
{
- AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
- throw DeadlyImportError( "Invalid .ply file: Missing format specification");
+ if (mGeneratedMesh != NULL)
+ delete(mGeneratedMesh);
+
+ streamedBuffer.close();
+ throw DeadlyImportError("Invalid .ply file: Unknown file format");
}
- this->pcDOM = &sPlyDom;
+ }
+ else
+ {
+ AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
+ if (mGeneratedMesh != NULL)
+ delete(mGeneratedMesh);
- // now load a list of vertices. This must be successfully in order to procedure
- std::vector avPositions;
- this->LoadVertices(&avPositions,false);
+ streamedBuffer.close();
+ throw DeadlyImportError("Invalid .ply file: Missing format specification");
+ }
- if ( avPositions.empty() ) {
- throw DeadlyImportError( "Invalid .ply file: No vertices found. "
- "Unable to parse the data format of the PLY file." );
- }
+ //free the file buffer
+ streamedBuffer.close();
- // now load a list of normals.
- std::vector avNormals;
- LoadVertices(&avNormals,true);
+ if (mGeneratedMesh == NULL)
+ {
+ throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data ");
+ }
- // load the face list
- std::vector avFaces;
- LoadFaces(&avFaces);
-
- // if no face list is existing we assume that the vertex
- // list is containing a list of triangles
- if (avFaces.empty())
+ // if no face list is existing we assume that the vertex
+ // list is containing a list of points
+ bool pointsOnly = mGeneratedMesh->mFaces == NULL ? true : false;
+ if (pointsOnly)
+ {
+ if (mGeneratedMesh->mNumVertices < 3)
{
- if (avPositions.size() < 3)
- {
- throw DeadlyImportError( "Invalid .ply file: Not enough "
- "vertices to build a proper face list. ");
- }
+ if (mGeneratedMesh != NULL)
+ delete(mGeneratedMesh);
- const unsigned int iNum = (unsigned int)avPositions.size() / 3;
- for (unsigned int i = 0; i< iNum;++i)
- {
- PLY::Face sFace;
- sFace.mIndices.push_back((iNum*3));
- sFace.mIndices.push_back((iNum*3)+1);
- sFace.mIndices.push_back((iNum*3)+2);
- avFaces.push_back(sFace);
- }
+ streamedBuffer.close();
+ throw DeadlyImportError("Invalid .ply file: Not enough "
+ "vertices to build a proper face list. ");
}
- // now load a list of all materials
- std::vector avMaterials;
- LoadMaterial(&avMaterials);
+ const unsigned int iNum = (unsigned int)mGeneratedMesh->mNumVertices / 3;
+ mGeneratedMesh->mNumFaces = iNum;
+ mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
- // now load a list of all vertex color channels
- std::vector avColors;
- avColors.reserve(avPositions.size());
- LoadVertexColor(&avColors);
-
- // now try to load texture coordinates
- std::vector avTexCoords;
- avTexCoords.reserve(avPositions.size());
- LoadTextureCoordinates(&avTexCoords);
-
- // now replace the default material in all faces and validate all material indices
- ReplaceDefaultMaterial(&avFaces,&avMaterials);
-
- // now convert this to a list of aiMesh instances
- std::vector avMeshes;
- avMeshes.reserve(avMaterials.size()+1);
- ConvertMeshes(&avFaces,&avPositions,&avNormals,
- &avColors,&avTexCoords,&avMaterials,&avMeshes);
-
- if ( avMeshes.empty() ) {
- throw DeadlyImportError( "Invalid .ply file: Unable to extract mesh data " );
+ for (unsigned int i = 0; i < iNum; ++i)
+ {
+ mGeneratedMesh->mFaces[i].mNumIndices = 3;
+ mGeneratedMesh->mFaces[i].mIndices = new unsigned int[3];
+ mGeneratedMesh->mFaces[i].mIndices[0] = (i * 3);
+ mGeneratedMesh->mFaces[i].mIndices[1] = (i * 3) + 1;
+ mGeneratedMesh->mFaces[i].mIndices[2] = (i * 3) + 2;
}
+ }
- // now generate the output scene object. Fill the material list
- pScene->mNumMaterials = (unsigned int)avMaterials.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for ( unsigned int i = 0; i < pScene->mNumMaterials; ++i ) {
- pScene->mMaterials[ i ] = avMaterials[ i ];
- }
+ // now load a list of all materials
+ std::vector avMaterials;
+ std::string defaultTexture;
+ LoadMaterial(&avMaterials, defaultTexture, pointsOnly);
- // fill the mesh list
- pScene->mNumMeshes = (unsigned int)avMeshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for ( unsigned int i = 0; i < pScene->mNumMeshes; ++i ) {
- pScene->mMeshes[ i ] = avMeshes[ i ];
- }
+ // now generate the output scene object. Fill the material list
+ pScene->mNumMaterials = (unsigned int)avMaterials.size();
+ pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
+ for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
+ pScene->mMaterials[i] = avMaterials[i];
+ }
- // generate a simple node structure
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
+ // fill the mesh list
+ pScene->mNumMeshes = 1;
+ pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
+ pScene->mMeshes[0] = mGeneratedMesh;
- for ( unsigned int i = 0; i < pScene->mRootNode->mNumMeshes; ++i ) {
- pScene->mRootNode->mMeshes[ i ] = i;
- }
+ // generate a simple node structure
+ pScene->mRootNode = new aiNode();
+ pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
+ pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
+
+ for (unsigned int i = 0; i < pScene->mRootNode->mNumMeshes; ++i) {
+ pScene->mRootNode->mMeshes[i] = i;
+ }
}
-// ------------------------------------------------------------------------------------------------
-// Split meshes by material IDs
-void PLYImporter::ConvertMeshes(std::vector* avFaces,
- const std::vector* avPositions,
- const std::vector* avNormals,
- const std::vector* avColors,
- const std::vector* avTexCoords,
- const std::vector* avMaterials,
- std::vector* avOut)
+void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
{
- ai_assert(NULL != avFaces);
- ai_assert(NULL != avPositions);
- ai_assert(NULL != avMaterials);
+ ai_assert(NULL != pcElement);
+ ai_assert(NULL != instElement);
- // split by materials
- std::vector* aiSplit = new std::vector[avMaterials->size()];
+ ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
- unsigned int iNum = 0;
- for (std::vector::const_iterator i = avFaces->begin();i != avFaces->end();++i,++iNum)
- aiSplit[(*i).iMaterialIndex].push_back(iNum);
+ ai_uint aiNormal[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ PLY::EDataType aiNormalTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
- // now generate sub-meshes
- for (unsigned int p = 0; p < avMaterials->size();++p)
+ unsigned int aiColors[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ PLY::EDataType aiColorsTypes[4] = { EDT_Char, EDT_Char, EDT_Char, EDT_Char };
+
+ unsigned int aiTexcoord[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
+ PLY::EDataType aiTexcoordTypes[2] = { EDT_Char, EDT_Char };
+
+ unsigned int cnt = 0;
+
+ // now check whether which normal components are available
+ unsigned int _a = 0;
+ for (std::vector::const_iterator a = pcElement->alProperties.begin();
+ a != pcElement->alProperties.end(); ++a, ++_a)
+ {
+ if ((*a).bIsList)continue;
+
+ // Positions
+ if (PLY::EST_XCoord == (*a).Semantic)
{
- if (aiSplit[p].size() != 0)
- {
- // allocate the mesh object
- aiMesh* p_pcOut = new aiMesh();
- p_pcOut->mMaterialIndex = p;
-
- p_pcOut->mNumFaces = (unsigned int)aiSplit[p].size();
- p_pcOut->mFaces = new aiFace[aiSplit[p].size()];
-
- // at first we need to determine the size of the output vector array
- unsigned int iNum = 0;
- for (unsigned int i = 0; i < aiSplit[p].size();++i)
- {
- iNum += (unsigned int)(*avFaces)[aiSplit[p][i]].mIndices.size();
- }
- p_pcOut->mNumVertices = iNum;
- if( 0 == iNum ) { // nothing to do
- delete[] aiSplit; // cleanup
- delete p_pcOut;
- return;
- }
- p_pcOut->mVertices = new aiVector3D[iNum];
-
- if (!avColors->empty())
- p_pcOut->mColors[0] = new aiColor4D[iNum];
- if (!avTexCoords->empty())
- {
- p_pcOut->mNumUVComponents[0] = 2;
- p_pcOut->mTextureCoords[0] = new aiVector3D[iNum];
- }
- if (!avNormals->empty())
- p_pcOut->mNormals = new aiVector3D[iNum];
-
- // add all faces
- iNum = 0;
- unsigned int iVertex = 0;
- for (std::vector::const_iterator i = aiSplit[p].begin();
- i != aiSplit[p].end();++i,++iNum)
- {
- p_pcOut->mFaces[iNum].mNumIndices = (unsigned int)(*avFaces)[*i].mIndices.size();
- p_pcOut->mFaces[iNum].mIndices = new unsigned int[p_pcOut->mFaces[iNum].mNumIndices];
-
- // build an unique set of vertices/colors for this face
- for (unsigned int q = 0; q < p_pcOut->mFaces[iNum].mNumIndices;++q)
- {
- p_pcOut->mFaces[iNum].mIndices[q] = iVertex;
- const size_t idx = ( *avFaces )[ *i ].mIndices[ q ];
- if( idx >= ( *avPositions ).size() ) {
- // out of border
- continue;
- }
- p_pcOut->mVertices[ iVertex ] = ( *avPositions )[ idx ];
-
- if (!avColors->empty())
- p_pcOut->mColors[ 0 ][ iVertex ] = ( *avColors )[ idx ];
-
- if (!avTexCoords->empty())
- {
- const aiVector2D& vec = ( *avTexCoords )[ idx ];
- p_pcOut->mTextureCoords[0][iVertex].x = vec.x;
- p_pcOut->mTextureCoords[0][iVertex].y = vec.y;
- }
-
- if (!avNormals->empty())
- p_pcOut->mNormals[ iVertex ] = ( *avNormals )[ idx ];
- iVertex++;
- }
-
- }
- // add the mesh to the output list
- avOut->push_back(p_pcOut);
- }
+ cnt++;
+ aiPositions[0] = _a;
+ aiTypes[0] = (*a).eType;
}
- delete[] aiSplit; // cleanup
+ else if (PLY::EST_YCoord == (*a).Semantic)
+ {
+ cnt++;
+ aiPositions[1] = _a;
+ aiTypes[1] = (*a).eType;
+ }
+ else if (PLY::EST_ZCoord == (*a).Semantic)
+ {
+ cnt++;
+ aiPositions[2] = _a;
+ aiTypes[2] = (*a).eType;
+ }
+
+ // Normals
+ else if (PLY::EST_XNormal == (*a).Semantic)
+ {
+ cnt++;
+ aiNormal[0] = _a;
+ aiNormalTypes[0] = (*a).eType;
+ }
+ else if (PLY::EST_YNormal == (*a).Semantic)
+ {
+ cnt++;
+ aiNormal[1] = _a;
+ aiNormalTypes[1] = (*a).eType;
+ }
+ else if (PLY::EST_ZNormal == (*a).Semantic)
+ {
+ cnt++;
+ aiNormal[2] = _a;
+ aiNormalTypes[2] = (*a).eType;
+ }
+ // Colors
+ else if (PLY::EST_Red == (*a).Semantic)
+ {
+ cnt++;
+ aiColors[0] = _a;
+ aiColorsTypes[0] = (*a).eType;
+ }
+ else if (PLY::EST_Green == (*a).Semantic)
+ {
+ cnt++;
+ aiColors[1] = _a;
+ aiColorsTypes[1] = (*a).eType;
+ }
+ else if (PLY::EST_Blue == (*a).Semantic)
+ {
+ cnt++;
+ aiColors[2] = _a;
+ aiColorsTypes[2] = (*a).eType;
+ }
+ else if (PLY::EST_Alpha == (*a).Semantic)
+ {
+ cnt++;
+ aiColors[3] = _a;
+ aiColorsTypes[3] = (*a).eType;
+ }
+ // Texture coordinates
+ else if (PLY::EST_UTextureCoord == (*a).Semantic)
+ {
+ cnt++;
+ aiTexcoord[0] = _a;
+ aiTexcoordTypes[0] = (*a).eType;
+ }
+ else if (PLY::EST_VTextureCoord == (*a).Semantic)
+ {
+ cnt++;
+ aiTexcoord[1] = _a;
+ aiTexcoordTypes[1] = (*a).eType;
+ }
+ }
+
+ // check whether we have a valid source for the vertex data
+ if (0 != cnt)
+ {
+ // Position
+ aiVector3D vOut;
+ if (0xFFFFFFFF != aiPositions[0])
+ {
+ vOut.x = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, aiPositions[0]).avList.front(), aiTypes[0]);
+ }
+
+ if (0xFFFFFFFF != aiPositions[1])
+ {
+ vOut.y = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, aiPositions[1]).avList.front(), aiTypes[1]);
+ }
+
+ if (0xFFFFFFFF != aiPositions[2])
+ {
+ vOut.z = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, aiPositions[2]).avList.front(), aiTypes[2]);
+ }
+
+ // Normals
+ aiVector3D nOut;
+ bool haveNormal = false;
+ if (0xFFFFFFFF != aiNormal[0])
+ {
+ nOut.x = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, aiNormal[0]).avList.front(), aiNormalTypes[0]);
+ haveNormal = true;
+ }
+
+ if (0xFFFFFFFF != aiNormal[1])
+ {
+ nOut.y = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, aiNormal[1]).avList.front(), aiNormalTypes[1]);
+ haveNormal = true;
+ }
+
+ if (0xFFFFFFFF != aiNormal[2])
+ {
+ nOut.z = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, aiNormal[2]).avList.front(), aiNormalTypes[2]);
+ haveNormal = true;
+ }
+
+ //Colors
+ aiColor4D cOut;
+ bool haveColor = false;
+ if (0xFFFFFFFF != aiColors[0])
+ {
+ cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
+ aiColors[0]).avList.front(), aiColorsTypes[0]);
+ haveColor = true;
+ }
+
+ if (0xFFFFFFFF != aiColors[1])
+ {
+ cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
+ aiColors[1]).avList.front(), aiColorsTypes[1]);
+ haveColor = true;
+ }
+
+ if (0xFFFFFFFF != aiColors[2])
+ {
+ cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
+ aiColors[2]).avList.front(), aiColorsTypes[2]);
+ haveColor = true;
+ }
+
+ // assume 1.0 for the alpha channel ifit is not set
+ if (0xFFFFFFFF == aiColors[3])
+ {
+ cOut.a = 1.0;
+ }
+ else
+ {
+ cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
+ aiColors[3]).avList.front(), aiColorsTypes[3]);
+
+ haveColor = true;
+ }
+
+ //Texture coordinates
+ aiVector3D tOut;
+ tOut.z = 0;
+ bool haveTextureCoords = false;
+ if (0xFFFFFFFF != aiTexcoord[0])
+ {
+ tOut.x = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, aiTexcoord[0]).avList.front(), aiTexcoordTypes[0]);
+ haveTextureCoords = true;
+ }
+
+ if (0xFFFFFFFF != aiTexcoord[1])
+ {
+ tOut.y = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, aiTexcoord[1]).avList.front(), aiTexcoordTypes[1]);
+ haveTextureCoords = true;
+ }
+
+ //create aiMesh if needed
+ if (mGeneratedMesh == NULL)
+ {
+ mGeneratedMesh = new aiMesh();
+ mGeneratedMesh->mMaterialIndex = 0;
+ }
+
+ if (mGeneratedMesh->mVertices == NULL)
+ {
+ mGeneratedMesh->mNumVertices = pcElement->NumOccur;
+ mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices];
+ }
+
+ mGeneratedMesh->mVertices[pos] = vOut;
+
+ if (haveNormal)
+ {
+ if (mGeneratedMesh->mNormals == NULL)
+ mGeneratedMesh->mNormals = new aiVector3D[mGeneratedMesh->mNumVertices];
+ mGeneratedMesh->mNormals[pos] = nOut;
+ }
+
+ if (haveColor)
+ {
+ if (mGeneratedMesh->mColors[0] == NULL)
+ mGeneratedMesh->mColors[0] = new aiColor4D[mGeneratedMesh->mNumVertices];
+ mGeneratedMesh->mColors[0][pos] = cOut;
+ }
+
+ if (haveTextureCoords)
+ {
+ if (mGeneratedMesh->mTextureCoords[0] == NULL)
+ {
+ mGeneratedMesh->mNumUVComponents[0] = 2;
+ mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
+ }
+ mGeneratedMesh->mTextureCoords[0][pos] = tOut;
+ }
+ }
}
-// ------------------------------------------------------------------------------------------------
-// Generate a default material if none was specified and apply it to all vanilla faces
-void PLYImporter::ReplaceDefaultMaterial(std::vector* avFaces,
- std::vector* avMaterials)
-{
- bool bNeedDefaultMat = false;
-
- for (std::vector::iterator i = avFaces->begin();i != avFaces->end();++i) {
- if (0xFFFFFFFF == (*i).iMaterialIndex) {
- bNeedDefaultMat = true;
- (*i).iMaterialIndex = (unsigned int)avMaterials->size();
- }
- else if ((*i).iMaterialIndex >= avMaterials->size() ) {
- // clamp the index
- (*i).iMaterialIndex = (unsigned int)avMaterials->size()-1;
- }
- }
-
- if (bNeedDefaultMat) {
- // generate a default material
- aiMaterial* pcHelper = new aiMaterial();
-
- // fill in a default material
- int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.6f;
- pcHelper->AddProperty(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- // The face order is absolutely undefined for PLY, so we have to
- // use two-sided rendering to be sure it's ok.
- const int two_sided = 1;
- pcHelper->AddProperty(&two_sided,1,AI_MATKEY_TWOSIDED);
-
- avMaterials->push_back(pcHelper);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void PLYImporter::LoadTextureCoordinates(std::vector* pvOut)
-{
- ai_assert(NULL != pvOut);
-
- unsigned int aiPositions[2] = {0xFFFFFFFF,0xFFFFFFFF};
- PLY::EDataType aiTypes[2] = {EDT_Char,EDT_Char};
- PLY::ElementInstanceList* pcList = NULL;
- unsigned int cnt = 0;
-
- // search in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector::const_iterator i = pcDOM->alElements.begin();
- i != pcDOM->alElements.end();++i,++_i)
- {
- if (PLY::EEST_Vertex == (*i).eSemantic)
- {
- pcList = &this->pcDOM->alElementData[_i];
-
- // now check whether which normal components are available
- unsigned int _a = 0;
- for (std::vector::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
- if (PLY::EST_UTextureCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- }
- else if (PLY::EST_VTextureCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- }
- }
- }
- }
- // check whether we have a valid source for the texture coordinates data
- if (NULL != pcList && 0 != cnt)
- {
- pvOut->reserve(pcList->alInstances.size());
- for (std::vector::const_iterator i = pcList->alInstances.begin();
- i != pcList->alInstances.end();++i)
- {
- // convert the vertices to sp floats
- aiVector2D vOut;
-
- if (0xFFFFFFFF != aiPositions[0])
- {
- vOut.x = PLY::PropertyInstance::ConvertTo(
- GetProperty((*i).alProperties, aiPositions[0]).avList.front(),aiTypes[0]);
- }
-
- if (0xFFFFFFFF != aiPositions[1])
- {
- vOut.y = PLY::PropertyInstance::ConvertTo(
- GetProperty((*i).alProperties, aiPositions[1]).avList.front(),aiTypes[1]);
- }
- // and add them to our nice list
- pvOut->push_back(vOut);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to extract vertices from the PLY DOM
-void PLYImporter::LoadVertices(std::vector* pvOut, bool p_bNormals)
-{
- ai_assert(NULL != pvOut);
-
- ai_uint aiPositions[3] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
- PLY::EDataType aiTypes[3] = {EDT_Char,EDT_Char,EDT_Char};
- PLY::ElementInstanceList* pcList = NULL;
- unsigned int cnt = 0;
-
- // search in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector::const_iterator i = pcDOM->alElements.begin();
- i != pcDOM->alElements.end();++i,++_i)
- {
- if (PLY::EEST_Vertex == (*i).eSemantic)
- {
- pcList = &pcDOM->alElementData[_i];
-
- // load normal vectors?
- if (p_bNormals)
- {
- // now check whether which normal components are available
- unsigned int _a = 0;
- for (std::vector::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
- if (PLY::EST_XNormal == (*a).Semantic)
- {
- cnt++;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- }
- else if (PLY::EST_YNormal == (*a).Semantic)
- {
- cnt++;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- }
- else if (PLY::EST_ZNormal == (*a).Semantic)
- {
- cnt++;
- aiPositions[2] = _a;
- aiTypes[2] = (*a).eType;
- }
- }
- }
- // load vertex coordinates
- else
- {
- // now check whether which coordinate sets are available
- unsigned int _a = 0;
- for (std::vector::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
- if (PLY::EST_XCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- }
- else if (PLY::EST_YCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- }
- else if (PLY::EST_ZCoord == (*a).Semantic)
- {
- cnt++;
- aiPositions[2] = _a;
- aiTypes[2] = (*a).eType;
- }
- if (3 == cnt)break;
- }
- }
- break;
- }
- }
- // check whether we have a valid source for the vertex data
- if (NULL != pcList && 0 != cnt)
- {
- pvOut->reserve(pcList->alInstances.size());
- for (std::vector::const_iterator
- i = pcList->alInstances.begin();
- i != pcList->alInstances.end();++i)
- {
- // convert the vertices to sp floats
- aiVector3D vOut;
-
- if (0xFFFFFFFF != aiPositions[0])
- {
- vOut.x = PLY::PropertyInstance::ConvertTo(
- GetProperty((*i).alProperties, aiPositions[0]).avList.front(),aiTypes[0]);
- }
-
- if (0xFFFFFFFF != aiPositions[1])
- {
- vOut.y = PLY::PropertyInstance::ConvertTo(
- GetProperty((*i).alProperties, aiPositions[1]).avList.front(),aiTypes[1]);
- }
-
- if (0xFFFFFFFF != aiPositions[2])
- {
- vOut.z = PLY::PropertyInstance::ConvertTo(
- GetProperty((*i).alProperties, aiPositions[2]).avList.front(),aiTypes[2]);
- }
-
- // and add them to our nice list
- pvOut->push_back(vOut);
- }
- }
-}
// ------------------------------------------------------------------------------------------------
// Convert a color component to [0...1]
-ai_real PLYImporter::NormalizeColorValue (PLY::PropertyInstance::ValueUnion val,
- PLY::EDataType eType)
+ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val,
+ PLY::EDataType eType)
{
- switch (eType)
- {
- case EDT_Float:
- return val.fFloat;
- case EDT_Double:
- return (ai_real)val.fDouble;
+ switch (eType)
+ {
+ case EDT_Float:
+ return val.fFloat;
+ case EDT_Double:
+ return (ai_real)val.fDouble;
- case EDT_UChar:
- return (ai_real)val.iUInt / (ai_real)0xFF;
- case EDT_Char:
- return (ai_real)(val.iInt+(0xFF/2)) / (ai_real)0xFF;
- case EDT_UShort:
- return (ai_real)val.iUInt / (ai_real)0xFFFF;
- case EDT_Short:
- return (ai_real)(val.iInt+(0xFFFF/2)) / (ai_real)0xFFFF;
- case EDT_UInt:
- return (ai_real)val.iUInt / (ai_real)0xFFFF;
- case EDT_Int:
- return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
- default: ;
- };
- return 0.0f;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to extract proper vertex colors from the PLY DOM
-void PLYImporter::LoadVertexColor(std::vector* pvOut)
-{
- ai_assert(NULL != pvOut);
-
- unsigned int aiPositions[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
- PLY::EDataType aiTypes[4] = {EDT_Char, EDT_Char, EDT_Char, EDT_Char}; // silencing gcc
- unsigned int cnt = 0;
- PLY::ElementInstanceList* pcList = NULL;
-
- // search in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector::const_iterator i = pcDOM->alElements.begin();
- i != pcDOM->alElements.end();++i,++_i)
- {
- if (PLY::EEST_Vertex == (*i).eSemantic)
- {
- pcList = &this->pcDOM->alElementData[_i];
-
- // now check whether which coordinate sets are available
- unsigned int _a = 0;
- for (std::vector::const_iterator
- a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
- if (PLY::EST_Red == (*a).Semantic)
- {
- cnt++;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- }
- else if (PLY::EST_Green == (*a).Semantic)
- {
- cnt++;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- }
- else if (PLY::EST_Blue == (*a).Semantic)
- {
- cnt++;
- aiPositions[2] = _a;
- aiTypes[2] = (*a).eType;
- }
- else if (PLY::EST_Alpha == (*a).Semantic)
- {
- cnt++;
- aiPositions[3] = _a;
- aiTypes[3] = (*a).eType;
- }
- if (4 == cnt)break;
- }
- break;
- }
- }
- // check whether we have a valid source for the vertex data
- if (NULL != pcList && 0 != cnt)
- {
- pvOut->reserve(pcList->alInstances.size());
- for (std::vector::const_iterator i = pcList->alInstances.begin();
- i != pcList->alInstances.end();++i)
- {
- // convert the vertices to sp floats
- aiColor4D vOut;
-
- if (0xFFFFFFFF != aiPositions[0])
- {
- vOut.r = NormalizeColorValue(GetProperty((*i).alProperties,
- aiPositions[0]).avList.front(),aiTypes[0]);
- }
-
- if (0xFFFFFFFF != aiPositions[1])
- {
- vOut.g = NormalizeColorValue(GetProperty((*i).alProperties,
- aiPositions[1]).avList.front(),aiTypes[1]);
- }
-
- if (0xFFFFFFFF != aiPositions[2])
- {
- vOut.b = NormalizeColorValue(GetProperty((*i).alProperties,
- aiPositions[2]).avList.front(),aiTypes[2]);
- }
-
- // assume 1.0 for the alpha channel ifit is not set
- if (0xFFFFFFFF == aiPositions[3])vOut.a = 1.0;
- else
- {
- vOut.a = NormalizeColorValue(GetProperty((*i).alProperties,
- aiPositions[3]).avList.front(),aiTypes[3]);
- }
-
- // and add them to our nice list
- pvOut->push_back(vOut);
- }
- }
+ case EDT_UChar:
+ return (ai_real)val.iUInt / (ai_real)0xFF;
+ case EDT_Char:
+ return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
+ case EDT_UShort:
+ return (ai_real)val.iUInt / (ai_real)0xFFFF;
+ case EDT_Short:
+ return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
+ case EDT_UInt:
+ return (ai_real)val.iUInt / (ai_real)0xFFFF;
+ case EDT_Int:
+ return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
+ default:;
+ };
+ return 0.0f;
}
// ------------------------------------------------------------------------------------------------
// Try to extract proper faces from the PLY DOM
-void PLYImporter::LoadFaces(std::vector* pvOut)
+void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
{
- ai_assert(NULL != pvOut);
+ ai_assert(NULL != pcElement);
+ ai_assert(NULL != instElement);
- PLY::ElementInstanceList* pcList = NULL;
- bool bOne = false;
+ if (mGeneratedMesh == NULL)
+ throw DeadlyImportError("Invalid .ply file: Vertices shoud be declared before faces");
- // index of the vertex index list
- unsigned int iProperty = 0xFFFFFFFF;
- PLY::EDataType eType = EDT_Char;
- bool bIsTriStrip = false;
+ bool bOne = false;
- // index of the material index property
- unsigned int iMaterialIndex = 0xFFFFFFFF;
- PLY::EDataType eType2 = EDT_Char;
+ // index of the vertex index list
+ unsigned int iProperty = 0xFFFFFFFF;
+ PLY::EDataType eType = EDT_Char;
+ bool bIsTriStrip = false;
- // search in the DOM for a face entry
- unsigned int _i = 0;
- for (std::vector::const_iterator i = pcDOM->alElements.begin();
- i != pcDOM->alElements.end();++i,++_i)
+ // index of the material index property
+ //unsigned int iMaterialIndex = 0xFFFFFFFF;
+ //PLY::EDataType eType2 = EDT_Char;
+
+ // texture coordinates
+ unsigned int iTextureCoord = 0xFFFFFFFF;
+ PLY::EDataType eType3 = EDT_Char;
+
+ // face = unique number of vertex indices
+ if (PLY::EEST_Face == pcElement->eSemantic)
+ {
+ unsigned int _a = 0;
+ for (std::vector::const_iterator a = pcElement->alProperties.begin();
+ a != pcElement->alProperties.end(); ++a, ++_a)
{
- // face = unique number of vertex indices
- if (PLY::EEST_Face == (*i).eSemantic)
- {
- pcList = &pcDOM->alElementData[_i];
- unsigned int _a = 0;
- for (std::vector::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if (PLY::EST_VertexIndex == (*a).Semantic)
- {
- // must be a dynamic list!
- if (!(*a).bIsList)continue;
- iProperty = _a;
- bOne = true;
- eType = (*a).eType;
- }
- else if (PLY::EST_MaterialIndex == (*a).Semantic)
- {
- if ((*a).bIsList)continue;
- iMaterialIndex = _a;
- bOne = true;
- eType2 = (*a).eType;
- }
- }
- break;
- }
- // triangle strip
- // TODO: triangle strip and material index support???
- else if (PLY::EEST_TriStrip == (*i).eSemantic)
- {
- // find a list property in this ...
- pcList = &this->pcDOM->alElementData[_i];
- unsigned int _a = 0;
- for (std::vector::const_iterator a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- // must be a dynamic list!
- if (!(*a).bIsList)continue;
- iProperty = _a;
- bOne = true;
- bIsTriStrip = true;
- eType = (*a).eType;
- break;
- }
- break;
- }
+ if (PLY::EST_VertexIndex == (*a).Semantic)
+ {
+ // must be a dynamic list!
+ if (!(*a).bIsList)
+ continue;
+
+ iProperty = _a;
+ bOne = true;
+ eType = (*a).eType;
+ }
+ /*else if (PLY::EST_MaterialIndex == (*a).Semantic)
+ {
+ if ((*a).bIsList)
+ continue;
+ iMaterialIndex = _a;
+ bOne = true;
+ eType2 = (*a).eType;
+ }*/
+ else if (PLY::EST_TextureCoordinates == (*a).Semantic)
+ {
+ // must be a dynamic list!
+ if (!(*a).bIsList)
+ continue;
+ iTextureCoord = _a;
+ bOne = true;
+ eType3 = (*a).eType;
+ }
}
- // check whether we have at least one per-face information set
- if (pcList && bOne)
+ }
+ // triangle strip
+ // TODO: triangle strip and material index support???
+ else if (PLY::EEST_TriStrip == pcElement->eSemantic)
+ {
+ unsigned int _a = 0;
+ for (std::vector::const_iterator a = pcElement->alProperties.begin();
+ a != pcElement->alProperties.end(); ++a, ++_a)
{
- if (!bIsTriStrip)
- {
- pvOut->reserve(pcList->alInstances.size());
- for (std::vector::const_iterator i = pcList->alInstances.begin();
- i != pcList->alInstances.end();++i)
- {
- PLY::Face sFace;
-
- // parse the list of vertex indices
- if (0xFFFFFFFF != iProperty)
- {
- const unsigned int iNum = (unsigned int)GetProperty((*i).alProperties, iProperty).avList.size();
- sFace.mIndices.resize(iNum);
-
- std::vector::const_iterator p =
- GetProperty((*i).alProperties, iProperty).avList.begin();
-
- for (unsigned int a = 0; a < iNum;++a,++p)
- {
- sFace.mIndices[a] = PLY::PropertyInstance::ConvertTo(*p,eType);
- }
- }
-
- // parse the material index
- if (0xFFFFFFFF != iMaterialIndex)
- {
- sFace.iMaterialIndex = PLY::PropertyInstance::ConvertTo(
- GetProperty((*i).alProperties, iMaterialIndex).avList.front(),eType2);
- }
- pvOut->push_back(sFace);
- }
- }
- else // triangle strips
- {
- // normally we have only one triangle strip instance where
- // a value of -1 indicates a restart of the strip
- bool flip = false;
- for (std::vector::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
- const std::vector& quak = GetProperty((*i).alProperties, iProperty).avList;
- pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
-
- int aiTable[2] = {-1,-1};
- for (std::vector::const_iterator a = quak.begin();a != quak.end();++a) {
- const int p = PLY::PropertyInstance::ConvertTo(*a,eType);
-
- if (-1 == p) {
- // restart the strip ...
- aiTable[0] = aiTable[1] = -1;
- flip = false;
- continue;
- }
- if (-1 == aiTable[0]) {
- aiTable[0] = p;
- continue;
- }
- if (-1 == aiTable[1]) {
- aiTable[1] = p;
- continue;
- }
-
- pvOut->push_back(PLY::Face());
- PLY::Face& sFace = pvOut->back();
- sFace.mIndices[0] = aiTable[0];
- sFace.mIndices[1] = aiTable[1];
- sFace.mIndices[2] = p;
- if ((flip = !flip)) {
- std::swap(sFace.mIndices[0],sFace.mIndices[1]);
- }
-
- aiTable[0] = aiTable[1];
- aiTable[1] = p;
- }
- }
- }
+ // must be a dynamic list!
+ if (!(*a).bIsList)
+ continue;
+ iProperty = _a;
+ bOne = true;
+ bIsTriStrip = true;
+ eType = (*a).eType;
+ break;
}
+ }
+
+ // check whether we have at least one per-face information set
+ if (bOne)
+ {
+ if (mGeneratedMesh->mFaces == NULL)
+ {
+ mGeneratedMesh->mNumFaces = pcElement->NumOccur;
+ mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
+ }
+
+ if (!bIsTriStrip)
+ {
+ // parse the list of vertex indices
+ if (0xFFFFFFFF != iProperty)
+ {
+ const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
+ mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
+ mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
+
+ std::vector::const_iterator p =
+ GetProperty(instElement->alProperties, iProperty).avList.begin();
+
+ for (unsigned int a = 0; a < iNum; ++a, ++p)
+ {
+ mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo(*p, eType);
+ }
+ }
+
+ // parse the material index
+ // cannot be handled without processing the whole file first
+ /*if (0xFFFFFFFF != iMaterialIndex)
+ {
+ mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo(
+ GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
+ }*/
+
+ if (0xFFFFFFFF != iTextureCoord)
+ {
+ const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
+
+ //should be 6 coords
+ std::vector::const_iterator p =
+ GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
+
+ if ((iNum / 3) == 2) // X Y coord
+ {
+ for (unsigned int a = 0; a < iNum; ++a, ++p)
+ {
+ unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
+ if (vindex < mGeneratedMesh->mNumVertices)
+ {
+ if (mGeneratedMesh->mTextureCoords[0] == NULL)
+ {
+ mGeneratedMesh->mNumUVComponents[0] = 2;
+ mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
+ }
+
+ if (a % 2 == 0)
+ mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo(*p, eType3);
+ else
+ mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo(*p, eType3);
+
+ mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
+ }
+ }
+ }
+ }
+ }
+ else // triangle strips
+ {
+ // normally we have only one triangle strip instance where
+ // a value of -1 indicates a restart of the strip
+ bool flip = false;
+ const std::vector& quak = GetProperty(instElement->alProperties, iProperty).avList;
+ //pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
+
+ int aiTable[2] = { -1, -1 };
+ for (std::vector::const_iterator a = quak.begin(); a != quak.end(); ++a) {
+ const int p = PLY::PropertyInstance::ConvertTo(*a, eType);
+
+ if (-1 == p) {
+ // restart the strip ...
+ aiTable[0] = aiTable[1] = -1;
+ flip = false;
+ continue;
+ }
+ if (-1 == aiTable[0]) {
+ aiTable[0] = p;
+ continue;
+ }
+ if (-1 == aiTable[1]) {
+ aiTable[1] = p;
+ continue;
+ }
+
+ if (mGeneratedMesh->mFaces == NULL)
+ {
+ mGeneratedMesh->mNumFaces = pcElement->NumOccur;
+ mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
+ }
+
+ mGeneratedMesh->mFaces[pos].mNumIndices = 3;
+ mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
+ mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
+ mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
+ mGeneratedMesh->mFaces[pos].mIndices[2] = aiTable[2];
+
+ if ((flip = !flip)) {
+ std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
+ }
+
+ aiTable[0] = aiTable[1];
+ aiTable[1] = p;
+ }
+ }
+ }
}
// ------------------------------------------------------------------------------------------------
// Get a RGBA color in [0...1] range
void PLYImporter::GetMaterialColor(const std::vector& avList,
- unsigned int aiPositions[4],
- PLY::EDataType aiTypes[4],
- aiColor4D* clrOut)
+ unsigned int aiPositions[4],
+ PLY::EDataType aiTypes[4],
+ aiColor4D* clrOut)
{
- ai_assert(NULL != clrOut);
+ ai_assert(NULL != clrOut);
- if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
- else
- {
- clrOut->r = NormalizeColorValue(GetProperty(avList,
- aiPositions[0]).avList.front(),aiTypes[0]);
- }
+ if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
+ else
+ {
+ clrOut->r = NormalizeColorValue(GetProperty(avList,
+ aiPositions[0]).avList.front(), aiTypes[0]);
+ }
- if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
- else
- {
- clrOut->g = NormalizeColorValue(GetProperty(avList,
- aiPositions[1]).avList.front(),aiTypes[1]);
- }
+ if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
+ else
+ {
+ clrOut->g = NormalizeColorValue(GetProperty(avList,
+ aiPositions[1]).avList.front(), aiTypes[1]);
+ }
- if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
- else
- {
- clrOut->b = NormalizeColorValue(GetProperty(avList,
- aiPositions[2]).avList.front(),aiTypes[2]);
- }
+ if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
+ else
+ {
+ clrOut->b = NormalizeColorValue(GetProperty(avList,
+ aiPositions[2]).avList.front(), aiTypes[2]);
+ }
- // assume 1.0 for the alpha channel ifit is not set
- if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
- else
- {
- clrOut->a = NormalizeColorValue(GetProperty(avList,
- aiPositions[3]).avList.front(),aiTypes[3]);
- }
+ // assume 1.0 for the alpha channel ifit is not set
+ if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
+ else
+ {
+ clrOut->a = NormalizeColorValue(GetProperty(avList,
+ aiPositions[3]).avList.front(), aiTypes[3]);
+ }
}
// ------------------------------------------------------------------------------------------------
// Extract a material from the PLY DOM
-void PLYImporter::LoadMaterial(std::vector* pvOut)
+void PLYImporter::LoadMaterial(std::vector* pvOut, std::string &defaultTexture, const bool pointsOnly)
{
- ai_assert(NULL != pvOut);
+ ai_assert(NULL != pvOut);
- // diffuse[4], specular[4], ambient[4]
- // rgba order
- unsigned int aaiPositions[3][4] = {
+ // diffuse[4], specular[4], ambient[4]
+ // rgba order
+ unsigned int aaiPositions[3][4] = {
- {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
- {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
- {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
- };
+ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
+ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
+ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
+ };
- PLY::EDataType aaiTypes[3][4] = {
- {EDT_Char,EDT_Char,EDT_Char,EDT_Char},
- {EDT_Char,EDT_Char,EDT_Char,EDT_Char},
- {EDT_Char,EDT_Char,EDT_Char,EDT_Char}
- };
- PLY::ElementInstanceList* pcList = NULL;
+ PLY::EDataType aaiTypes[3][4] = {
+ { EDT_Char, EDT_Char, EDT_Char, EDT_Char },
+ { EDT_Char, EDT_Char, EDT_Char, EDT_Char },
+ { EDT_Char, EDT_Char, EDT_Char, EDT_Char }
+ };
+ PLY::ElementInstanceList* pcList = NULL;
- unsigned int iPhong = 0xFFFFFFFF;
- PLY::EDataType ePhong = EDT_Char;
+ unsigned int iPhong = 0xFFFFFFFF;
+ PLY::EDataType ePhong = EDT_Char;
- unsigned int iOpacity = 0xFFFFFFFF;
- PLY::EDataType eOpacity = EDT_Char;
+ unsigned int iOpacity = 0xFFFFFFFF;
+ PLY::EDataType eOpacity = EDT_Char;
- // search in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector::const_iterator i = this->pcDOM->alElements.begin();
- i != this->pcDOM->alElements.end();++i,++_i)
+ // search in the DOM for a vertex entry
+ unsigned int _i = 0;
+ for (std::vector::const_iterator i = this->pcDOM->alElements.begin();
+ i != this->pcDOM->alElements.end(); ++i, ++_i)
+ {
+ if (PLY::EEST_Material == (*i).eSemantic)
{
- if (PLY::EEST_Material == (*i).eSemantic)
+ pcList = &this->pcDOM->alElementData[_i];
+
+ // now check whether which coordinate sets are available
+ unsigned int _a = 0;
+ for (std::vector::const_iterator
+ a = (*i).alProperties.begin();
+ a != (*i).alProperties.end(); ++a, ++_a)
+ {
+ if ((*a).bIsList)continue;
+
+ // pohng specularity -----------------------------------
+ if (PLY::EST_PhongPower == (*a).Semantic)
{
- pcList = &this->pcDOM->alElementData[_i];
-
- // now check whether which coordinate sets are available
- unsigned int _a = 0;
- for (std::vector::const_iterator
- a = (*i).alProperties.begin();
- a != (*i).alProperties.end();++a,++_a)
- {
- if ((*a).bIsList)continue;
-
- // pohng specularity -----------------------------------
- if (PLY::EST_PhongPower == (*a).Semantic)
- {
- iPhong = _a;
- ePhong = (*a).eType;
- }
-
- // general opacity -----------------------------------
- if (PLY::EST_Opacity == (*a).Semantic)
- {
- iOpacity = _a;
- eOpacity = (*a).eType;
- }
-
- // diffuse color channels -----------------------------------
- if (PLY::EST_DiffuseRed == (*a).Semantic)
- {
- aaiPositions[0][0] = _a;
- aaiTypes[0][0] = (*a).eType;
- }
- else if (PLY::EST_DiffuseGreen == (*a).Semantic)
- {
- aaiPositions[0][1] = _a;
- aaiTypes[0][1] = (*a).eType;
- }
- else if (PLY::EST_DiffuseBlue == (*a).Semantic)
- {
- aaiPositions[0][2] = _a;
- aaiTypes[0][2] = (*a).eType;
- }
- else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
- {
- aaiPositions[0][3] = _a;
- aaiTypes[0][3] = (*a).eType;
- }
- // specular color channels -----------------------------------
- else if (PLY::EST_SpecularRed == (*a).Semantic)
- {
- aaiPositions[1][0] = _a;
- aaiTypes[1][0] = (*a).eType;
- }
- else if (PLY::EST_SpecularGreen == (*a).Semantic)
- {
- aaiPositions[1][1] = _a;
- aaiTypes[1][1] = (*a).eType;
- }
- else if (PLY::EST_SpecularBlue == (*a).Semantic)
- {
- aaiPositions[1][2] = _a;
- aaiTypes[1][2] = (*a).eType;
- }
- else if (PLY::EST_SpecularAlpha == (*a).Semantic)
- {
- aaiPositions[1][3] = _a;
- aaiTypes[1][3] = (*a).eType;
- }
- // ambient color channels -----------------------------------
- else if (PLY::EST_AmbientRed == (*a).Semantic)
- {
- aaiPositions[2][0] = _a;
- aaiTypes[2][0] = (*a).eType;
- }
- else if (PLY::EST_AmbientGreen == (*a).Semantic)
- {
- aaiPositions[2][1] = _a;
- aaiTypes[2][1] = (*a).eType;
- }
- else if (PLY::EST_AmbientBlue == (*a).Semantic)
- {
- aaiPositions[2][2] = _a;
- aaiTypes[2][2] = (*a).eType;
- }
- else if (PLY::EST_AmbientAlpha == (*a).Semantic)
- {
- aaiPositions[2][3] = _a;
- aaiTypes[2][3] = (*a).eType;
- }
- }
- break;
+ iPhong = _a;
+ ePhong = (*a).eType;
}
- }
- // check whether we have a valid source for the material data
- if (NULL != pcList) {
- for (std::vector::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
- aiColor4D clrOut;
- aiMaterial* pcHelper = new aiMaterial();
- // build the diffuse material color
- GetMaterialColor((*i).alProperties,aaiPositions[0],aaiTypes[0],&clrOut);
- pcHelper->AddProperty(&clrOut,1,AI_MATKEY_COLOR_DIFFUSE);
-
- // build the specular material color
- GetMaterialColor((*i).alProperties,aaiPositions[1],aaiTypes[1],&clrOut);
- pcHelper->AddProperty(&clrOut,1,AI_MATKEY_COLOR_SPECULAR);
-
- // build the ambient material color
- GetMaterialColor((*i).alProperties,aaiPositions[2],aaiTypes[2],&clrOut);
- pcHelper->AddProperty(&clrOut,1,AI_MATKEY_COLOR_AMBIENT);
-
- // handle phong power and shading mode
- int iMode = (int)aiShadingMode_Gouraud;
- if (0xFFFFFFFF != iPhong) {
- ai_real fSpec = PLY::PropertyInstance::ConvertTo(GetProperty((*i).alProperties, iPhong).avList.front(),ePhong);
-
- // if shininess is 0 (and the pow() calculation would therefore always
- // become 1, not depending on the angle), use gouraud lighting
- if (fSpec) {
- // scale this with 15 ... hopefully this is correct
- fSpec *= 15;
- pcHelper->AddProperty(&fSpec, 1, AI_MATKEY_SHININESS);
-
- iMode = (int)aiShadingMode_Phong;
- }
- }
- pcHelper->AddProperty(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // handle opacity
- if (0xFFFFFFFF != iOpacity) {
- ai_real fOpacity = PLY::PropertyInstance::ConvertTo(GetProperty((*i).alProperties, iPhong).avList.front(),eOpacity);
- pcHelper->AddProperty(&fOpacity, 1, AI_MATKEY_OPACITY);
- }
-
- // The face order is absolutely undefined for PLY, so we have to
- // use two-sided rendering to be sure it's ok.
- const int two_sided = 1;
- pcHelper->AddProperty(&two_sided,1,AI_MATKEY_TWOSIDED);
-
- // add the newly created material instance to the list
- pvOut->push_back(pcHelper);
+ // general opacity -----------------------------------
+ if (PLY::EST_Opacity == (*a).Semantic)
+ {
+ iOpacity = _a;
+ eOpacity = (*a).eType;
}
+
+ // diffuse color channels -----------------------------------
+ if (PLY::EST_DiffuseRed == (*a).Semantic)
+ {
+ aaiPositions[0][0] = _a;
+ aaiTypes[0][0] = (*a).eType;
+ }
+ else if (PLY::EST_DiffuseGreen == (*a).Semantic)
+ {
+ aaiPositions[0][1] = _a;
+ aaiTypes[0][1] = (*a).eType;
+ }
+ else if (PLY::EST_DiffuseBlue == (*a).Semantic)
+ {
+ aaiPositions[0][2] = _a;
+ aaiTypes[0][2] = (*a).eType;
+ }
+ else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
+ {
+ aaiPositions[0][3] = _a;
+ aaiTypes[0][3] = (*a).eType;
+ }
+ // specular color channels -----------------------------------
+ else if (PLY::EST_SpecularRed == (*a).Semantic)
+ {
+ aaiPositions[1][0] = _a;
+ aaiTypes[1][0] = (*a).eType;
+ }
+ else if (PLY::EST_SpecularGreen == (*a).Semantic)
+ {
+ aaiPositions[1][1] = _a;
+ aaiTypes[1][1] = (*a).eType;
+ }
+ else if (PLY::EST_SpecularBlue == (*a).Semantic)
+ {
+ aaiPositions[1][2] = _a;
+ aaiTypes[1][2] = (*a).eType;
+ }
+ else if (PLY::EST_SpecularAlpha == (*a).Semantic)
+ {
+ aaiPositions[1][3] = _a;
+ aaiTypes[1][3] = (*a).eType;
+ }
+ // ambient color channels -----------------------------------
+ else if (PLY::EST_AmbientRed == (*a).Semantic)
+ {
+ aaiPositions[2][0] = _a;
+ aaiTypes[2][0] = (*a).eType;
+ }
+ else if (PLY::EST_AmbientGreen == (*a).Semantic)
+ {
+ aaiPositions[2][1] = _a;
+ aaiTypes[2][1] = (*a).eType;
+ }
+ else if (PLY::EST_AmbientBlue == (*a).Semantic)
+ {
+ aaiPositions[2][2] = _a;
+ aaiTypes[2][2] = (*a).eType;
+ }
+ else if (PLY::EST_AmbientAlpha == (*a).Semantic)
+ {
+ aaiPositions[2][3] = _a;
+ aaiTypes[2][3] = (*a).eType;
+ }
+ }
+ break;
}
+ else if (PLY::EEST_TextureFile == (*i).eSemantic)
+ {
+ defaultTexture = (*i).szName;
+ }
+ }
+ // check whether we have a valid source for the material data
+ if (NULL != pcList) {
+ for (std::vector::const_iterator i = pcList->alInstances.begin(); i != pcList->alInstances.end(); ++i) {
+ aiColor4D clrOut;
+ aiMaterial* pcHelper = new aiMaterial();
+
+ // build the diffuse material color
+ GetMaterialColor((*i).alProperties, aaiPositions[0], aaiTypes[0], &clrOut);
+ pcHelper->AddProperty(&clrOut, 1, AI_MATKEY_COLOR_DIFFUSE);
+
+ // build the specular material color
+ GetMaterialColor((*i).alProperties, aaiPositions[1], aaiTypes[1], &clrOut);
+ pcHelper->AddProperty(&clrOut, 1, AI_MATKEY_COLOR_SPECULAR);
+
+ // build the ambient material color
+ GetMaterialColor((*i).alProperties, aaiPositions[2], aaiTypes[2], &clrOut);
+ pcHelper->AddProperty(&clrOut, 1, AI_MATKEY_COLOR_AMBIENT);
+
+ // handle phong power and shading mode
+ int iMode = (int)aiShadingMode_Gouraud;
+ if (0xFFFFFFFF != iPhong) {
+ ai_real fSpec = PLY::PropertyInstance::ConvertTo(GetProperty((*i).alProperties, iPhong).avList.front(), ePhong);
+
+ // if shininess is 0 (and the pow() calculation would therefore always
+ // become 1, not depending on the angle), use gouraud lighting
+ if (fSpec) {
+ // scale this with 15 ... hopefully this is correct
+ fSpec *= 15;
+ pcHelper->AddProperty(&fSpec, 1, AI_MATKEY_SHININESS);
+
+ iMode = (int)aiShadingMode_Phong;
+ }
+ }
+ pcHelper->AddProperty(&iMode, 1, AI_MATKEY_SHADING_MODEL);
+
+ // handle opacity
+ if (0xFFFFFFFF != iOpacity) {
+ ai_real fOpacity = PLY::PropertyInstance::ConvertTo(GetProperty((*i).alProperties, iPhong).avList.front(), eOpacity);
+ pcHelper->AddProperty(&fOpacity, 1, AI_MATKEY_OPACITY);
+ }
+
+ // The face order is absolutely undefined for PLY, so we have to
+ // use two-sided rendering to be sure it's ok.
+ const int two_sided = 1;
+ pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
+
+ //default texture
+ if (!defaultTexture.empty())
+ {
+ const aiString name(defaultTexture.c_str());
+ pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
+ }
+
+ if (!pointsOnly)
+ {
+ const int two_sided = 1;
+ pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
+ }
+
+ //set to wireframe, so when using this material info we can switch to points rendering
+ if (pointsOnly)
+ {
+ const int wireframe = 1;
+ pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
+ }
+
+ // add the newly created material instance to the list
+ pvOut->push_back(pcHelper);
+ }
+ }
+ else
+ {
+ // generate a default material
+ aiMaterial* pcHelper = new aiMaterial();
+
+ // fill in a default material
+ int iMode = (int)aiShadingMode_Gouraud;
+ pcHelper->AddProperty(&iMode, 1, AI_MATKEY_SHADING_MODEL);
+
+ //generate white material most 3D engine just multiply ambient / diffuse color with actual ambient / light color
+ aiColor3D clr;
+ clr.b = clr.g = clr.r = 1.0f;
+ pcHelper->AddProperty(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
+ pcHelper->AddProperty(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
+
+ clr.b = clr.g = clr.r = 1.0f;
+ pcHelper->AddProperty(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
+
+ // The face order is absolutely undefined for PLY, so we have to
+ // use two-sided rendering to be sure it's ok.
+ if (!pointsOnly)
+ {
+ const int two_sided = 1;
+ pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
+ }
+
+ //default texture
+ if (!defaultTexture.empty())
+ {
+ const aiString name(defaultTexture.c_str());
+ pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
+ }
+
+ //set to wireframe, so when using this material info we can switch to points rendering
+ if (pointsOnly)
+ {
+ const int wireframe = 1;
+ pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
+ }
+
+ pvOut->push_back(pcHelper);
+ }
}
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
diff --git a/code/PlyLoader.h b/code/PlyLoader.h
index 6c3825aa4..eb64a9036 100644
--- a/code/PlyLoader.h
+++ b/code/PlyLoader.h
@@ -68,7 +68,6 @@ public:
PLYImporter();
~PLYImporter();
-
public:
// -------------------------------------------------------------------
@@ -78,6 +77,16 @@ public:
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
+ // -------------------------------------------------------------------
+ /** Extract a vertex from the DOM
+ */
+ void LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos);
+
+ // -------------------------------------------------------------------
+ /** Extract a face from the DOM
+ */
+ void LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos);
+
protected:
// -------------------------------------------------------------------
@@ -94,53 +103,10 @@ protected:
IOSystem* pIOHandler);
protected:
-
-
- // -------------------------------------------------------------------
- /** Extract vertices from the DOM
- */
- void LoadVertices(std::vector* pvOut,
- bool p_bNormals = false);
-
- // -------------------------------------------------------------------
- /** Extract vertex color channels from the DOM
- */
- void LoadVertexColor(std::vector* pvOut);
-
- // -------------------------------------------------------------------
- /** Extract texture coordinate channels from the DOM
- */
- void LoadTextureCoordinates(std::vector* pvOut);
-
- // -------------------------------------------------------------------
- /** Extract a face list from the DOM
- */
- void LoadFaces(std::vector* pvOut);
-
// -------------------------------------------------------------------
/** Extract a material list from the DOM
*/
- void LoadMaterial(std::vector* pvOut);
-
-
- // -------------------------------------------------------------------
- /** Validate material indices, replace default material identifiers
- */
- void ReplaceDefaultMaterial(std::vector* avFaces,
- std::vector* avMaterials);
-
-
- // -------------------------------------------------------------------
- /** Convert all meshes into our ourer representation
- */
- void ConvertMeshes(std::vector* avFaces,
- const std::vector* avPositions,
- const std::vector* avNormals,
- const std::vector* avColors,
- const std::vector* avTexCoords,
- const std::vector* avMaterials,
- std::vector* avOut);
-
+ void LoadMaterial(std::vector* pvOut, std::string &defaultTexture, const bool pointsOnly);
// -------------------------------------------------------------------
/** Static helper to parse a color from four single channels in
@@ -151,7 +117,6 @@ protected:
PLY::EDataType aiTypes[4],
aiColor4D* clrOut);
-
// -------------------------------------------------------------------
/** Static helper to parse a color channel value. The input value
* is normalized to 0-1.
@@ -160,12 +125,14 @@ protected:
PLY::PropertyInstance::ValueUnion val,
PLY::EDataType eType);
-
/** Buffer to hold the loaded file */
unsigned char* mBuffer;
/** Document object model representation extracted from the file */
PLY::DOM* pcDOM;
+
+ /** Mesh generated by loader */
+ aiMesh* mGeneratedMesh;
};
} // end of namespace Assimp
diff --git a/code/PlyParser.cpp b/code/PlyParser.cpp
index 7e5a07d8e..e29005068 100644
--- a/code/PlyParser.cpp
+++ b/code/PlyParser.cpp
@@ -5,7 +5,6 @@ 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,
@@ -13,18 +12,18 @@ 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.
+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.
+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.
+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
@@ -45,916 +44,1093 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-#include "PlyLoader.h"
#include "fast_atof.h"
#include
#include "ByteSwapper.h"
-
+#include "PlyLoader.h"
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
-PLY::EDataType PLY::Property::ParseDataType(const char* pCur,const char** pCurOut) {
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
+PLY::EDataType PLY::Property::ParseDataType(std::vector &buffer) {
+ ai_assert(!buffer.empty());
- PLY::EDataType eOut = PLY::EDT_INVALID;
+ PLY::EDataType eOut = PLY::EDT_INVALID;
- if (TokenMatch(pCur,"char",4) ||
- TokenMatch(pCur,"int8",4))
- {
- eOut = PLY::EDT_Char;
- }
- else if (TokenMatch(pCur,"uchar",5) ||
- TokenMatch(pCur,"uint8",5))
- {
- eOut = PLY::EDT_UChar;
- }
- else if (TokenMatch(pCur,"short",5) ||
- TokenMatch(pCur,"int16",5))
- {
- eOut = PLY::EDT_Short;
- }
- else if (TokenMatch(pCur,"ushort",6) ||
- TokenMatch(pCur,"uint16",6))
- {
- eOut = PLY::EDT_UShort;
- }
- else if (TokenMatch(pCur,"int32",5) || TokenMatch(pCur,"int",3))
- {
- eOut = PLY::EDT_Int;
- }
- else if (TokenMatch(pCur,"uint32",6) || TokenMatch(pCur,"uint",4))
- {
- eOut = PLY::EDT_UInt;
- }
- else if (TokenMatch(pCur,"float",5) || TokenMatch(pCur,"float32",7))
- {
- eOut = PLY::EDT_Float;
- }
- else if (TokenMatch(pCur,"double64",8) || TokenMatch(pCur,"double",6) ||
- TokenMatch(pCur,"float64",7))
- {
- eOut = PLY::EDT_Double;
- }
- if (PLY::EDT_INVALID == eOut)
- {
- DefaultLogger::get()->info("Found unknown data type in PLY file. This is OK");
- }
- *pCurOut = pCur;
+ if (PLY::DOM::TokenMatch(buffer, "char", 4) ||
+ PLY::DOM::TokenMatch(buffer, "int8", 4))
+ {
+ eOut = PLY::EDT_Char;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "uchar", 5) ||
+ PLY::DOM::TokenMatch(buffer, "uint8", 5))
+ {
+ eOut = PLY::EDT_UChar;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "short", 5) ||
+ PLY::DOM::TokenMatch(buffer, "int16", 5))
+ {
+ eOut = PLY::EDT_Short;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "ushort", 6) ||
+ PLY::DOM::TokenMatch(buffer, "uint16", 6))
+ {
+ eOut = PLY::EDT_UShort;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "int32", 5) || PLY::DOM::TokenMatch(buffer, "int", 3))
+ {
+ eOut = PLY::EDT_Int;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "uint32", 6) || PLY::DOM::TokenMatch(buffer, "uint", 4))
+ {
+ eOut = PLY::EDT_UInt;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "float", 5) || PLY::DOM::TokenMatch(buffer, "float32", 7))
+ {
+ eOut = PLY::EDT_Float;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "double64", 8) || PLY::DOM::TokenMatch(buffer, "double", 6) ||
+ PLY::DOM::TokenMatch(buffer, "float64", 7))
+ {
+ eOut = PLY::EDT_Double;
+ }
+ if (PLY::EDT_INVALID == eOut)
+ {
+ DefaultLogger::get()->info("Found unknown data type in PLY file. This is OK");
+ }
- return eOut;
+ return eOut;
}
// ------------------------------------------------------------------------------------------------
-PLY::ESemantic PLY::Property::ParseSemantic(const char* pCur,const char** pCurOut) {
- ai_assert (NULL != pCur );
- ai_assert( NULL != pCurOut );
+PLY::ESemantic PLY::Property::ParseSemantic(std::vector &buffer) {
+ ai_assert(!buffer.empty());
- PLY::ESemantic eOut = PLY::EST_INVALID;
- if (TokenMatch(pCur,"red",3)) {
- eOut = PLY::EST_Red;
- } else if (TokenMatch(pCur,"green",5)) {
- eOut = PLY::EST_Green;
- } else if (TokenMatch(pCur,"blue",4)) {
- eOut = PLY::EST_Blue;
- } else if (TokenMatch(pCur,"alpha",5)) {
- eOut = PLY::EST_Alpha;
- } else if (TokenMatch(pCur,"vertex_index",12) || TokenMatch(pCur,"vertex_indices",14)) {
- eOut = PLY::EST_VertexIndex;
- }
- else if (TokenMatch(pCur,"material_index",14))
- {
- eOut = PLY::EST_MaterialIndex;
- }
- else if (TokenMatch(pCur,"ambient_red",11))
- {
- eOut = PLY::EST_AmbientRed;
- }
- else if (TokenMatch(pCur,"ambient_green",13))
- {
- eOut = PLY::EST_AmbientGreen;
- }
- else if (TokenMatch(pCur,"ambient_blue",12))
- {
- eOut = PLY::EST_AmbientBlue;
- }
- else if (TokenMatch(pCur,"ambient_alpha",13))
- {
- eOut = PLY::EST_AmbientAlpha;
- }
- else if (TokenMatch(pCur,"diffuse_red",11))
- {
- eOut = PLY::EST_DiffuseRed;
- }
- else if (TokenMatch(pCur,"diffuse_green",13))
- {
- eOut = PLY::EST_DiffuseGreen;
- }
- else if (TokenMatch(pCur,"diffuse_blue",12))
- {
- eOut = PLY::EST_DiffuseBlue;
- }
- else if (TokenMatch(pCur,"diffuse_alpha",13))
- {
- eOut = PLY::EST_DiffuseAlpha;
- }
- else if (TokenMatch(pCur,"specular_red",12))
- {
- eOut = PLY::EST_SpecularRed;
- }
- else if (TokenMatch(pCur,"specular_green",14))
- {
- eOut = PLY::EST_SpecularGreen;
- }
- else if (TokenMatch(pCur,"specular_blue",13))
- {
- eOut = PLY::EST_SpecularBlue;
- }
- else if (TokenMatch(pCur,"specular_alpha",14))
- {
- eOut = PLY::EST_SpecularAlpha;
- }
- else if (TokenMatch(pCur,"opacity",7))
- {
- eOut = PLY::EST_Opacity;
- }
- else if (TokenMatch(pCur,"specular_power",14))
- {
- eOut = PLY::EST_PhongPower;
- }
- else if (TokenMatch(pCur,"r",1))
- {
- eOut = PLY::EST_Red;
- }
- else if (TokenMatch(pCur,"g",1))
- {
- eOut = PLY::EST_Green;
- }
- else if (TokenMatch(pCur,"b",1))
- {
- eOut = PLY::EST_Blue;
- }
- // NOTE: Blender3D exports texture coordinates as s,t tuples
- else if (TokenMatch(pCur,"u",1) || TokenMatch(pCur,"s",1) || TokenMatch(pCur,"tx",2) || TokenMatch(pCur,"texture_u",9))
- {
- eOut = PLY::EST_UTextureCoord;
- }
- else if (TokenMatch(pCur,"v",1) || TokenMatch(pCur,"t",1) || TokenMatch(pCur,"ty",2) || TokenMatch(pCur,"texture_v",9))
- {
- eOut = PLY::EST_VTextureCoord;
- }
- else if (TokenMatch(pCur,"x",1))
- {
- eOut = PLY::EST_XCoord;
- } else if (TokenMatch(pCur,"y",1)) {
- eOut = PLY::EST_YCoord;
- } else if (TokenMatch(pCur,"z",1)) {
- eOut = PLY::EST_ZCoord;
- } else if (TokenMatch(pCur,"nx",2)) {
- eOut = PLY::EST_XNormal;
- } else if (TokenMatch(pCur,"ny",2)) {
- eOut = PLY::EST_YNormal;
- } else if (TokenMatch(pCur,"nz",2)) {
- eOut = PLY::EST_ZNormal;
- } else {
- DefaultLogger::get()->info("Found unknown property semantic in file. This is ok");
- SkipLine(&pCur);
- }
- *pCurOut = pCur;
- return eOut;
+ PLY::ESemantic eOut = PLY::EST_INVALID;
+ if (PLY::DOM::TokenMatch(buffer, "red", 3)) {
+ eOut = PLY::EST_Red;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "green", 5)) {
+ eOut = PLY::EST_Green;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "blue", 4)) {
+ eOut = PLY::EST_Blue;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "alpha", 5)) {
+ eOut = PLY::EST_Alpha;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "vertex_index", 12) || PLY::DOM::TokenMatch(buffer, "vertex_indices", 14)) {
+ eOut = PLY::EST_VertexIndex;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "texcoord", 8)) // Manage uv coords on faces
+ {
+ eOut = PLY::EST_TextureCoordinates;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "material_index", 14))
+ {
+ eOut = PLY::EST_MaterialIndex;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "ambient_red", 11))
+ {
+ eOut = PLY::EST_AmbientRed;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "ambient_green", 13))
+ {
+ eOut = PLY::EST_AmbientGreen;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "ambient_blue", 12))
+ {
+ eOut = PLY::EST_AmbientBlue;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "ambient_alpha", 13))
+ {
+ eOut = PLY::EST_AmbientAlpha;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "diffuse_red", 11))
+ {
+ eOut = PLY::EST_DiffuseRed;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "diffuse_green", 13))
+ {
+ eOut = PLY::EST_DiffuseGreen;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "diffuse_blue", 12))
+ {
+ eOut = PLY::EST_DiffuseBlue;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "diffuse_alpha", 13))
+ {
+ eOut = PLY::EST_DiffuseAlpha;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "specular_red", 12))
+ {
+ eOut = PLY::EST_SpecularRed;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "specular_green", 14))
+ {
+ eOut = PLY::EST_SpecularGreen;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "specular_blue", 13))
+ {
+ eOut = PLY::EST_SpecularBlue;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "specular_alpha", 14))
+ {
+ eOut = PLY::EST_SpecularAlpha;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "opacity", 7))
+ {
+ eOut = PLY::EST_Opacity;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "specular_power", 14))
+ {
+ eOut = PLY::EST_PhongPower;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "r", 1))
+ {
+ eOut = PLY::EST_Red;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "g", 1))
+ {
+ eOut = PLY::EST_Green;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "b", 1))
+ {
+ eOut = PLY::EST_Blue;
+ }
+
+ // NOTE: Blender3D exports texture coordinates as s,t tuples
+ else if (PLY::DOM::TokenMatch(buffer, "u", 1) || PLY::DOM::TokenMatch(buffer, "s", 1) || PLY::DOM::TokenMatch(buffer, "tx", 2) || PLY::DOM::TokenMatch(buffer, "texture_u", 9))
+ {
+ eOut = PLY::EST_UTextureCoord;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "v", 1) || PLY::DOM::TokenMatch(buffer, "t", 1) || PLY::DOM::TokenMatch(buffer, "ty", 2) || PLY::DOM::TokenMatch(buffer, "texture_v", 9))
+ {
+ eOut = PLY::EST_VTextureCoord;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "x", 1))
+ {
+ eOut = PLY::EST_XCoord;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "y", 1)) {
+ eOut = PLY::EST_YCoord;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "z", 1)) {
+ eOut = PLY::EST_ZCoord;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "nx", 2)) {
+ eOut = PLY::EST_XNormal;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "ny", 2)) {
+ eOut = PLY::EST_YNormal;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "nz", 2)) {
+ eOut = PLY::EST_ZNormal;
+ }
+ else {
+ DefaultLogger::get()->info("Found unknown property semantic in file. This is ok");
+ PLY::DOM::SkipLine(buffer);
+ }
+ return eOut;
}
// ------------------------------------------------------------------------------------------------
-bool PLY::Property::ParseProperty (const char* pCur,
- const char** pCurOut,
- PLY::Property* pOut)
+bool PLY::Property::ParseProperty(std::vector &buffer, PLY::Property* pOut)
{
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
+ ai_assert(!buffer.empty());
- // Forms supported:
- // "property float x"
- // "property list uchar int vertex_index"
- *pCurOut = pCur;
-
- // skip leading spaces
- if (!SkipSpaces(pCur,&pCur)) {
- return false;
- }
-
- // skip the "property" string at the beginning
- if (!TokenMatch(pCur,"property",8))
- {
- // seems not to be a valid property entry
- return false;
- }
- // get next word
- if (!SkipSpaces(pCur,&pCur)) {
- return false;
- }
- if (TokenMatch(pCur,"list",4))
- {
- pOut->bIsList = true;
-
- // seems to be a list.
- if(EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(pCur, &pCur)))
- {
- // unable to parse list size data type
- SkipLine(pCur,&pCur);
- *pCurOut = pCur;
- return false;
- }
- if (!SkipSpaces(pCur,&pCur))return false;
- if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur)))
- {
- // unable to parse list data type
- SkipLine(pCur,&pCur);
- *pCurOut = pCur;
- return false;
- }
- }
- else
- {
- if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur)))
- {
- // unable to parse data type. Skip the property
- SkipLine(pCur,&pCur);
- *pCurOut = pCur;
- return false;
- }
- }
-
- if (!SkipSpaces(pCur,&pCur))return false;
- const char* szCur = pCur;
- pOut->Semantic = PLY::Property::ParseSemantic(pCur, &pCur);
-
- if (PLY::EST_INVALID == pOut->Semantic)
- {
- // store the name of the semantic
- uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
-
- DefaultLogger::get()->info("Found unknown semantic in PLY file. This is OK");
- pOut->szName = std::string(szCur,iDiff);
- }
-
- SkipSpacesAndLineEnd(pCur,&pCur);
- *pCurOut = pCur;
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-PLY::EElementSemantic PLY::Element::ParseSemantic(const char* pCur,
- const char** pCurOut)
-{
- ai_assert(NULL != pCur && NULL != pCurOut);
- PLY::EElementSemantic eOut = PLY::EEST_INVALID;
- if (TokenMatch(pCur,"vertex",6))
- {
- eOut = PLY::EEST_Vertex;
- }
- else if (TokenMatch(pCur,"face",4))
- {
- eOut = PLY::EEST_Face;
- }
-#if 0
- // TODO: maybe implement this?
- else if (TokenMatch(pCur,"range_grid",10))
- {
- eOut = PLY::EEST_Face;
- }
-#endif
- else if (TokenMatch(pCur,"tristrips",9))
- {
- eOut = PLY::EEST_TriStrip;
- }
- else if (TokenMatch(pCur,"edge",4))
- {
- eOut = PLY::EEST_Edge;
- }
- else if (TokenMatch(pCur,"material",8))
- {
- eOut = PLY::EEST_Material;
- }
- *pCurOut = pCur;
-
- return eOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::Element::ParseElement (const char* pCur,
- const char** pCurOut,
- PLY::Element* pOut)
-{
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
- ai_assert( NULL != pOut );
-
- // Example format: "element vertex 8"
- *pCurOut = pCur;
-
- // skip leading spaces
- if (!SkipSpaces(&pCur)) {
- return false;
- }
-
- // skip the "element" string at the beginning
- if (!TokenMatch(pCur,"element",7))
- {
- // seems not to be a valid property entry
- return false;
- }
- // get next word
- if (!SkipSpaces(&pCur))return false;
-
- // parse the semantic of the element
- const char* szCur = pCur;
- pOut->eSemantic = PLY::Element::ParseSemantic(pCur,&pCur);
- if (PLY::EEST_INVALID == pOut->eSemantic)
- {
- // if the exact semantic can't be determined, just store
- // the original string identifier
- uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
- pOut->szName = std::string(szCur,iDiff);
- }
-
- if (!SkipSpaces(&pCur))return false;
-
- //parse the number of occurrences of this element
- pOut->NumOccur = strtoul10(pCur,&pCur);
-
- // go to the next line
- SkipSpacesAndLineEnd(pCur,&pCur);
-
- // now parse all properties of the element
- while(true)
- {
- // skip all comments
- PLY::DOM::SkipComments(pCur,&pCur);
-
- PLY::Property prop;
- if(!PLY::Property::ParseProperty(pCur,&pCur,&prop))break;
- pOut->alProperties.push_back(prop);
- }
- *pCurOut = pCur;
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::SkipComments (const char* pCur,
- const char** pCurOut)
-{
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
- *pCurOut = pCur;
-
- // skip spaces
- if (!SkipSpaces(pCur,&pCur)) {
- return false;
- }
-
- if (TokenMatch(pCur,"comment",7))
- {
- if ( !IsLineEnd(pCur[-1]) )
- {
- SkipLine(pCur,&pCur);
- }
- SkipComments(pCur,&pCur);
- *pCurOut = pCur;
- return true;
- }
- *pCurOut = pCur;
+ // Forms supported:
+ // "property float x"
+ // "property list uchar int vertex_index"
+ // skip leading spaces
+ if (!PLY::DOM::SkipSpaces(buffer)) {
return false;
-}
+ }
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut,bool isBinary) {
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
+ // skip the "property" string at the beginning
+ if (!PLY::DOM::TokenMatch(buffer, "property", 8))
+ {
+ // seems not to be a valid property entry
+ return false;
+ }
+ // get next word
+ if (!PLY::DOM::SkipSpaces(buffer)) {
+ return false;
+ }
+ if (PLY::DOM::TokenMatch(buffer, "list", 4))
+ {
+ pOut->bIsList = true;
- DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin");
-
- // after ply and format line
- *pCurOut = pCur;
-
- // parse all elements
- while ((*pCur) != '\0')
+ // seems to be a list.
+ if (EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(buffer)))
{
- // skip all comments
- PLY::DOM::SkipComments(pCur,&pCur);
-
- PLY::Element out;
- if(PLY::Element::ParseElement(pCur,&pCur,&out))
- {
- // add the element to the list of elements
- alElements.push_back(out);
- }
- else if (TokenMatch(pCur,"end_header",10))
- {
- // we have reached the end of the header
- break;
- }
- else
- {
- // ignore unknown header elements
- SkipLine(&pCur);
- }
+ // unable to parse list size data type
+ PLY::DOM::SkipLine(buffer);
+ return false;
}
- if(!isBinary)
- { // it would occur an error, if binary data start with values as space or line end.
- SkipSpacesAndLineEnd(pCur,&pCur);
+ if (!PLY::DOM::SkipSpaces(buffer))return false;
+ if (EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(buffer)))
+ {
+ // unable to parse list data type
+ PLY::DOM::SkipLine(buffer);
+ return false;
}
- *pCurOut = pCur;
+ }
+ else
+ {
+ if (EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(buffer)))
+ {
+ // unable to parse data type. Skip the property
+ PLY::DOM::SkipLine(buffer);
+ return false;
+ }
+ }
- DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded");
- return true;
+ if (!PLY::DOM::SkipSpaces(buffer))
+ return false;
+
+ pOut->Semantic = PLY::Property::ParseSemantic(buffer);
+
+ if (PLY::EST_INVALID == pOut->Semantic)
+ {
+ DefaultLogger::get()->info("Found unknown semantic in PLY file. This is OK");
+ std::string(&buffer[0], &buffer[0] + strlen(&buffer[0]));
+ }
+
+ PLY::DOM::SkipSpacesAndLineEnd(buffer);
+ return true;
}
// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseElementInstanceLists (
- const char* pCur,
- const char** pCurOut)
+PLY::EElementSemantic PLY::Element::ParseSemantic(std::vector &buffer)
{
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
+ ai_assert(!buffer.empty());
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() begin");
- *pCurOut = pCur;
+ PLY::EElementSemantic eOut = PLY::EEST_INVALID;
+ if (PLY::DOM::TokenMatch(buffer, "vertex", 6))
+ {
+ eOut = PLY::EEST_Vertex;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "face", 4))
+ {
+ eOut = PLY::EEST_Face;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "tristrips", 9))
+ {
+ eOut = PLY::EEST_TriStrip;
+ }
+#if 0
+ // TODO: maybe implement this?
+ else if (PLY::DOM::TokenMatch(buffer,"range_grid",10))
+ {
+ eOut = PLY::EEST_Face;
+ }
+#endif
+ else if (PLY::DOM::TokenMatch(buffer, "edge", 4))
+ {
+ eOut = PLY::EEST_Edge;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "material", 8))
+ {
+ eOut = PLY::EEST_Material;
+ }
+ else if (PLY::DOM::TokenMatch(buffer, "TextureFile", 11))
+ {
+ eOut = PLY::EEST_TextureFile;
+ }
- alElementData.resize(alElements.size());
-
- std::vector::const_iterator i = alElements.begin();
- std::vector::iterator a = alElementData.begin();
-
- // parse all element instances
- for (;i != alElements.end();++i,++a)
- {
- (*a).alInstances.resize((*i).NumOccur);
- PLY::ElementInstanceList::ParseInstanceList(pCur,&pCur,&(*i),&(*a));
- }
-
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() succeeded");
- *pCurOut = pCur;
- return true;
+ return eOut;
}
// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseElementInstanceListsBinary (
- const char* pCur,
- const char** pCurOut,
+bool PLY::Element::ParseElement(IOStreamBuffer &streamBuffer, std::vector &buffer, PLY::Element* pOut)
+{
+ ai_assert(NULL != pOut);
+ // Example format: "element vertex 8"
+
+ // skip leading spaces
+ if (!PLY::DOM::SkipSpaces(buffer))
+ {
+ return false;
+ }
+
+ // skip the "element" string at the beginning
+ if (!PLY::DOM::TokenMatch(buffer, "element", 7) && !PLY::DOM::TokenMatch(buffer, "comment", 7))
+ {
+ // seems not to be a valid property entry
+ return false;
+ }
+ // get next word
+ if (!PLY::DOM::SkipSpaces(buffer))
+ return false;
+
+ // parse the semantic of the element
+ pOut->eSemantic = PLY::Element::ParseSemantic(buffer);
+ if (PLY::EEST_INVALID == pOut->eSemantic)
+ {
+ // if the exact semantic can't be determined, just store
+ // the original string identifier
+ pOut->szName = std::string(&buffer[0], &buffer[0] + strlen(&buffer[0]));
+ }
+
+ if (!PLY::DOM::SkipSpaces(buffer))
+ return false;
+
+ if (PLY::EEST_TextureFile == pOut->eSemantic)
+ {
+ char* endPos = &buffer[0] + (strlen(&buffer[0]) - 1);
+ pOut->szName = std::string(&buffer[0], endPos);
+ }
+
+ //parse the number of occurrences of this element
+ const char* pCur = (char*)&buffer[0];
+ pOut->NumOccur = strtoul10(pCur, &pCur);
+
+ // go to the next line
+ PLY::DOM::SkipSpacesAndLineEnd(buffer);
+
+ // now parse all properties of the element
+ while (true)
+ {
+ streamBuffer.getNextLine(buffer);
+ pCur = (char*)&buffer[0];
+
+ // skip all comments
+ PLY::DOM::SkipComments(buffer);
+
+ PLY::Property prop;
+ if (!PLY::Property::ParseProperty(buffer, &prop))
+ break;
+
+ pOut->alProperties.push_back(prop);
+ }
+
+ return true;
+}
+
+// ------------------------------------------------------------------------------------------------
+bool PLY::DOM::SkipSpaces(std::vector &buffer)
+{
+ const char* pCur = buffer.empty() ? NULL : (char*)&buffer[0];
+ bool ret = false;
+ if (pCur)
+ {
+ const char* szCur = pCur;
+ ret = Assimp::SkipSpaces(pCur, &pCur);
+
+ uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
+ buffer.erase(buffer.begin(), buffer.begin() + iDiff);
+ return ret;
+ }
+
+ return ret;
+}
+
+bool PLY::DOM::SkipLine(std::vector &buffer)
+{
+ const char* pCur = buffer.empty() ? NULL : (char*)&buffer[0];
+ bool ret = false;
+ if (pCur)
+ {
+ const char* szCur = pCur;
+ ret = Assimp::SkipLine(pCur, &pCur);
+
+ uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
+ buffer.erase(buffer.begin(), buffer.begin() + iDiff);
+ return ret;
+ }
+
+ return ret;
+}
+
+bool PLY::DOM::TokenMatch(std::vector &buffer, const char* token, unsigned int len)
+{
+ const char* pCur = buffer.empty() ? NULL : (char*)&buffer[0];
+ bool ret = false;
+ if (pCur)
+ {
+ const char* szCur = pCur;
+ ret = Assimp::TokenMatch(pCur, token, len);
+
+ uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
+ buffer.erase(buffer.begin(), buffer.begin() + iDiff);
+ return ret;
+ }
+
+ return ret;
+}
+
+bool PLY::DOM::SkipSpacesAndLineEnd(std::vector &buffer)
+{
+ const char* pCur = buffer.empty() ? NULL : (char*)&buffer[0];
+ bool ret = false;
+ if (pCur)
+ {
+ const char* szCur = pCur;
+ ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur);
+
+ uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
+ buffer.erase(buffer.begin(), buffer.begin() + iDiff);
+ return ret;
+ }
+
+ return ret;
+}
+
+bool PLY::DOM::SkipComments(std::vector &buffer)
+{
+ ai_assert(!buffer.empty());
+
+ std::vector nbuffer = buffer;
+ // skip spaces
+ if (!SkipSpaces(nbuffer)) {
+ return false;
+ }
+
+ if (TokenMatch(nbuffer, "comment", 7))
+ {
+ if (!SkipSpaces(nbuffer))
+ SkipLine(nbuffer);
+
+ if (!TokenMatch(nbuffer, "TextureFile", 11))
+ {
+ SkipLine(nbuffer);
+ buffer = nbuffer;
+ return true;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+// ------------------------------------------------------------------------------------------------
+bool PLY::DOM::ParseHeader(IOStreamBuffer &streamBuffer, std::vector &buffer, bool isBinary) {
+ DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin");
+
+ // parse all elements
+ while (!buffer.empty())
+ {
+ // skip all comments
+ PLY::DOM::SkipComments(buffer);
+
+ PLY::Element out;
+ if (PLY::Element::ParseElement(streamBuffer, buffer, &out))
+ {
+ // add the element to the list of elements
+ alElements.push_back(out);
+ }
+ else if (TokenMatch(buffer, "end_header", 10))
+ {
+ // we have reached the end of the header
+ break;
+ }
+ else
+ {
+ // ignore unknown header elements
+ streamBuffer.getNextLine(buffer);
+ }
+ }
+
+ if (!isBinary) // it would occur an error, if binary data start with values as space or line end.
+ SkipSpacesAndLineEnd(buffer);
+
+ DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded");
+ return true;
+}
+
+// ------------------------------------------------------------------------------------------------
+bool PLY::DOM::ParseElementInstanceLists(IOStreamBuffer &streamBuffer, std::vector &buffer, PLYImporter* loader)
+{
+ DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() begin");
+ alElementData.resize(alElements.size());
+
+ std::vector::const_iterator i = alElements.begin();
+ std::vector::iterator a = alElementData.begin();
+
+ // parse all element instances
+ //construct vertices and faces
+ for (; i != alElements.end(); ++i, ++a)
+ {
+ if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip)
+ {
+ PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), NULL, loader);
+ }
+ else
+ {
+ (*a).alInstances.resize((*i).NumOccur);
+ PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), &(*a), NULL);
+ }
+ }
+
+ DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() succeeded");
+ return true;
+}
+
+// ------------------------------------------------------------------------------------------------
+bool PLY::DOM::ParseElementInstanceListsBinary(IOStreamBuffer &streamBuffer, std::vector &buffer,
+ const char* &pCur,
+ unsigned int &bufferSize,
+ PLYImporter* loader,
bool p_bBE)
{
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut);
+ DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() begin");
+ alElementData.resize(alElements.size());
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() begin");
- *pCurOut = pCur;
+ std::vector::const_iterator i = alElements.begin();
+ std::vector::iterator a = alElementData.begin();
- alElementData.resize(alElements.size());
-
- std::vector::const_iterator i = alElements.begin();
- std::vector::iterator a = alElementData.begin();
-
- // parse all element instances
- for (;i != alElements.end();++i,++a)
+ // parse all element instances
+ for (; i != alElements.end(); ++i, ++a)
+ {
+ if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip)
{
- (*a).alInstances.resize((*i).NumOccur);
- PLY::ElementInstanceList::ParseInstanceListBinary(pCur,&pCur,&(*i),&(*a),p_bBE);
- }
-
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() succeeded");
- *pCurOut = pCur;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseInstanceBinary (const char* pCur,DOM* p_pcOut,bool p_bBE)
-{
- ai_assert( NULL != pCur );
- ai_assert( NULL != p_pcOut );
-
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin");
-
- if(!p_pcOut->ParseHeader(pCur,&pCur,true))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
- return false;
- }
- if(!p_pcOut->ParseElementInstanceListsBinary(pCur,&pCur,p_bBE))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
- return false;
- }
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseInstance (const char* pCur,DOM* p_pcOut)
-{
- ai_assert(NULL != pCur);
- ai_assert(NULL != p_pcOut);
-
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin");
-
-
- if(!p_pcOut->ParseHeader(pCur,&pCur,false))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
- return false;
- }
- if(!p_pcOut->ParseElementInstanceLists(pCur,&pCur))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
- return false;
- }
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstanceList::ParseInstanceList (
- const char* pCur,
- const char** pCurOut,
- const PLY::Element* pcElement,
- PLY::ElementInstanceList* p_pcOut)
-{
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
- ai_assert( NULL != pcElement );
- ai_assert( NULL != p_pcOut );
-
- if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty())
- {
- // if the element has an unknown semantic we can skip all lines
- // However, there could be comments
- for (unsigned int i = 0; i < pcElement->NumOccur;++i)
- {
- PLY::DOM::SkipComments(pCur,&pCur);
- SkipLine(pCur,&pCur);
- }
+ PLY::ElementInstanceList::ParseInstanceListBinary(streamBuffer, buffer, pCur, bufferSize, &(*i), NULL, loader, p_bBE);
}
else
{
- // be sure to have enough storage
- for (unsigned int i = 0; i < pcElement->NumOccur;++i)
- {
- PLY::DOM::SkipComments(pCur,&pCur);
- PLY::ElementInstance::ParseInstance(pCur, &pCur,pcElement,
- &p_pcOut->alInstances[i]);
- }
+ (*a).alInstances.resize((*i).NumOccur);
+ PLY::ElementInstanceList::ParseInstanceListBinary(streamBuffer, buffer, pCur, bufferSize, &(*i), &(*a), NULL, p_bBE);
}
- *pCurOut = pCur;
- return true;
+ }
+
+ DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() succeeded");
+ return true;
}
// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstanceList::ParseInstanceListBinary (
- const char* pCur,
- const char** pCurOut,
- const PLY::Element* pcElement,
- PLY::ElementInstanceList* p_pcOut,
- bool p_bBE /* = false */)
+bool PLY::DOM::ParseInstanceBinary(IOStreamBuffer &streamBuffer, DOM* p_pcOut, PLYImporter* loader, bool p_bBE)
{
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
- ai_assert( NULL != pcElement );
- ai_assert( NULL != p_pcOut );
+ ai_assert(NULL != p_pcOut);
+ ai_assert(NULL != loader);
- // we can add special handling code for unknown element semantics since
- // we can't skip it as a whole block (we don't know its exact size
- // due to the fact that lists could be contained in the property list
- // of the unknown element)
- for (unsigned int i = 0; i < pcElement->NumOccur;++i)
- {
- PLY::ElementInstance::ParseInstanceBinary(pCur, &pCur,pcElement,
- &p_pcOut->alInstances[i], p_bBE);
- }
- *pCurOut = pCur;
- return true;
+ std::vector buffer;
+ streamBuffer.getNextLine(buffer);
+
+ DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin");
+
+ if (!p_pcOut->ParseHeader(streamBuffer, buffer, true))
+ {
+ DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
+ return false;
+ }
+
+ streamBuffer.getNextBlock(buffer);
+ unsigned int bufferSize = buffer.size();
+ const char* pCur = (char*)&buffer[0];
+ if (!p_pcOut->ParseElementInstanceListsBinary(streamBuffer, buffer, pCur, bufferSize, loader, p_bBE))
+ {
+ DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
+ return false;
+ }
+ DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() succeeded");
+ return true;
}
// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstance::ParseInstance (
- const char* pCur,
- const char** pCurOut,
- const PLY::Element* pcElement,
- PLY::ElementInstance* p_pcOut)
+bool PLY::DOM::ParseInstance(IOStreamBuffer &streamBuffer, DOM* p_pcOut, PLYImporter* loader)
{
- ai_assert( NULL != pCur );
- ai_assert( NULL != pCurOut );
- ai_assert( NULL != pcElement );
- ai_assert( NULL != p_pcOut );
+ ai_assert(NULL != p_pcOut);
+ ai_assert(NULL != loader);
- if (!SkipSpaces(pCur, &pCur)) {
- return false;
- }
+ std::vector buffer;
+ streamBuffer.getNextLine(buffer);
- // allocate enough storage
- p_pcOut->alProperties.resize(pcElement->alProperties.size());
+ DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin");
- std::vector::iterator i = p_pcOut->alProperties.begin();
- std::vector::const_iterator a = pcElement->alProperties.begin();
- for (;i != p_pcOut->alProperties.end();++i,++a)
- {
- if(!(PLY::PropertyInstance::ParseInstance(pCur, &pCur,&(*a),&(*i))))
- {
- DefaultLogger::get()->warn("Unable to parse property instance. "
- "Skipping this element instance");
+ if (!p_pcOut->ParseHeader(streamBuffer, buffer, false))
+ {
+ DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
+ return false;
+ }
- // skip the rest of the instance
- SkipLine(pCur, &pCur);
-
- PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType);
- (*i).avList.push_back(v);
- }
- }
- *pCurOut = pCur;
- return true;
+ //get next line after header
+ streamBuffer.getNextLine(buffer);
+ if (!p_pcOut->ParseElementInstanceLists(streamBuffer, buffer, loader))
+ {
+ DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
+ return false;
+ }
+ DefaultLogger::get()->debug("PLY::DOM::ParseInstance() succeeded");
+ return true;
}
// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstance::ParseInstanceBinary (
- const char* pCur,
- const char** pCurOut,
- const PLY::Element* pcElement,
- PLY::ElementInstance* p_pcOut,
- bool p_bBE /* = false */)
+bool PLY::ElementInstanceList::ParseInstanceList(
+ IOStreamBuffer &streamBuffer,
+ std::vector