Merge branch 'master' into coverity_scan
commit
e6cfe6b5c8
|
@ -5,7 +5,8 @@ function generate()
|
||||||
|
|
||||||
if [ $ANDROID ]; then
|
if [ $ANDROID ]; then
|
||||||
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
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 \
|
generate \
|
||||||
&& make -j4 \
|
&& make -j4 \
|
||||||
&& sudo make install \
|
&& sudo make install \
|
||||||
|
|
47
.travis.yml
47
.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:
|
env:
|
||||||
global:
|
global:
|
||||||
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
|
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
|
||||||
|
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
|
||||||
before_install:
|
matrix:
|
||||||
- sudo apt-get update -qq
|
- LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON
|
||||||
- sudo apt-get install cmake
|
- LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF
|
||||||
- echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
|
- LINUX=1 SHARED_BUILD=ON ENABLE_COVERALLS=OFF
|
||||||
|
- LINUX=1 SHARED_BUILD=OFF ENABLE_COVERALLS=OFF
|
||||||
language: cpp
|
#exclude:
|
||||||
|
# - os: linux
|
||||||
|
# compiler: clang
|
||||||
|
# - os: osx
|
||||||
|
# compiler: gcc
|
||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
- clang
|
- clang
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
cmake .
|
# init coverage to 0 (optional)
|
||||||
|
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --zerocounters ; fi
|
||||||
|
|
||||||
script:
|
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:
|
addons:
|
||||||
coverity_scan:
|
coverity_scan:
|
||||||
|
|
|
@ -89,6 +89,10 @@ OPTION ( BUILD_DOCS
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
add_definitions( -DWIN32_LEAN_AND_MEAN )
|
||||||
|
endif()
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
||||||
OPTION( ASSIMP_INSTALL_PDB
|
OPTION( ASSIMP_INSTALL_PDB
|
||||||
|
@ -141,6 +145,13 @@ IF(ASSIMP_DOUBLE_PRECISION)
|
||||||
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
||||||
ENDIF(ASSIMP_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(
|
configure_file(
|
||||||
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
||||||
|
@ -157,7 +168,7 @@ include_directories(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/include
|
${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_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(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)
|
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)
|
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
||||||
# hide all not-exported symbols
|
# hide all not-exported symbols
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -std=c++0x")
|
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++)
|
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
||||||
ELSEIF(MSVC)
|
ELSEIF(MSVC)
|
||||||
# enable multi-core compilation with MSVC
|
# enable multi-core compilation with MSVC
|
||||||
|
|
16
Readme.md
16
Readme.md
|
@ -1,6 +1,6 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
==================================
|
==================================
|
||||||
|
### Current build status ###
|
||||||
[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
|
[![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)
|
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
|
||||||
<a href="https://scan.coverity.com/projects/5607">
|
<a href="https://scan.coverity.com/projects/5607">
|
||||||
|
@ -9,22 +9,19 @@ Open Asset Import Library (assimp)
|
||||||
</a>
|
</a>
|
||||||
<span class="badge-patreon"><a href="https://www.patreon.com/assimp" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
|
<span class="badge-patreon"><a href="https://www.patreon.com/assimp" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
|
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
|
||||||
|
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
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.
|
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.
|
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).
|
||||||
The current build status is:
|
|
||||||
|
|
||||||
Gitter chat: [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
One-off donations via PayPal:
|
||||||
|
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
|
||||||
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
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
|
|
||||||
|
|
||||||
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
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)
|
* [Pascal](port/AssimpPascal/Readme.md)
|
||||||
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
|
* [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 ####
|
#### Repository structure ####
|
||||||
Open Asset Import Library is implemented in C++. The directory structure is:
|
Open Asset Import Library is implemented in C++. The directory structure is:
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "3DSExporter.h"
|
#include "3DSExporter.h"
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
#include "3DSHelper.h"
|
#include "3DSHelper.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "SplitLargeMeshes.h"
|
#include "SplitLargeMeshes.h"
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
|
@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "AMFImporter.hpp"
|
#include "AMFImporter.hpp"
|
||||||
|
|
||||||
// Header files, Assimp.
|
// Header files, Assimp.
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "StandardShapes.h"
|
#include "StandardShapes.h"
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
// underlying structure for aiPropertyStore
|
// underlying structure for aiPropertyStore
|
||||||
typedef BatchLoader::PropertyMap PropertyMap;
|
typedef BatchLoader::PropertyMap PropertyMap;
|
||||||
|
|
||||||
|
@ -110,12 +109,11 @@ static std::mutex gLogStreamMutex;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Custom LogStream implementation for the C-API
|
// Custom LogStream implementation for the C-API
|
||||||
class LogToCallbackRedirector : public LogStream
|
class LogToCallbackRedirector : public LogStream {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit LogToCallbackRedirector(const aiLogStream& s)
|
explicit LogToCallbackRedirector(const aiLogStream& s)
|
||||||
: stream (s) {
|
: stream (s) {
|
||||||
ai_assert(NULL != s.callback);
|
ai_assert(NULL != s.callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
~LogToCallbackRedirector() {
|
~LogToCallbackRedirector() {
|
||||||
|
@ -146,8 +144,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ReportSceneNotFoundError()
|
void ReportSceneNotFoundError() {
|
||||||
{
|
|
||||||
DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
|
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");
|
"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.
|
// 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);
|
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);
|
return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
|
const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
|
||||||
aiFileIO* pFS,
|
aiFileIO* pFS, const aiPropertyStore* props) {
|
||||||
const aiPropertyStore* props)
|
|
||||||
{
|
|
||||||
ai_assert(NULL != pFile);
|
ai_assert(NULL != pFile);
|
||||||
|
|
||||||
const aiScene* scene = NULL;
|
const aiScene* scene = NULL;
|
||||||
|
@ -190,7 +183,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
|
||||||
pimpl->mMatrixProperties = pp->matrices;
|
pimpl->mMatrixProperties = pp->matrices;
|
||||||
}
|
}
|
||||||
// setup a custom IO system if necessary
|
// setup a custom IO system if necessary
|
||||||
if (pFS) {
|
if (pFS) {
|
||||||
imp->SetIOHandler( new CIOSystemWrapper (pFS) );
|
imp->SetIOHandler( new CIOSystemWrapper (pFS) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,8 +194,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
|
||||||
if( scene) {
|
if( scene) {
|
||||||
ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
||||||
priv->mOrigImporter = imp;
|
priv->mOrigImporter = imp;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// if failed, extract error code and destroy the import
|
// if failed, extract error code and destroy the import
|
||||||
gLastErrorString = imp->GetErrorString();
|
gLastErrorString = imp->GetErrorString();
|
||||||
delete imp;
|
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
|
// return imported data. If the import failed the pointer is NULL anyways
|
||||||
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
||||||
|
|
||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,9 @@ Assimp C export interface. See Exporter.cpp for some notes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
||||||
#include "CInterfaceIOWrapper.h"
|
#include "CInterfaceIOWrapper.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "ScenePrivate.h"
|
#include "ScenePrivate.h"
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
|
|
|
@ -303,24 +303,13 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
#include "../contrib/utf8cpp/source/utf8.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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Convert to UTF8 data
|
// Convert to UTF8 data
|
||||||
void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||||
{
|
{
|
||||||
ConversionResult result;
|
//ConversionResult result;
|
||||||
if(data.size() < 8) {
|
if(data.size() < 8) {
|
||||||
throw DeadlyImportError("File is too small");
|
throw DeadlyImportError("File is too small");
|
||||||
}
|
}
|
||||||
|
@ -333,7 +322,8 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||||
data.resize(data.size()-3);
|
data.resize(data.size()-3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// UTF 32 BE with BOM
|
// UTF 32 BE with BOM
|
||||||
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
|
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
|
||||||
|
|
||||||
|
@ -347,21 +337,10 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||||
if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
|
if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
|
||||||
DefaultLogger::get()->debug("Found UTF-32 BOM ...");
|
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<char> output;
|
std::vector<char> output;
|
||||||
do {
|
int *ptr = (int*)&data[ 0 ];
|
||||||
output.resize(output.size()?output.size()*3/2:data.size()/2);
|
int *end = ptr + ( data.size() / sizeof(int) ) +1;
|
||||||
dstart = &output.front(),dend = &output.back()+1;
|
utf8::utf32to8( ptr, end, back_inserter(output));
|
||||||
|
|
||||||
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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,21 +357,9 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||||
if(*((uint16_t*)&data.front()) == 0xFEFF) {
|
if(*((uint16_t*)&data.front()) == 0xFEFF) {
|
||||||
DefaultLogger::get()->debug("Found UTF-16 BOM ...");
|
DefaultLogger::get()->debug("Found UTF-16 BOM ...");
|
||||||
|
|
||||||
const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
|
std::vector<unsigned char> output;
|
||||||
char* dstart,*dend;
|
int16_t *ptr = (int16_t*) &data[ 0 ];
|
||||||
std::vector<char> output;
|
utf8::utf16to8(data.begin(), data.end(), back_inserter(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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,6 @@ class BaseProcess;
|
||||||
class SharedPostProcessInfo;
|
class SharedPostProcessInfo;
|
||||||
class IOStream;
|
class IOStream;
|
||||||
|
|
||||||
|
|
||||||
// utility to do char4 to uint32 in a portable manner
|
// utility to do char4 to uint32 in a portable manner
|
||||||
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
||||||
(string[1] << 16) + (string[2] << 8) + string[3]))
|
(string[1] << 16) + (string[2] << 8) + string[3]))
|
||||||
|
@ -194,14 +193,11 @@ public:
|
||||||
const Importer* pImp
|
const Importer* pImp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called by #Importer::GetImporterInfo to get a description of
|
/** Called by #Importer::GetImporterInfo to get a description of
|
||||||
* some loader features. Importers must provide this information. */
|
* some loader features. Importers must provide this information. */
|
||||||
virtual const aiImporterDesc* GetInfo() const = 0;
|
virtual const aiImporterDesc* GetInfo() const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called by #Importer::GetExtensionList for each loaded importer.
|
/** Called by #Importer::GetExtensionList for each loaded importer.
|
||||||
* Take the extension list contained in the structure returned by
|
* 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.
|
* @param Size of one token, in bytes. Maximally 16 bytes.
|
||||||
* @return true if one of the given tokens was found
|
* @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
|
* byte-swapped variant of all tokens (big endian). Only for
|
||||||
* tokens of size 2,4.
|
* tokens of size 2,4.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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).
|
* @brief Implementation of some blender modifiers (i.e subdivision, mirror).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
#include "BlenderModifier.h"
|
#include "BlenderModifier.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "Subdivision.h"
|
#include "Subdivision.h"
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
|
@ -96,6 +96,7 @@ SET( PUBLIC_HEADERS
|
||||||
${HEADER_PATH}/Exporter.hpp
|
${HEADER_PATH}/Exporter.hpp
|
||||||
${HEADER_PATH}/DefaultIOStream.h
|
${HEADER_PATH}/DefaultIOStream.h
|
||||||
${HEADER_PATH}/DefaultIOSystem.h
|
${HEADER_PATH}/DefaultIOSystem.h
|
||||||
|
${HEADER_PATH}/SceneCombiner.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET( Core_SRCS
|
SET( Core_SRCS
|
||||||
|
@ -148,7 +149,6 @@ SET( Common_SRCS
|
||||||
SpatialSort.cpp
|
SpatialSort.cpp
|
||||||
SpatialSort.h
|
SpatialSort.h
|
||||||
SceneCombiner.cpp
|
SceneCombiner.cpp
|
||||||
SceneCombiner.h
|
|
||||||
ScenePreprocessor.cpp
|
ScenePreprocessor.cpp
|
||||||
ScenePreprocessor.h
|
ScenePreprocessor.h
|
||||||
SkeletonMeshBuilder.cpp
|
SkeletonMeshBuilder.cpp
|
||||||
|
@ -695,11 +695,6 @@ SET( Extra_SRCS
|
||||||
)
|
)
|
||||||
SOURCE_GROUP( Extra FILES ${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
|
SET( Clipper_SRCS
|
||||||
../contrib/clipper/clipper.hpp
|
../contrib/clipper/clipper.hpp
|
||||||
|
@ -737,10 +732,12 @@ SET ( openddl_parser_SRCS
|
||||||
../contrib/openddlparser/code/OpenDDLCommon.cpp
|
../contrib/openddlparser/code/OpenDDLCommon.cpp
|
||||||
../contrib/openddlparser/code/OpenDDLExport.cpp
|
../contrib/openddlparser/code/OpenDDLExport.cpp
|
||||||
../contrib/openddlparser/code/Value.cpp
|
../contrib/openddlparser/code/Value.cpp
|
||||||
|
../contrib/openddlparser/code/OpenDDLStream.cpp
|
||||||
../contrib/openddlparser/include/openddlparser/OpenDDLParser.h
|
../contrib/openddlparser/include/openddlparser/OpenDDLParser.h
|
||||||
../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
|
../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
|
||||||
../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
|
../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
|
||||||
../contrib/openddlparser/include/openddlparser/OpenDDLExport.h
|
../contrib/openddlparser/include/openddlparser/OpenDDLExport.h
|
||||||
|
../contrib/openddlparser/include/openddlparser/OpenDDLStream.h
|
||||||
../contrib/openddlparser/include/openddlparser/DDLNode.h
|
../contrib/openddlparser/include/openddlparser/DDLNode.h
|
||||||
../contrib/openddlparser/include/openddlparser/Value.h
|
../contrib/openddlparser/include/openddlparser/Value.h
|
||||||
)
|
)
|
||||||
|
@ -835,7 +832,6 @@ SET( assimp_src
|
||||||
|
|
||||||
# Third-party libraries
|
# Third-party libraries
|
||||||
${IrrXML_SRCS}
|
${IrrXML_SRCS}
|
||||||
${ConvertUTF_SRCS}
|
|
||||||
${unzip_compile_SRCS}
|
${unzip_compile_SRCS}
|
||||||
${Poly2Tri_SRCS}
|
${Poly2Tri_SRCS}
|
||||||
${Clipper_SRCS}
|
${Clipper_SRCS}
|
||||||
|
|
|
@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ColladaExporter.h"
|
#include "ColladaExporter.h"
|
||||||
#include "Bitmap.h"
|
#include "Bitmap.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
#include "XMLTools.h"
|
#include "XMLTools.h"
|
||||||
#include <assimp/DefaultIOSystem.h>
|
#include <assimp/DefaultIOSystem.h>
|
||||||
|
|
|
@ -1726,6 +1726,8 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
|
||||||
aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
|
aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
|
||||||
const Collada::Effect& pEffect, const std::string& pName)
|
const Collada::Effect& pEffect, const std::string& pName)
|
||||||
{
|
{
|
||||||
|
aiString result;
|
||||||
|
|
||||||
// recurse through the param references until we end up at an image
|
// recurse through the param references until we end up at an image
|
||||||
std::string name = pName;
|
std::string name = pName;
|
||||||
while( 1)
|
while( 1)
|
||||||
|
@ -1744,11 +1746,17 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
|
||||||
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
|
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
|
||||||
if( imIt == pParser.mImageLibrary.end())
|
if( imIt == pParser.mImageLibrary.end())
|
||||||
{
|
{
|
||||||
throw DeadlyImportError( format() <<
|
//missing texture should not stop the conversion
|
||||||
"Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
|
//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 this is an embedded texture image setup an aiTexture for it
|
||||||
if (imIt->second.mFileName.empty())
|
if (imIt->second.mFileName.empty())
|
||||||
|
|
|
@ -54,7 +54,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
||||||
#include "BlobIOSystem.h"
|
#include "BlobIOSystem.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "BaseProcess.h"
|
#include "BaseProcess.h"
|
||||||
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
|
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,7 @@ namespace MDL {
|
||||||
* \brief Data structure for the HL2 main header
|
* \brief Data structure for the HL2 main header
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
struct Header_HL2
|
struct Header_HL2 {
|
||||||
{
|
|
||||||
//! magic number: "IDST"/"IDSQ"
|
//! magic number: "IDST"/"IDSQ"
|
||||||
char ident[4];
|
char ident[4];
|
||||||
|
|
||||||
|
@ -139,7 +138,7 @@ struct Header_HL2
|
||||||
//! Number of animation transitions
|
//! Number of animation transitions
|
||||||
int32_t numtransitions;
|
int32_t numtransitions;
|
||||||
int32_t transitionindex;
|
int32_t transitionindex;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
#include "./../include/assimp/Compiler/poppack1.h"
|
#include "./../include/assimp/Compiler/poppack1.h"
|
||||||
|
|
||||||
|
|
|
@ -882,6 +882,7 @@ void ProcessSpatialStructures(ConversionData& conv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<aiNode*> nodes;
|
||||||
|
|
||||||
for(const STEP::LazyObject* lz : *range) {
|
for(const STEP::LazyObject* lz : *range) {
|
||||||
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
|
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
|
||||||
|
@ -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():""));
|
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();
|
const STEP::DB::RefMap& refs = conv.db.GetRefs();
|
||||||
STEP::DB::RefMapRange range = refs.equal_range(conv.proj.GetID());
|
STEP::DB::RefMapRange ref_range = refs.equal_range(conv.proj.GetID());
|
||||||
for(;range.first != range.second; ++range.first) {
|
for(; ref_range.first != ref_range.second; ++ref_range.first) {
|
||||||
if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr<IfcRelAggregates>()) {
|
if(const IfcRelAggregates* const aggr = conv.db.GetObject((*ref_range.first).second)->ToPtr<IfcRelAggregates>()) {
|
||||||
|
|
||||||
for(const IfcObjectDefinition& def : aggr->RelatedObjects) {
|
for(const IfcObjectDefinition& def : aggr->RelatedObjects) {
|
||||||
// comparing pointer values is not sufficient, we would need to cast them to the same type first
|
// 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.
|
// as there is multiple inheritance in the game.
|
||||||
if (def.GetID() == prod->GetID()) {
|
if (def.GetID() == prod->GetID()) {
|
||||||
IFCImporter::LogDebug("selecting this spatial structure as root structure");
|
IFCImporter::LogDebug("selecting this spatial structure as root structure");
|
||||||
// got it, this is the primary site.
|
// got it, this is one primary site.
|
||||||
conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
|
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
if (nb_nodes == 0) {
|
||||||
for(const STEP::LazyObject* lz : *range) {
|
IFCImporter::LogWarn("failed to determine primary site element, taking all the IfcSite");
|
||||||
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
|
for (const STEP::LazyObject* lz : *range) {
|
||||||
if(!prod) {
|
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
|
||||||
continue;
|
if (!prod) {
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
|
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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<unsigned int>(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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/IOStream.hpp>
|
#include <assimp/IOStream.hpp>
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -69,8 +71,8 @@ public:
|
||||||
/// @return true if successful.
|
/// @return true if successful.
|
||||||
bool close();
|
bool close();
|
||||||
|
|
||||||
/// @brief Returns the filesize.
|
/// @brief Returns the file-size.
|
||||||
/// @return The filesize.
|
/// @return The file-size.
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
/// @brief Returns the cache size.
|
/// @brief Returns the cache size.
|
||||||
|
@ -96,7 +98,17 @@ public:
|
||||||
/// @brief Will read the next line.
|
/// @brief Will read the next line.
|
||||||
/// @param buffer The buffer for the next line.
|
/// @param buffer The buffer for the next line.
|
||||||
/// @return true if successful.
|
/// @return true if successful.
|
||||||
bool getNextLine( std::vector<T> &buffer );
|
bool getNextDataLine( std::vector<T> &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<T> &buffer);
|
||||||
|
|
||||||
|
/// @brief Will read the next block.
|
||||||
|
/// @param buffer The buffer for the next block.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool getNextBlock( std::vector<T> &buffer );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IOStream *m_stream;
|
IOStream *m_stream;
|
||||||
|
@ -227,15 +239,35 @@ size_t IOStreamBuffer<T>::getFilePos() const {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline
|
inline
|
||||||
bool IOStreamBuffer<T>::getNextLine( std::vector<T> &buffer ) {
|
bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
|
||||||
buffer.resize( m_cacheSize );
|
buffer.resize( m_cacheSize );
|
||||||
if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
|
if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
|
||||||
if ( !readNextBlock() ) {
|
if ( !readNextBlock() ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool continuationFound( false ), endOfDataLine( false );
|
||||||
size_t i = 0;
|
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 ];
|
buffer[ i ] = m_cache[ m_cachePos ];
|
||||||
m_cachePos++;
|
m_cachePos++;
|
||||||
i++;
|
i++;
|
||||||
|
@ -245,10 +277,63 @@ bool IOStreamBuffer<T>::getNextLine( std::vector<T> &buffer ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[ i ] = '\n';
|
buffer[ i ] = '\n';
|
||||||
m_cachePos++;
|
m_cachePos++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &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<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
|
||||||
|
//just return the last blockvalue if getNextLine was used before
|
||||||
|
if ( m_cachePos != 0) {
|
||||||
|
buffer = std::vector<T>(m_cache.begin() + m_cachePos, m_cache.end());
|
||||||
|
m_cachePos = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( !readNextBlock() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
buffer = std::vector<T>(m_cache.begin(), m_cache.end());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // !ns Assimp
|
} // !ns Assimp
|
||||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "GenericProperty.h"
|
#include "GenericProperty.h"
|
||||||
|
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "StandardShapes.h"
|
#include "StandardShapes.h"
|
||||||
#include "Importer.h"
|
#include "Importer.h"
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_IRRLOADER_H_INCLUDED
|
#define AI_IRRLOADER_H_INCLUDED
|
||||||
|
|
||||||
#include "IRRShared.h"
|
#include "IRRShared.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "Importer.h"
|
#include "Importer.h"
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
#include <assimp/anim.h>
|
#include <assimp/anim.h>
|
||||||
|
|
|
@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "LWOFileData.h"
|
#include "LWOFileData.h"
|
||||||
|
#include <assimp/anim.h>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::LWO;
|
using namespace Assimp::LWO;
|
||||||
|
|
|
@ -48,11 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_LWO_ANIMATION_INCLUDED
|
#ifndef AI_LWO_ANIMATION_INCLUDED
|
||||||
#define AI_LWO_ANIMATION_INCLUDED
|
#define AI_LWO_ANIMATION_INCLUDED
|
||||||
|
|
||||||
#include <assimp/anim.h>
|
//
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
struct aiNodeAnim;
|
struct aiNodeAnim;
|
||||||
|
struct aiVectorKey;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace LWO {
|
namespace LWO {
|
||||||
|
@ -166,7 +167,6 @@ struct Envelope
|
||||||
//! Keyframes for this envelope
|
//! Keyframes for this envelope
|
||||||
std::vector<Key> keys;
|
std::vector<Key> keys;
|
||||||
|
|
||||||
|
|
||||||
// temporary data for AnimResolver
|
// temporary data for AnimResolver
|
||||||
size_t old_first,old_last;
|
size_t old_first,old_last;
|
||||||
};
|
};
|
||||||
|
@ -198,8 +198,7 @@ public:
|
||||||
* @param Output tick rate, per second
|
* @param Output tick rate, per second
|
||||||
* @note The input envelopes are possibly modified.
|
* @note The input envelopes are possibly modified.
|
||||||
*/
|
*/
|
||||||
AnimResolver(std::list<Envelope>& envelopes,
|
AnimResolver(std::list<Envelope>& envelopes, double tick);
|
||||||
double tick);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
|
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "GenericProperty.h"
|
#include "GenericProperty.h"
|
||||||
#include "SkeletonMeshBuilder.h"
|
#include "SkeletonMeshBuilder.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "ConvertToLHProcess.h"
|
||||||
|
|
|
@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_LWSLOADER_H_INCLUDED
|
#define AI_LWSLOADER_H_INCLUDED
|
||||||
|
|
||||||
#include "LWOFileData.h"
|
#include "LWOFileData.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
|
|
||||||
struct aiImporterDesc;
|
struct aiImporterDesc;
|
||||||
|
|
|
@ -142,14 +142,14 @@ struct Frame
|
||||||
//! name of frame
|
//! name of frame
|
||||||
char name[ AI_MD3_MAXFRAME ];
|
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
|
//! name of the tag
|
||||||
char NAME[ AI_MD3_MAXQPATH ];
|
char NAME[ AI_MD3_MAXQPATH ];
|
||||||
|
|
||||||
|
@ -157,14 +157,13 @@ struct Tag
|
||||||
aiVector3D origin;
|
aiVector3D origin;
|
||||||
ai_real orientation[3][3];
|
ai_real orientation[3][3];
|
||||||
|
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** @brief Data structure for the surface header
|
/** @brief Data structure for the surface header
|
||||||
*/
|
*/
|
||||||
struct Surface
|
struct Surface {
|
||||||
{
|
|
||||||
//! magic number
|
//! magic number
|
||||||
int32_t IDENT;
|
int32_t IDENT;
|
||||||
|
|
||||||
|
@ -186,7 +185,6 @@ struct Surface
|
||||||
//! number of triangles in the surface
|
//! number of triangles in the surface
|
||||||
uint32_t NUM_TRIANGLES;
|
uint32_t NUM_TRIANGLES;
|
||||||
|
|
||||||
|
|
||||||
//! offset to the triangle data
|
//! offset to the triangle data
|
||||||
uint32_t OFS_TRIANGLES;
|
uint32_t OFS_TRIANGLES;
|
||||||
|
|
||||||
|
@ -201,19 +199,18 @@ struct Surface
|
||||||
|
|
||||||
//! offset to the end of the Surface object
|
//! offset to the end of the Surface object
|
||||||
int32_t OFS_END;
|
int32_t OFS_END;
|
||||||
} PACK_STRUCT;
|
} /*PACK_STRUCT*/;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** @brief Data structure for a shader defined in there
|
/** @brief Data structure for a shader defined in there
|
||||||
*/
|
*/
|
||||||
struct Shader
|
struct Shader {
|
||||||
{
|
|
||||||
//! filename of the shader
|
//! filename of the shader
|
||||||
char NAME[ AI_MD3_MAXQPATH ];
|
char NAME[ AI_MD3_MAXQPATH ];
|
||||||
|
|
||||||
//! index of the shader
|
//! index of the shader
|
||||||
uint32_t SHADER_INDEX;
|
uint32_t SHADER_INDEX;
|
||||||
} PACK_STRUCT;
|
} /*PACK_STRUCT*/;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -223,7 +220,7 @@ struct Triangle
|
||||||
{
|
{
|
||||||
//! triangle indices
|
//! triangle indices
|
||||||
uint32_t INDEXES[3];
|
uint32_t INDEXES[3];
|
||||||
} PACK_STRUCT;
|
} /*PACK_STRUCT*/;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -233,7 +230,7 @@ struct TexCoord
|
||||||
{
|
{
|
||||||
//! UV coordinates
|
//! UV coordinates
|
||||||
ai_real U,V;
|
ai_real U,V;
|
||||||
} PACK_STRUCT;
|
} /*PACK_STRUCT*/;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -246,7 +243,7 @@ struct Vertex
|
||||||
|
|
||||||
//! encoded normal vector
|
//! encoded normal vector
|
||||||
uint16_t NORMAL;
|
uint16_t NORMAL;
|
||||||
} PACK_STRUCT;
|
} /*PACK_STRUCT*/;
|
||||||
|
|
||||||
#include "./../include/assimp/Compiler/poppack1.h"
|
#include "./../include/assimp/Compiler/poppack1.h"
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
|
||||||
|
|
||||||
#include "MD3Loader.h"
|
#include "MD3Loader.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "GenericProperty.h"
|
#include "GenericProperty.h"
|
||||||
#include "RemoveComments.h"
|
#include "RemoveComments.h"
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
|
|
|
@ -157,7 +157,7 @@ struct Frame
|
||||||
|
|
||||||
//! Name of the frame
|
//! Name of the frame
|
||||||
char name [ 16 ] ;
|
char name [ 16 ] ;
|
||||||
} PACK_STRUCT;
|
} /*PACK_STRUCT*/;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** \brief Data structure for a MDC triangle
|
/** \brief Data structure for a MDC triangle
|
||||||
|
|
|
@ -53,10 +53,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_MDLFILEHELPER_H_INC
|
#ifndef AI_MDLFILEHELPER_H_INC
|
||||||
#define AI_MDLFILEHELPER_H_INC
|
#define AI_MDLFILEHELPER_H_INC
|
||||||
|
|
||||||
|
#include <assimp/anim.h>
|
||||||
|
#include <assimp/mesh.h>
|
||||||
|
#include <assimp/Compiler/pushpack1.h>
|
||||||
#include "ByteSwapper.h"
|
#include "ByteSwapper.h"
|
||||||
#include "./../include/assimp/anim.h"
|
|
||||||
#include "./../include/assimp/mesh.h"
|
|
||||||
#include "./../include/assimp/Compiler/pushpack1.h"
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -90,7 +90,6 @@ namespace MDL {
|
||||||
#define AI_MDL_MAGIC_NUMBER_BE_GS7 AI_MAKE_MAGIC("MDL7")
|
#define AI_MDL_MAGIC_NUMBER_BE_GS7 AI_MAKE_MAGIC("MDL7")
|
||||||
#define AI_MDL_MAGIC_NUMBER_LE_GS7 AI_MAKE_MAGIC("7LDM")
|
#define AI_MDL_MAGIC_NUMBER_LE_GS7 AI_MAKE_MAGIC("7LDM")
|
||||||
|
|
||||||
|
|
||||||
// common limitations for Quake1 meshes. The loader does not check them,
|
// common limitations for Quake1 meshes. The loader does not check them,
|
||||||
// (however it warns) but models should not exceed these limits.
|
// (however it warns) but models should not exceed these limits.
|
||||||
#if (!defined AI_MDL_VERSION)
|
#if (!defined AI_MDL_VERSION)
|
||||||
|
@ -119,8 +118,7 @@ namespace MDL {
|
||||||
/** \struct Header
|
/** \struct Header
|
||||||
* \brief Data structure for the MDL main header
|
* \brief Data structure for the MDL main header
|
||||||
*/
|
*/
|
||||||
struct Header
|
struct Header {
|
||||||
{
|
|
||||||
//! magic number: "IDPO"
|
//! magic number: "IDPO"
|
||||||
uint32_t ident;
|
uint32_t ident;
|
||||||
|
|
||||||
|
@ -166,15 +164,14 @@ struct Header
|
||||||
|
|
||||||
//! Could be the total size of the file (and not a float)
|
//! Could be the total size of the file (and not a float)
|
||||||
float size;
|
float size;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Header_MDL7
|
/** \struct Header_MDL7
|
||||||
* \brief Data structure for the MDL 7 main header
|
* \brief Data structure for the MDL 7 main header
|
||||||
*/
|
*/
|
||||||
struct Header_MDL7
|
struct Header_MDL7 {
|
||||||
{
|
|
||||||
//! magic number: "MDL7"
|
//! magic number: "MDL7"
|
||||||
char ident[4];
|
char ident[4];
|
||||||
|
|
||||||
|
@ -226,15 +223,14 @@ struct Header_MDL7
|
||||||
|
|
||||||
//! Size of the Frame_MDL7 data structure used in the file
|
//! Size of the Frame_MDL7 data structure used in the file
|
||||||
uint16_t frame_stc_size;
|
uint16_t frame_stc_size;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Bone_MDL7
|
/** \struct Bone_MDL7
|
||||||
* \brief Data structure for a bone in a MDL7 file
|
* \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:
|
//! Index of the parent bone of *this* bone. 0xffff means:
|
||||||
//! "hey, I have no parent, I'm an orphan"
|
//! "hey, I have no parent, I'm an orphan"
|
||||||
uint16_t parent_index;
|
uint16_t parent_index;
|
||||||
|
@ -246,7 +242,7 @@ struct Bone_MDL7
|
||||||
|
|
||||||
//! Optional name of the bone
|
//! Optional name of the bone
|
||||||
char name[1 /* DUMMY SIZE */];
|
char name[1 /* DUMMY SIZE */];
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
|
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
|
||||||
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
|
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
|
||||||
|
@ -268,8 +264,7 @@ struct Bone_MDL7
|
||||||
/** \struct Group_MDL7
|
/** \struct Group_MDL7
|
||||||
* \brief Group in a MDL7 file
|
* \brief Group in a MDL7 file
|
||||||
*/
|
*/
|
||||||
struct Group_MDL7
|
struct Group_MDL7 {
|
||||||
{
|
|
||||||
//! = '1' -> triangle based Mesh
|
//! = '1' -> triangle based Mesh
|
||||||
unsigned char typ;
|
unsigned char typ;
|
||||||
|
|
||||||
|
@ -295,7 +290,7 @@ struct Group_MDL7
|
||||||
|
|
||||||
//! Number of frames
|
//! Number of frames
|
||||||
int32_t numframes;
|
int32_t numframes;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
|
#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
|
||||||
#define AI_MDL7_SKINTYPE_MATERIAL 0x10
|
#define AI_MDL7_SKINTYPE_MATERIAL 0x10
|
||||||
|
@ -310,41 +305,36 @@ struct Group_MDL7
|
||||||
/** \struct Deformer_MDL7
|
/** \struct Deformer_MDL7
|
||||||
* \brief Deformer in a MDL7 file
|
* \brief Deformer in a MDL7 file
|
||||||
*/
|
*/
|
||||||
struct Deformer_MDL7
|
struct Deformer_MDL7 {
|
||||||
{
|
|
||||||
int8_t deformer_version; // 0
|
int8_t deformer_version; // 0
|
||||||
int8_t deformer_typ; // 0 - bones
|
int8_t deformer_typ; // 0 - bones
|
||||||
int8_t _unused_[2];
|
int8_t _unused_[2];
|
||||||
int32_t group_index;
|
int32_t group_index;
|
||||||
int32_t elements;
|
int32_t elements;
|
||||||
int32_t deformerdata_size;
|
int32_t deformerdata_size;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct DeformerElement_MDL7
|
/** \struct DeformerElement_MDL7
|
||||||
* \brief Deformer element in a MDL7 file
|
* \brief Deformer element in a MDL7 file
|
||||||
*/
|
*/
|
||||||
struct DeformerElement_MDL7
|
struct DeformerElement_MDL7 {
|
||||||
{
|
|
||||||
//! bei deformer_typ==0 (==bones) element_index == bone index
|
//! bei deformer_typ==0 (==bones) element_index == bone index
|
||||||
int32_t element_index;
|
int32_t element_index;
|
||||||
char element_name[AI_MDL7_MAX_BONENAMESIZE];
|
char element_name[AI_MDL7_MAX_BONENAMESIZE];
|
||||||
int32_t weights;
|
int32_t weights;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct DeformerWeight_MDL7
|
/** \struct DeformerWeight_MDL7
|
||||||
* \brief Deformer weight in a MDL7 file
|
* \brief Deformer weight in a MDL7 file
|
||||||
*/
|
*/
|
||||||
struct DeformerWeight_MDL7
|
struct DeformerWeight_MDL7 {
|
||||||
{
|
|
||||||
//! for deformer_typ==0 (==bones) index == vertex index
|
//! for deformer_typ==0 (==bones) index == vertex index
|
||||||
int32_t index;
|
int32_t index;
|
||||||
float weight;
|
float weight;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// don't know why this was in the original headers ...
|
// don't know why this was in the original headers ...
|
||||||
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||||
|
@ -353,17 +343,15 @@ typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||||
/** \struct ColorValue_MDL7
|
/** \struct ColorValue_MDL7
|
||||||
* \brief Data structure for a color value in a MDL7 file
|
* \brief Data structure for a color value in a MDL7 file
|
||||||
*/
|
*/
|
||||||
struct ColorValue_MDL7
|
struct ColorValue_MDL7 {
|
||||||
{
|
|
||||||
float r,g,b,a;
|
float r,g,b,a;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Material_MDL7
|
/** \struct Material_MDL7
|
||||||
* \brief Data structure for a Material in a MDL7 file
|
* \brief Data structure for a Material in a MDL7 file
|
||||||
*/
|
*/
|
||||||
struct Material_MDL7
|
struct Material_MDL7 {
|
||||||
{
|
|
||||||
//! Diffuse base color of the material
|
//! Diffuse base color of the material
|
||||||
ColorValue_MDL7 Diffuse;
|
ColorValue_MDL7 Diffuse;
|
||||||
|
|
||||||
|
@ -378,15 +366,13 @@ struct Material_MDL7
|
||||||
|
|
||||||
//! Phong power
|
//! Phong power
|
||||||
float Power;
|
float Power;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Skin
|
/** \struct Skin
|
||||||
* \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
|
* \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
|
||||||
*/
|
*/
|
||||||
struct Skin
|
struct Skin {
|
||||||
{
|
|
||||||
//! 0 = single (Skin), 1 = group (GroupSkin)
|
//! 0 = single (Skin), 1 = group (GroupSkin)
|
||||||
//! For MDL3-5: Defines the type of the skin and there
|
//! For MDL3-5: Defines the type of the skin and there
|
||||||
//! fore the size of the data to skip:
|
//! fore the size of the data to skip:
|
||||||
|
@ -402,7 +388,7 @@ struct Skin
|
||||||
|
|
||||||
//! Texture data
|
//! Texture data
|
||||||
uint8_t *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
|
* \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
|
||||||
* \see Skin
|
* \see Skin
|
||||||
*/
|
*/
|
||||||
struct Skin_MDL5
|
struct Skin_MDL5 {
|
||||||
{
|
|
||||||
int32_t size, width, height;
|
int32_t size, width, height;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// maximum length of texture file name
|
// maximum length of texture file name
|
||||||
#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
|
#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
|
||||||
|
@ -425,44 +410,40 @@ struct Skin_MDL5
|
||||||
/** \struct Skin_MDL7
|
/** \struct Skin_MDL7
|
||||||
* \brief Skin data structure #3 - used by MDL7 and HMP7
|
* \brief Skin data structure #3 - used by MDL7 and HMP7
|
||||||
*/
|
*/
|
||||||
struct Skin_MDL7
|
struct Skin_MDL7 {
|
||||||
{
|
|
||||||
uint8_t typ;
|
uint8_t typ;
|
||||||
int8_t _unused_[3];
|
int8_t _unused_[3];
|
||||||
int32_t width;
|
int32_t width;
|
||||||
int32_t height;
|
int32_t height;
|
||||||
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct RGB565
|
/** \struct RGB565
|
||||||
* \brief Data structure for a RGB565 pixel in a texture
|
* \brief Data structure for a RGB565 pixel in a texture
|
||||||
*/
|
*/
|
||||||
struct RGB565
|
struct RGB565 {
|
||||||
{
|
|
||||||
uint16_t r : 5;
|
uint16_t r : 5;
|
||||||
uint16_t g : 6;
|
uint16_t g : 6;
|
||||||
uint16_t b : 5;
|
uint16_t b : 5;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct ARGB4
|
/** \struct ARGB4
|
||||||
* \brief Data structure for a ARGB4444 pixel in a texture
|
* \brief Data structure for a ARGB4444 pixel in a texture
|
||||||
*/
|
*/
|
||||||
struct ARGB4
|
struct ARGB4 {
|
||||||
{
|
|
||||||
uint16_t a : 4;
|
uint16_t a : 4;
|
||||||
uint16_t r : 4;
|
uint16_t r : 4;
|
||||||
uint16_t g : 4;
|
uint16_t g : 4;
|
||||||
uint16_t b : 4;
|
uint16_t b : 4;
|
||||||
} PACK_STRUCT;
|
} /*PACK_STRUCT*/;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct GroupSkin
|
/** \struct GroupSkin
|
||||||
* \brief Skin data structure #2 (group of pictures)
|
* \brief Skin data structure #2 (group of pictures)
|
||||||
*/
|
*/
|
||||||
struct GroupSkin
|
struct GroupSkin {
|
||||||
{
|
|
||||||
//! 0 = single (Skin), 1 = group (GroupSkin)
|
//! 0 = single (Skin), 1 = group (GroupSkin)
|
||||||
int32_t group;
|
int32_t group;
|
||||||
|
|
||||||
|
@ -474,14 +455,13 @@ struct GroupSkin
|
||||||
|
|
||||||
//! Data of each image
|
//! Data of each image
|
||||||
uint8_t **data;
|
uint8_t **data;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord
|
/** \struct TexCoord
|
||||||
* \brief Texture coordinate data structure used by the Quake1 MDL format
|
* \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?
|
//! Is the vertex on the noundary between front and back piece?
|
||||||
int32_t onseam;
|
int32_t onseam;
|
||||||
|
|
||||||
|
@ -490,33 +470,31 @@ struct TexCoord
|
||||||
|
|
||||||
//! Texture coordinate in the ty direction
|
//! Texture coordinate in the ty direction
|
||||||
int32_t t;
|
int32_t t;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord_MDL3
|
/** \struct TexCoord_MDL3
|
||||||
* \brief Data structure for an UV coordinate in the 3DGS MDL3 format
|
* \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
|
//! position, horizontally in range 0..skinwidth-1
|
||||||
int16_t u;
|
int16_t u;
|
||||||
|
|
||||||
//! position, vertically in range 0..skinheight-1
|
//! position, vertically in range 0..skinheight-1
|
||||||
int16_t v;
|
int16_t v;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord_MDL7
|
/** \struct TexCoord_MDL7
|
||||||
* \brief Data structure for an UV coordinate in the 3DGS MDL7 format
|
* \brief Data structure for an UV coordinate in the 3DGS MDL7 format
|
||||||
*/
|
*/
|
||||||
struct TexCoord_MDL7
|
struct TexCoord_MDL7 {
|
||||||
{
|
|
||||||
//! position, horizontally in range 0..1
|
//! position, horizontally in range 0..1
|
||||||
float u;
|
float u;
|
||||||
|
|
||||||
//! position, vertically in range 0..1
|
//! position, vertically in range 0..1
|
||||||
float v;
|
float v;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct SkinSet_MDL7
|
/** \struct SkinSet_MDL7
|
||||||
|
@ -532,7 +510,7 @@ struct SkinSet_MDL7
|
||||||
|
|
||||||
//! Material index
|
//! Material index
|
||||||
int32_t material; // size 4
|
int32_t material; // size 4
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle
|
/** \struct Triangle
|
||||||
|
@ -545,7 +523,7 @@ struct Triangle
|
||||||
|
|
||||||
//! Vertex indices
|
//! Vertex indices
|
||||||
int32_t vertex[3];
|
int32_t vertex[3];
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle_MDL3
|
/** \struct Triangle_MDL3
|
||||||
|
@ -558,7 +536,7 @@ struct Triangle_MDL3
|
||||||
|
|
||||||
//! Index of 3 skin vertices in range 0..numskinverts
|
//! Index of 3 skin vertices in range 0..numskinverts
|
||||||
uint16_t index_uv[3];
|
uint16_t index_uv[3];
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle_MDL7
|
/** \struct Triangle_MDL7
|
||||||
|
@ -571,7 +549,7 @@ struct Triangle_MDL7
|
||||||
|
|
||||||
//! Two skinsets. The second will be used for multi-texturing
|
//! Two skinsets. The second will be used for multi-texturing
|
||||||
SkinSet_MDL7 skinsets[2];
|
SkinSet_MDL7 skinsets[2];
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
||||||
# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
|
# 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 v[3];
|
||||||
uint8_t normalIndex;
|
uint8_t normalIndex;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
|
@ -625,8 +603,7 @@ struct Vertex_MDL7
|
||||||
uint8_t norm162index;
|
uint8_t norm162index;
|
||||||
float norm[3];
|
float norm[3];
|
||||||
};
|
};
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct BoneTransform_MDL7
|
/** \struct BoneTransform_MDL7
|
||||||
|
@ -643,12 +620,11 @@ struct BoneTransform_MDL7
|
||||||
//! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
|
//! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
|
||||||
//! THIS STUPID FILE FORMAT!
|
//! THIS STUPID FILE FORMAT!
|
||||||
int8_t _unused_[2];
|
int8_t _unused_[2];
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
#define AI_MDL7_MAX_FRAMENAMESIZE 16
|
#define AI_MDL7_MAX_FRAMENAMESIZE 16
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Frame_MDL7
|
/** \struct Frame_MDL7
|
||||||
* \brief Frame data structure used by MDL7 files
|
* \brief Frame data structure used by MDL7 files
|
||||||
|
@ -678,7 +654,7 @@ struct SimpleFrame
|
||||||
|
|
||||||
//! Vertex list of the frame
|
//! Vertex list of the frame
|
||||||
Vertex *verts;
|
Vertex *verts;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Frame
|
/** \struct Frame
|
||||||
|
@ -691,7 +667,7 @@ struct Frame
|
||||||
|
|
||||||
//! Frame data
|
//! Frame data
|
||||||
SimpleFrame frame;
|
SimpleFrame frame;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
|
@ -708,7 +684,7 @@ struct SimpleFrame_MDLn_SP
|
||||||
|
|
||||||
//! Vertex list of the frame
|
//! Vertex list of the frame
|
||||||
Vertex_MDL4 *verts;
|
Vertex_MDL4 *verts;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct GroupFrame
|
/** \struct GroupFrame
|
||||||
|
@ -730,7 +706,7 @@ struct GroupFrame
|
||||||
|
|
||||||
//! List of single frames
|
//! List of single frames
|
||||||
SimpleFrame *frames;
|
SimpleFrame *frames;
|
||||||
} PACK_STRUCT;
|
} /* PACK_STRUCT */;
|
||||||
|
|
||||||
#include "./../include/assimp/Compiler/poppack1.h"
|
#include "./../include/assimp/Compiler/poppack1.h"
|
||||||
|
|
||||||
|
@ -738,8 +714,7 @@ struct GroupFrame
|
||||||
/** \struct IntFace_MDL7
|
/** \struct IntFace_MDL7
|
||||||
* \brief Internal data structure to temporarily represent a face
|
* \brief Internal data structure to temporarily represent a face
|
||||||
*/
|
*/
|
||||||
struct IntFace_MDL7
|
struct IntFace_MDL7 {
|
||||||
{
|
|
||||||
// provide a constructor for our own convenience
|
// provide a constructor for our own convenience
|
||||||
IntFace_MDL7()
|
IntFace_MDL7()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
#pragma once
|
||||||
|
|
||||||
#ifndef MMD_CPP14_H
|
#ifndef MMD_CPP14_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
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -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 <utility>
|
#include <utility>
|
||||||
#include "MMDPmxParser.h"
|
#include "MMDPmxParser.h"
|
||||||
|
#include "../contrib/utf8cpp/source/utf8.h"
|
||||||
#include "Exceptional.h"
|
#include "Exceptional.h"
|
||||||
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
|
||||||
|
|
||||||
namespace pmx
|
namespace pmx
|
||||||
{
|
{
|
||||||
|
@ -60,15 +100,7 @@ namespace pmx
|
||||||
const unsigned int targetSize = size * 3; // enough to encode
|
const unsigned int targetSize = size * 3; // enough to encode
|
||||||
char* targetStart = new char[targetSize]();
|
char* targetStart = new char[targetSize]();
|
||||||
const char* targetReserved = targetStart;
|
const char* targetReserved = targetStart;
|
||||||
ConversionFlags flags = ConversionFlags::lenientConversion;
|
utf8::utf16to8( sourceStart, sourceStart + size, targetStart );
|
||||||
|
|
||||||
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." );
|
|
||||||
}
|
|
||||||
|
|
||||||
result.assign(targetReserved, targetStart - targetReserved);
|
result.assign(targetReserved, targetStart - targetReserved);
|
||||||
delete[] targetReserved;
|
delete[] targetReserved;
|
||||||
|
|
|
@ -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
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -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
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -64,7 +64,7 @@ ObjFileParser::ObjFileParser()
|
||||||
, m_uiLine( 0 )
|
, m_uiLine( 0 )
|
||||||
, m_pIO( nullptr )
|
, m_pIO( nullptr )
|
||||||
, m_progress( nullptr )
|
, m_progress( nullptr )
|
||||||
, m_originalObjFileName( "" ) {
|
, m_originalObjFileName() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,28 +109,6 @@ ObjFile::Model *ObjFileParser::GetModel() const {
|
||||||
return m_pModel;
|
return m_pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ignoreNewLines(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer)
|
|
||||||
{
|
|
||||||
auto curPosition = buffer.begin();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
while (*curPosition!='\n'&&*curPosition!='\\')
|
|
||||||
{
|
|
||||||
++curPosition;
|
|
||||||
}
|
|
||||||
if (*curPosition=='\\')
|
|
||||||
{
|
|
||||||
std::vector<char> tempBuf;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
streamBuffer.getNextLine(tempBuf);
|
|
||||||
} while (tempBuf[0]=='\n');
|
|
||||||
*curPosition = ' ';
|
|
||||||
std::copy(tempBuf.cbegin(), tempBuf.cend(), ++curPosition);
|
|
||||||
}
|
|
||||||
} while (*curPosition!='\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
||||||
// only update every 100KB or it'll be too slow
|
// only update every 100KB or it'll be too slow
|
||||||
//const unsigned int updateProgressEveryBytes = 100 * 1024;
|
//const unsigned int updateProgressEveryBytes = 100 * 1024;
|
||||||
|
@ -142,7 +120,7 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
||||||
size_t lastFilePos( 0 );
|
size_t lastFilePos( 0 );
|
||||||
|
|
||||||
std::vector<char> buffer;
|
std::vector<char> buffer;
|
||||||
while ( streamBuffer.getNextLine( buffer ) ) {
|
while ( streamBuffer.getNextDataLine( buffer, '\\' ) ) {
|
||||||
m_DataIt = buffer.begin();
|
m_DataIt = buffer.begin();
|
||||||
m_DataItEnd = buffer.end();
|
m_DataItEnd = buffer.end();
|
||||||
|
|
||||||
|
@ -154,14 +132,14 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
||||||
progressCounter++;
|
progressCounter++;
|
||||||
m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
|
m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
|
||||||
}
|
}
|
||||||
//ignoreNewLines(streamBuffer, buffer);
|
|
||||||
// parse line
|
// parse line
|
||||||
switch (*m_DataIt) {
|
switch (*m_DataIt) {
|
||||||
case 'v': // Parse a vertex texture coordinate
|
case 'v': // Parse a vertex texture coordinate
|
||||||
{
|
{
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (*m_DataIt == ' ' || *m_DataIt == '\t') {
|
if (*m_DataIt == ' ' || *m_DataIt == '\t') {
|
||||||
size_t numComponents = getNumComponentsInLine();
|
size_t numComponents = getNumComponentsInDataDefinition();
|
||||||
if (numComponents == 3) {
|
if (numComponents == 3) {
|
||||||
// read in vertex definition
|
// read in vertex definition
|
||||||
getVector3(m_pModel->m_Vertices);
|
getVector3(m_pModel->m_Vertices);
|
||||||
|
@ -245,7 +223,6 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
pf_skip_line:
|
pf_skip_line:
|
||||||
|
|
||||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -274,21 +251,44 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
|
||||||
pBuffer[index] = '\0';
|
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 );
|
size_t numComponents( 0 );
|
||||||
const char* tmp( &m_DataIt[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 ) ) {
|
if ( !SkipSpaces( &tmp ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
const bool isNum( IsNumeric( *tmp ) );
|
||||||
SkipToken( tmp );
|
SkipToken( tmp );
|
||||||
++numComponents;
|
if ( isNum ) {
|
||||||
|
++numComponents;
|
||||||
|
}
|
||||||
|
if ( !SkipSpaces( &tmp ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return numComponents;
|
return numComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
||||||
size_t numComponents = getNumComponentsInLine();
|
size_t numComponents = getNumComponentsInDataDefinition();
|
||||||
ai_real x, y, z;
|
ai_real x, y, z;
|
||||||
if( 2 == numComponents ) {
|
if( 2 == numComponents ) {
|
||||||
copyNextWord( m_buffer, Buffersize );
|
copyNextWord( m_buffer, Buffersize );
|
||||||
|
@ -397,10 +397,6 @@ static const std::string DefaultObjName = "defaultobject";
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get values for a new face instance
|
// Get values for a new face instance
|
||||||
void ObjFileParser::getFace( aiPrimitiveType type ) {
|
void ObjFileParser::getFace( aiPrimitiveType type ) {
|
||||||
//copyNextLine(m_buffer, Buffersize);
|
|
||||||
//char *pPtr = m_DataIt;
|
|
||||||
//char *pPtr = m_buffer;
|
|
||||||
//char *pEnd = &pPtr[Buffersize];
|
|
||||||
m_DataIt = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
|
m_DataIt = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
|
||||||
if ( m_DataIt == m_DataItEnd || *m_DataIt == '\0' ) {
|
if ( m_DataIt == m_DataItEnd || *m_DataIt == '\0' ) {
|
||||||
return;
|
return;
|
||||||
|
@ -571,14 +567,7 @@ void ObjFileParser::getMaterialDesc() {
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get a comment, values will be skipped
|
// Get a comment, values will be skipped
|
||||||
void ObjFileParser::getComment() {
|
void ObjFileParser::getComment() {
|
||||||
while (m_DataIt != m_DataItEnd) {
|
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||||
if ( '\n' == (*m_DataIt)) {
|
|
||||||
++m_DataIt;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
++m_DataIt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -91,6 +91,8 @@ protected:
|
||||||
void copyNextWord(char *pBuffer, size_t length);
|
void copyNextWord(char *pBuffer, size_t length);
|
||||||
/// Method to copy the new line.
|
/// Method to copy the new line.
|
||||||
// void copyNextLine(char *pBuffer, size_t length);
|
// void copyNextLine(char *pBuffer, size_t length);
|
||||||
|
/// Get the number of components in a line.
|
||||||
|
size_t getNumComponentsInDataDefinition();
|
||||||
/// Stores the vector
|
/// Stores the vector
|
||||||
void getVector( std::vector<aiVector3D> &point3d_array );
|
void getVector( std::vector<aiVector3D> &point3d_array );
|
||||||
/// Stores the following 3d vector.
|
/// Stores the following 3d vector.
|
||||||
|
@ -129,8 +131,6 @@ protected:
|
||||||
bool needsNewMesh( const std::string &rMaterialName );
|
bool needsNewMesh( const std::string &rMaterialName );
|
||||||
/// Error report in token
|
/// Error report in token
|
||||||
void reportErrorTokenInFace();
|
void reportErrorTokenInFace();
|
||||||
/// Get the number of components in a line.
|
|
||||||
size_t getNumComponentsInLine();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Copy and assignment constructor should be private
|
// Copy and assignment constructor should be private
|
||||||
|
@ -154,9 +154,8 @@ private:
|
||||||
IOSystem *m_pIO;
|
IOSystem *m_pIO;
|
||||||
//! Pointer to progress handler
|
//! Pointer to progress handler
|
||||||
ProgressHandler* m_progress;
|
ProgressHandler* m_progress;
|
||||||
/// Path to the current model
|
/// Path to the current model, name of the obj file where the buffer comes from
|
||||||
// name of the obj file where the buffer comes from
|
const std::string m_originalObjFileName;
|
||||||
const std::string& m_originalObjFileName;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
|
@ -116,14 +116,16 @@ inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
|
||||||
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
|
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
if ( it != end )
|
|
||||||
{
|
if ( it != end ) {
|
||||||
++it;
|
++it;
|
||||||
++uiLine;
|
++uiLine;
|
||||||
}
|
}
|
||||||
// fix .. from time to time there are spaces at the beginning of a material line
|
// 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;
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "OptimizeGraph.h"
|
#include "OptimizeGraph.h"
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "Exceptional.h"
|
#include "Exceptional.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "OptimizeMeshes.h"
|
#include "OptimizeMeshes.h"
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "Exceptional.h"
|
#include "Exceptional.h"
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -51,14 +51,12 @@ struct aiScene;
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/** Helper class to export a given scene to a Stanford Ply file. */
|
/** Helper class to export a given scene to a Stanford Ply file. */
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
class PlyExporter
|
class PlyExporter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/// The class constructor for a specific scene to export
|
/// The class constructor for a specific scene to export
|
||||||
PlyExporter(const char* filename, const aiScene* pScene, bool binary = false);
|
PlyExporter(const char* filename, const aiScene* pScene, bool binary = false);
|
||||||
|
|
1826
code/PlyLoader.cpp
1826
code/PlyLoader.cpp
File diff suppressed because it is too large
Load Diff
|
@ -68,7 +68,6 @@ public:
|
||||||
PLYImporter();
|
PLYImporter();
|
||||||
~PLYImporter();
|
~PLYImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -78,6 +77,16 @@ public:
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
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:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -94,53 +103,10 @@ protected:
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Extract vertices from the DOM
|
|
||||||
*/
|
|
||||||
void LoadVertices(std::vector<aiVector3D>* pvOut,
|
|
||||||
bool p_bNormals = false);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Extract vertex color channels from the DOM
|
|
||||||
*/
|
|
||||||
void LoadVertexColor(std::vector<aiColor4D>* pvOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Extract texture coordinate channels from the DOM
|
|
||||||
*/
|
|
||||||
void LoadTextureCoordinates(std::vector<aiVector2D>* pvOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Extract a face list from the DOM
|
|
||||||
*/
|
|
||||||
void LoadFaces(std::vector<PLY::Face>* pvOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Extract a material list from the DOM
|
/** Extract a material list from the DOM
|
||||||
*/
|
*/
|
||||||
void LoadMaterial(std::vector<aiMaterial*>* pvOut);
|
void LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Validate material indices, replace default material identifiers
|
|
||||||
*/
|
|
||||||
void ReplaceDefaultMaterial(std::vector<PLY::Face>* avFaces,
|
|
||||||
std::vector<aiMaterial*>* avMaterials);
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Convert all meshes into our ourer representation
|
|
||||||
*/
|
|
||||||
void ConvertMeshes(std::vector<PLY::Face>* avFaces,
|
|
||||||
const std::vector<aiVector3D>* avPositions,
|
|
||||||
const std::vector<aiVector3D>* avNormals,
|
|
||||||
const std::vector<aiColor4D>* avColors,
|
|
||||||
const std::vector<aiVector2D>* avTexCoords,
|
|
||||||
const std::vector<aiMaterial*>* avMaterials,
|
|
||||||
std::vector<aiMesh*>* avOut);
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Static helper to parse a color from four single channels in
|
/** Static helper to parse a color from four single channels in
|
||||||
|
@ -151,7 +117,6 @@ protected:
|
||||||
PLY::EDataType aiTypes[4],
|
PLY::EDataType aiTypes[4],
|
||||||
aiColor4D* clrOut);
|
aiColor4D* clrOut);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Static helper to parse a color channel value. The input value
|
/** Static helper to parse a color channel value. The input value
|
||||||
* is normalized to 0-1.
|
* is normalized to 0-1.
|
||||||
|
@ -160,12 +125,14 @@ protected:
|
||||||
PLY::PropertyInstance::ValueUnion val,
|
PLY::PropertyInstance::ValueUnion val,
|
||||||
PLY::EDataType eType);
|
PLY::EDataType eType);
|
||||||
|
|
||||||
|
|
||||||
/** Buffer to hold the loaded file */
|
/** Buffer to hold the loaded file */
|
||||||
unsigned char* mBuffer;
|
unsigned char* mBuffer;
|
||||||
|
|
||||||
/** Document object model representation extracted from the file */
|
/** Document object model representation extracted from the file */
|
||||||
PLY::DOM* pcDOM;
|
PLY::DOM* pcDOM;
|
||||||
|
|
||||||
|
/** Mesh generated by loader */
|
||||||
|
aiMesh* mGeneratedMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
1792
code/PlyParser.cpp
1792
code/PlyParser.cpp
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,6 @@ Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2017, assimp team
|
Copyright (c) 2006-2017, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,19 +45,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
|
#include "IOStreamBuffer.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//pre-declaration
|
||||||
|
class PLYImporter;
|
||||||
|
|
||||||
// http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/
|
// http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/
|
||||||
// http://w3.impa.br/~lvelho/outgoing/sossai/old/ViHAP_D4.4.2_PLY_format_v1.1.pdf
|
// http://w3.impa.br/~lvelho/outgoing/sossai/old/ViHAP_D4.4.2_PLY_format_v1.1.pdf
|
||||||
// http://www.okino.com/conv/exp_ply.htm
|
// http://www.okino.com/conv/exp_ply.htm
|
||||||
namespace PLY
|
namespace PLY
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
/*
|
/*
|
||||||
name type number of bytes
|
name type number of bytes
|
||||||
|
@ -197,6 +198,9 @@ enum EElementSemantic
|
||||||
//! The element is a material description
|
//! The element is a material description
|
||||||
EEST_Material,
|
EEST_Material,
|
||||||
|
|
||||||
|
//! texture path
|
||||||
|
EEST_TextureFile,
|
||||||
|
|
||||||
//! Marks invalid entries
|
//! Marks invalid entries
|
||||||
EEST_INVALID
|
EEST_INVALID
|
||||||
};
|
};
|
||||||
|
@ -238,16 +242,15 @@ public:
|
||||||
//! string is either '\n', '\r' or '\0'. Return value is false
|
//! string is either '\n', '\r' or '\0'. Return value is false
|
||||||
//! if the input string is NOT a valid property (E.g. does
|
//! if the input string is NOT a valid property (E.g. does
|
||||||
//! not start with the "property" keyword)
|
//! not start with the "property" keyword)
|
||||||
static bool ParseProperty (const char* pCur, const char** pCurOut,
|
static bool ParseProperty(std::vector<char> &buffer, Property* pOut);
|
||||||
Property* pOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a data type from a string
|
//! Parse a data type from a string
|
||||||
static EDataType ParseDataType(const char* pCur,const char** pCurOut);
|
static EDataType ParseDataType(std::vector<char> &buffer);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a semantic from a string
|
//! Parse a semantic from a string
|
||||||
static ESemantic ParseSemantic(const char* pCur,const char** pCurOut);
|
static ESemantic ParseSemantic(std::vector<char> &buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
@ -285,13 +288,11 @@ public:
|
||||||
//! Parse an element from a string.
|
//! Parse an element from a string.
|
||||||
//! The function will parse all properties contained in the
|
//! The function will parse all properties contained in the
|
||||||
//! element, too.
|
//! element, too.
|
||||||
static bool ParseElement (const char* pCur, const char** pCurOut,
|
static bool ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, Element* pOut);
|
||||||
Element* pOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a semantic from a string
|
//! Parse a semantic from a string
|
||||||
static EElementSemantic ParseSemantic(const char* pCur,
|
static EElementSemantic ParseSemantic(std::vector<char> &buffer);
|
||||||
const char** pCurOut);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
@ -331,13 +332,13 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a property instance
|
//! Parse a property instance
|
||||||
static bool ParseInstance (const char* pCur,const char** pCurOut,
|
static bool ParseInstance(const char* &pCur,
|
||||||
const Property* prop, PropertyInstance* p_pcOut);
|
const Property* prop, PropertyInstance* p_pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a property instance in binary format
|
//! Parse a property instance in binary format
|
||||||
static bool ParseInstanceBinary (const char* pCur,const char** pCurOut,
|
static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||||
const Property* prop, PropertyInstance* p_pcOut,bool p_bBE);
|
const char* &pCur, unsigned int &bufferSize, const Property* prop, PropertyInstance* p_pcOut, bool p_bBE);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Get the default value for a given data type
|
//! Get the default value for a given data type
|
||||||
|
@ -345,13 +346,12 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a value
|
//! Parse a value
|
||||||
static bool ParseValue(const char* pCur,const char** pCurOut,
|
static bool ParseValue(const char* &pCur, EDataType eType, ValueUnion* out);
|
||||||
EDataType eType,ValueUnion* out);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a binary value
|
//! Parse a binary value
|
||||||
static bool ParseValueBinary(const char* pCur,const char** pCurOut,
|
static bool ParseValueBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||||
EDataType eType,ValueUnion* out,bool p_bBE);
|
const char* &pCur, unsigned int &bufferSize, EDataType eType, ValueUnion* out, bool p_bBE);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Convert a property value to a given type TYPE
|
//! Convert a property value to a given type TYPE
|
||||||
|
@ -375,13 +375,13 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse an element instance
|
//! Parse an element instance
|
||||||
static bool ParseInstance (const char* pCur,const char** pCurOut,
|
static bool ParseInstance(const char* &pCur,
|
||||||
const Element* pcElement, ElementInstance* p_pcOut);
|
const Element* pcElement, ElementInstance* p_pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a binary element instance
|
//! Parse a binary element instance
|
||||||
static bool ParseInstanceBinary (const char* pCur,const char** pCurOut,
|
static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||||
const Element* pcElement, ElementInstance* p_pcOut,bool p_bBE);
|
const char* &pCur, unsigned int &bufferSize, const Element* pcElement, ElementInstance* p_pcOut, bool p_bBE);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
@ -400,13 +400,13 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse an element instance list
|
//! Parse an element instance list
|
||||||
static bool ParseInstanceList (const char* pCur,const char** pCurOut,
|
static bool ParseInstanceList(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||||
const Element* pcElement, ElementInstanceList* p_pcOut);
|
const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a binary element instance list
|
//! Parse a binary element instance list
|
||||||
static bool ParseInstanceListBinary (const char* pCur,const char** pCurOut,
|
static bool ParseInstanceListBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||||
const Element* pcElement, ElementInstanceList* p_pcOut,bool p_bBE);
|
const char* &pCur, unsigned int &bufferSize, const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader, bool p_bBE);
|
||||||
};
|
};
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
/** \brief Class to represent the document object model of an ASCII or binary
|
/** \brief Class to represent the document object model of an ASCII or binary
|
||||||
|
@ -428,50 +428,33 @@ public:
|
||||||
|
|
||||||
//! Parse the DOM for a PLY file. The input string is assumed
|
//! Parse the DOM for a PLY file. The input string is assumed
|
||||||
//! to be terminated with zero
|
//! to be terminated with zero
|
||||||
static bool ParseInstance (const char* pCur,DOM* p_pcOut);
|
static bool ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader);
|
||||||
static bool ParseInstanceBinary (const char* pCur,
|
static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader, bool p_bBE);
|
||||||
DOM* p_pcOut,bool p_bBE);
|
|
||||||
|
|
||||||
//! Skip all comment lines after this
|
//! Skip all comment lines after this
|
||||||
static bool SkipComments (const char* pCur,const char** pCurOut);
|
static bool SkipComments(std::vector<char> &buffer);
|
||||||
|
|
||||||
|
static bool SkipSpaces(std::vector<char> &buffer);
|
||||||
|
|
||||||
|
static bool SkipLine(std::vector<char> &buffer);
|
||||||
|
|
||||||
|
static bool TokenMatch(std::vector<char> &buffer, const char* token, unsigned int len);
|
||||||
|
|
||||||
|
static bool SkipSpacesAndLineEnd(std::vector<char> &buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Handle the file header and read all element descriptions
|
//! Handle the file header and read all element descriptions
|
||||||
bool ParseHeader (const char* pCur,const char** pCurOut, bool p_bBE);
|
bool ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, bool p_bBE);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Read in all element instance lists
|
//! Read in all element instance lists
|
||||||
bool ParseElementInstanceLists (const char* pCur,const char** pCurOut);
|
bool ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, PLYImporter* loader);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Read in all element instance lists for a binary file format
|
//! Read in all element instance lists for a binary file format
|
||||||
bool ParseElementInstanceListsBinary (const char* pCur,
|
bool ParseElementInstanceListsBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, const char* &pCur, unsigned int &bufferSize, PLYImporter* loader, bool p_bBE);
|
||||||
const char** pCurOut,bool p_bBE);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
/** \brief Helper class to represent a loaded PLY face
|
|
||||||
*/
|
|
||||||
class Face
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
Face()
|
|
||||||
: iMaterialIndex(0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
// set all indices to zero by default
|
|
||||||
mIndices.resize(3,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! List of vertex indices
|
|
||||||
std::vector<unsigned int> mIndices;
|
|
||||||
|
|
||||||
//! Material index
|
|
||||||
unsigned int iMaterialIndex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
|
@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "PretransformVertices.h"
|
#include "PretransformVertices.h"
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "Exceptional.h"
|
#include "Exceptional.h"
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -58,7 +58,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ByteSwapper.h"
|
#include "ByteSwapper.h"
|
||||||
#include "StreamReader.h"
|
#include "StreamReader.h"
|
||||||
#include "TinyFormatter.h"
|
#include "TinyFormatter.h"
|
||||||
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
//#include "../contrib/ConvertUTF/ConvertUTF.h"
|
||||||
|
#include "../contrib/utf8cpp/source/utf8.h"
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
@ -177,21 +178,33 @@ static void UnknownChunk(StreamReaderLE* stream, const SIBChunk& chunk)
|
||||||
// Reads a UTF-16LE string and returns it at UTF-8.
|
// Reads a UTF-16LE string and returns it at UTF-8.
|
||||||
static aiString ReadString(StreamReaderLE* stream, uint32_t numWChars)
|
static aiString ReadString(StreamReaderLE* stream, uint32_t numWChars)
|
||||||
{
|
{
|
||||||
|
if ( 0 == numWChars ) {
|
||||||
|
static const aiString empty;
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
// Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8)
|
// Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8)
|
||||||
UTF16* temp = new UTF16[numWChars];
|
//UTF16* temp = new UTF16[numWChars];
|
||||||
UTF8* str = new UTF8[numWChars * 4 + 1];
|
std::vector<unsigned char> str;
|
||||||
|
str.reserve(numWChars * 4 + 1);
|
||||||
|
//unsigned char* str = new unsigned char[numWChars * 4 + 1];
|
||||||
|
uint16_t *temp = new uint16_t[numWChars];
|
||||||
for (uint32_t n=0;n<numWChars;n++)
|
for (uint32_t n=0;n<numWChars;n++)
|
||||||
temp[n] = stream->GetU2();
|
temp[n] = stream->GetU2();
|
||||||
|
|
||||||
// Convert it and NUL-terminate.
|
// Convert it and NUL-terminate.
|
||||||
const UTF16 *start = temp, *end = temp + numWChars;
|
//const UTF16 *start = temp, *end = temp + numWChars;
|
||||||
UTF8 *dest = str, *limit = str + numWChars*4;
|
|
||||||
ConvertUTF16toUTF8(&start, end, &dest, limit, lenientConversion);
|
|
||||||
*dest = '\0';
|
|
||||||
|
|
||||||
|
const uint16_t *start = temp, *end = temp + numWChars;
|
||||||
|
utf8::utf16to8(start, end, back_inserter(str));
|
||||||
|
|
||||||
|
//UTF8 *dest = str, *limit = str + numWChars*4;
|
||||||
|
//ConvertUTF16toUTF8(&start, end, &dest, limit, lenientConversion);
|
||||||
|
//*dest = '\0';
|
||||||
|
|
||||||
|
str[str.size()-1] = '\0';
|
||||||
// Return the final string.
|
// Return the final string.
|
||||||
aiString result = aiString((const char *)str);
|
aiString result = aiString((const char *)&str[0]);
|
||||||
delete[] str;
|
//delete[] str;
|
||||||
delete[] temp;
|
delete[] temp;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,18 +40,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file STEPFileEncoding.cpp
|
/** @file STEPFileEncoding.cpp
|
||||||
* @brief STEP character handling, string unescaping
|
* @brief STEP character handling, string un-escaping
|
||||||
*/
|
*/
|
||||||
#include "STEPFileEncoding.h"
|
#include "STEPFileEncoding.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
|
#include <contrib/utf8cpp/source/utf8.h>
|
||||||
|
|
||||||
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// roman1 to utf16 table
|
// roman1 to utf16 table
|
||||||
static const UTF16 mac_codetable[] = {
|
static const uint16_t mac_codetable[] = {
|
||||||
// 0x20 unassig./nonprint. slots
|
// 0x20 unassig./nonprint. slots
|
||||||
0x0020 ,
|
0x0020 ,
|
||||||
0x0021 ,
|
0x0021 ,
|
||||||
|
@ -309,14 +309,12 @@ bool STEP::StringToUTF8(std::string& s)
|
||||||
|
|
||||||
ai_assert(sizeof(mac_codetable) / sizeof(mac_codetable[0]) == 0x100-0x20);
|
ai_assert(sizeof(mac_codetable) / sizeof(mac_codetable[0]) == 0x100-0x20);
|
||||||
|
|
||||||
const UTF32 unival = mac_codetable[macval - 0x20], *univalp = &unival;
|
const uint32_t unival = mac_codetable[macval - 0x20], *univalp = &unival;
|
||||||
|
|
||||||
UTF8 temp[5], *tempp = temp;
|
unsigned char temp[5], *tempp = temp;
|
||||||
ai_assert(sizeof(UTF8) == 1);
|
ai_assert(sizeof( unsigned char ) == 1);
|
||||||
|
|
||||||
if(ConvertUTF32toUTF8(&univalp, univalp+1, &tempp, tempp+sizeof(temp), lenientConversion) != conversionOK) {
|
utf8::utf32to8( univalp, univalp + 1, tempp );
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t outcount = static_cast<size_t>(tempp-temp);
|
const size_t outcount = static_cast<size_t>(tempp-temp);
|
||||||
|
|
||||||
|
@ -355,28 +353,26 @@ bool STEP::StringToUTF8(std::string& s)
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t count = (j-basei)/4;
|
const size_t count = (j-basei)/4;
|
||||||
std::unique_ptr<UTF16[]> src(new UTF16[count]);
|
std::unique_ptr<uint16_t[]> src(new uint16_t[count]);
|
||||||
|
|
||||||
const char* cur = s.c_str() + basei;
|
const char* cur = s.c_str() + basei;
|
||||||
for (size_t k = 0; k < count; ++k, cur += 4) {
|
for (size_t k = 0; k < count; ++k, cur += 4) {
|
||||||
src[k] = (static_cast<UTF16>(HexOctetToDecimal(cur)) << 8u) |
|
src[k] = (static_cast<uint16_t>(HexOctetToDecimal(cur)) << 8u) |
|
||||||
static_cast<UTF16>(HexOctetToDecimal(cur+2));
|
static_cast<uint16_t>(HexOctetToDecimal(cur+2));
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t dcount = count * 3; // this is enough to hold all possible outputs
|
const size_t dcount = count * 3; // this is enough to hold all possible outputs
|
||||||
std::unique_ptr<UTF8[]> dest(new UTF8[dcount]);
|
std::unique_ptr<unsigned char[]> dest(new unsigned char[dcount]);
|
||||||
|
|
||||||
const UTF16* srct = src.get();
|
const uint16_t* srct = src.get();
|
||||||
UTF8* destt = dest.get();
|
unsigned char* destt = dest.get();
|
||||||
if(ConvertUTF16toUTF8(&srct, srct+count, &destt, destt+dcount, lenientConversion) != conversionOK) {
|
utf8::utf16to8( srct, srct + count, destt );
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t outcount = static_cast<size_t>(destt-dest.get());
|
const size_t outcount = static_cast<size_t>(destt-dest.get());
|
||||||
|
|
||||||
s.erase(i,(j+4-i));
|
s.erase(i,(j+4-i));
|
||||||
|
|
||||||
ai_assert(sizeof(UTF8) == 1);
|
ai_assert(sizeof(unsigned char) == 1);
|
||||||
s.insert(i, reinterpret_cast<char*>(dest.get()), outcount);
|
s.insert(i, reinterpret_cast<char*>(dest.get()), outcount);
|
||||||
|
|
||||||
i += outcount;
|
i += outcount;
|
||||||
|
@ -388,37 +384,34 @@ bool STEP::StringToUTF8(std::string& s)
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t count = (j-basei)/8;
|
const size_t count = (j-basei)/8;
|
||||||
std::unique_ptr<UTF32[]> src(new UTF32[count]);
|
std::unique_ptr<uint32_t[]> src(new uint32_t[count]);
|
||||||
|
|
||||||
const char* cur = s.c_str() + basei;
|
const char* cur = s.c_str() + basei;
|
||||||
for (size_t k = 0; k < count; ++k, cur += 8) {
|
for (size_t k = 0; k < count; ++k, cur += 8) {
|
||||||
src[k] = (static_cast<UTF32>(HexOctetToDecimal(cur )) << 24u) |
|
src[k] = (static_cast<uint32_t>(HexOctetToDecimal(cur )) << 24u) |
|
||||||
(static_cast<UTF32>(HexOctetToDecimal(cur+2)) << 16u) |
|
(static_cast<uint32_t>(HexOctetToDecimal(cur+2)) << 16u) |
|
||||||
(static_cast<UTF32>(HexOctetToDecimal(cur+4)) << 8u) |
|
(static_cast<uint32_t>(HexOctetToDecimal(cur+4)) << 8u) |
|
||||||
(static_cast<UTF32>(HexOctetToDecimal(cur+6)));
|
(static_cast<uint32_t>(HexOctetToDecimal(cur+6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t dcount = count * 5; // this is enough to hold all possible outputs
|
const size_t dcount = count * 5; // this is enough to hold all possible outputs
|
||||||
std::unique_ptr<UTF8[]> dest(new UTF8[dcount]);
|
std::unique_ptr<unsigned char[]> dest(new unsigned char[dcount]);
|
||||||
|
|
||||||
const UTF32* srct = src.get();
|
const uint32_t* srct = src.get();
|
||||||
UTF8* destt = dest.get();
|
unsigned char* destt = dest.get();
|
||||||
if(ConvertUTF32toUTF8(&srct, srct+count, &destt, destt+dcount, lenientConversion) != conversionOK) {
|
utf8::utf32to8( srct, srct + count, destt );
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t outcount = static_cast<size_t>(destt-dest.get());
|
const size_t outcount = static_cast<size_t>(destt-dest.get());
|
||||||
|
|
||||||
s.erase(i,(j+4-i));
|
s.erase(i,(j+4-i));
|
||||||
|
|
||||||
ai_assert(sizeof(UTF8) == 1);
|
ai_assert(sizeof(unsigned char) == 1);
|
||||||
s.insert(i, reinterpret_cast<char*>(dest.get()), outcount);
|
s.insert(i, reinterpret_cast<char*>(dest.get()), outcount);
|
||||||
|
|
||||||
i += outcount;
|
i += outcount;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// TODO: other encoding patterns?
|
// TODO: other encoding patterns?
|
||||||
|
|
|
@ -211,20 +211,20 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
|
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
|
||||||
pScene->mRootNode->mMeshes[i] = i;
|
pScene->mRootNode->mMeshes[i] = i;
|
||||||
|
|
||||||
// create a single default material, using a light gray diffuse color for consistency with
|
// create a single default material, using a white diffuse color for consistency with
|
||||||
// other geometric types (e.g., PLY).
|
// other geometric types (e.g., PLY).
|
||||||
aiMaterial* pcMat = new aiMaterial();
|
aiMaterial* pcMat = new aiMaterial();
|
||||||
aiString s;
|
aiString s;
|
||||||
s.Set(AI_DEFAULT_MATERIAL_NAME);
|
s.Set(AI_DEFAULT_MATERIAL_NAME);
|
||||||
pcMat->AddProperty(&s, AI_MATKEY_NAME);
|
pcMat->AddProperty(&s, AI_MATKEY_NAME);
|
||||||
|
|
||||||
aiColor4D clrDiffuse(ai_real(0.6),ai_real(0.6),ai_real(0.6),ai_real(1.0));
|
aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0));
|
||||||
if (bMatClr) {
|
if (bMatClr) {
|
||||||
clrDiffuse = clrColorDefault;
|
clrDiffuse = clrColorDefault;
|
||||||
}
|
}
|
||||||
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
|
||||||
clrDiffuse = aiColor4D( ai_real( 0.05), ai_real( 0.05), ai_real( 0.05), ai_real( 1.0));
|
clrDiffuse = aiColor4D( ai_real(1.0), ai_real(1.0), ai_real(1.0), ai_real(1.0));
|
||||||
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
pScene->mNumMaterials = 1;
|
pScene->mNumMaterials = 1;
|
||||||
|
|
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* OptimizeGraph step.
|
* OptimizeGraph step.
|
||||||
*/
|
*/
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "Hash.h"
|
#include "Hash.h"
|
||||||
|
|
|
@ -126,9 +126,8 @@ void SpatialSort::FindPositions( const aiVector3D& pPosition,
|
||||||
const ai_real dist = pPosition * mPlaneNormal;
|
const ai_real dist = pPosition * mPlaneNormal;
|
||||||
const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
|
const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
|
||||||
|
|
||||||
// clear the array in this strange fashion because a simple clear() would also deallocate
|
// clear the array
|
||||||
// the array which we want to avoid
|
poResults.clear();
|
||||||
poResults.erase( poResults.begin(), poResults.end());
|
|
||||||
|
|
||||||
// quick check for positions outside the range
|
// quick check for positions outside the range
|
||||||
if( mPositions.size() == 0)
|
if( mPositions.size() == 0)
|
||||||
|
|
|
@ -43,12 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
|
||||||
|
|
||||||
#include "StepExporter.h"
|
#include "StepExporter.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "ConvertToLHProcess.h"
|
||||||
#include "Bitmap.h"
|
#include "Bitmap.h"
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
|
@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Subdivision.h"
|
#include "Subdivision.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include "SpatialSort.h"
|
#include "SpatialSort.h"
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
#include "Vertex.h"
|
#include "Vertex.h"
|
||||||
|
|
|
@ -43,12 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
|
||||||
|
|
||||||
#include "XFileExporter.h"
|
#include "XFileExporter.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "ConvertToLHProcess.h"
|
||||||
#include "Bitmap.h"
|
#include "Bitmap.h"
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "SceneCombiner.h"
|
#include <assimp/SceneCombiner.h>
|
||||||
#include <assimp/DefaultIOSystem.h>
|
#include <assimp/DefaultIOSystem.h>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||||
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
|
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
|
||||||
// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
|
// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
|
||||||
|
@ -22,6 +24,7 @@
|
||||||
#include <assimp/defs.h>
|
#include <assimp/defs.h>
|
||||||
|
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -192,7 +195,7 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int*
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
|
|
||||||
if ( *in < '0' || *in > '9' )
|
if ( *in < '0' || *in > '9' )
|
||||||
throw std::invalid_argument(std::string("The string \"") + in + "\" cannot be converted into a value.");
|
throw std::invalid_argument(std::string("The string \"") + in + "\" cannot be converted into a value.");
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
while ( running )
|
while ( running )
|
||||||
|
@ -202,8 +205,12 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int*
|
||||||
|
|
||||||
const uint64_t new_value = ( value * 10 ) + ( *in - '0' );
|
const uint64_t new_value = ( value * 10 ) + ( *in - '0' );
|
||||||
|
|
||||||
if (new_value < value) /* numeric overflow, we rely on you */
|
// numeric overflow, we rely on you
|
||||||
throw std::overflow_error(std::string("Converting the string \"") + in + "\" into a value resulted in overflow.");
|
if ( new_value < value ) {
|
||||||
|
DefaultLogger::get()->warn( std::string( "Converting the string \"" ) + in + "\" into a value resulted in overflow." );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//throw std::overflow_error();
|
||||||
|
|
||||||
value = new_value;
|
value = new_value;
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ByteSwapper.h"
|
#include "ByteSwapper.h"
|
||||||
|
|
||||||
#include "SplitLargeMeshes.h"
|
#include "SplitLargeMeshes.h"
|
||||||
#include "SceneCombiner.h"
|
|
||||||
|
|
||||||
|
#include <assimp/SceneCombiner.h>
|
||||||
#include <assimp/version.h>
|
#include <assimp/version.h>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
|
@ -185,8 +185,11 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
|
||||||
unsigned int bytesPerComp = ComponentTypeSize(compType);
|
unsigned int bytesPerComp = ComponentTypeSize(compType);
|
||||||
|
|
||||||
size_t offset = buffer->byteLength;
|
size_t offset = buffer->byteLength;
|
||||||
|
// make sure offset is correctly byte-aligned, as required by spec
|
||||||
|
size_t padding = offset % bytesPerComp;
|
||||||
|
offset += padding;
|
||||||
size_t length = count * numCompsOut * bytesPerComp;
|
size_t length = count * numCompsOut * bytesPerComp;
|
||||||
buffer->Grow(length);
|
buffer->Grow(length + padding);
|
||||||
|
|
||||||
// bufferView
|
// bufferView
|
||||||
Ref<BufferView> bv = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));
|
Ref<BufferView> bv = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));
|
||||||
|
|
|
@ -1,539 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2001-2004 Unicode, Inc.
|
|
||||||
*
|
|
||||||
* Disclaimer
|
|
||||||
*
|
|
||||||
* This source code is provided as is by Unicode, Inc. No claims are
|
|
||||||
* made as to fitness for any particular purpose. No warranties of any
|
|
||||||
* kind are expressed or implied. The recipient agrees to determine
|
|
||||||
* applicability of information provided. If this file has been
|
|
||||||
* purchased on magnetic or optical media from Unicode, Inc., the
|
|
||||||
* sole remedy for any claim will be exchange of defective media
|
|
||||||
* within 90 days of receipt.
|
|
||||||
*
|
|
||||||
* Limitations on Rights to Redistribute This Code
|
|
||||||
*
|
|
||||||
* Unicode, Inc. hereby grants the right to freely use the information
|
|
||||||
* supplied in this file in the creation of products supporting the
|
|
||||||
* Unicode Standard, and to make copies of this file in any form
|
|
||||||
* for internal or external distribution as long as this notice
|
|
||||||
* remains attached.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
Conversions between UTF32, UTF-16, and UTF-8. Source code file.
|
|
||||||
Author: Mark E. Davis, 1994.
|
|
||||||
Rev History: Rick McGowan, fixes & updates May 2001.
|
|
||||||
Sept 2001: fixed const & error conditions per
|
|
||||||
mods suggested by S. Parent & A. Lillich.
|
|
||||||
June 2002: Tim Dodd added detection and handling of incomplete
|
|
||||||
source sequences, enhanced error detection, added casts
|
|
||||||
to eliminate compiler warnings.
|
|
||||||
July 2003: slight mods to back out aggressive FFFE detection.
|
|
||||||
Jan 2004: updated switches in from-UTF8 conversions.
|
|
||||||
Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
|
|
||||||
|
|
||||||
See the header file "ConvertUTF.h" for complete documentation.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
|
|
||||||
#include "ConvertUTF.h"
|
|
||||||
#ifdef CVTUTF_DEBUG
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const int halfShift = 10; /* used for shifting by 10 bits */
|
|
||||||
|
|
||||||
static const UTF32 halfBase = 0x0010000UL;
|
|
||||||
static const UTF32 halfMask = 0x3FFUL;
|
|
||||||
|
|
||||||
#define UNI_SUR_HIGH_START (UTF32)0xD800
|
|
||||||
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
|
|
||||||
#define UNI_SUR_LOW_START (UTF32)0xDC00
|
|
||||||
#define UNI_SUR_LOW_END (UTF32)0xDFFF
|
|
||||||
#define false 0
|
|
||||||
#define true 1
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF32toUTF16 (
|
|
||||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
|
||||||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF32* source = *sourceStart;
|
|
||||||
UTF16* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch;
|
|
||||||
if (target >= targetEnd) {
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
ch = *source++;
|
|
||||||
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*target++ = (UTF16)ch; /* normal case */
|
|
||||||
}
|
|
||||||
} else if (ch > UNI_MAX_LEGAL_UTF32) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
result = sourceIllegal;
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* target is a character in range 0xFFFF - 0x10FFFF. */
|
|
||||||
if (target + 1 >= targetEnd) {
|
|
||||||
--source; /* Back up source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
ch -= halfBase;
|
|
||||||
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
|
|
||||||
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF16toUTF32 (
|
|
||||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
|
||||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF16* source = *sourceStart;
|
|
||||||
UTF32* target = *targetStart;
|
|
||||||
UTF32 ch, ch2;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
|
|
||||||
ch = *source++;
|
|
||||||
/* If we have a surrogate pair, convert to UTF32 first. */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
|
|
||||||
/* If the 16 bits following the high surrogate are in the source buffer... */
|
|
||||||
if (source < sourceEnd) {
|
|
||||||
ch2 = *source;
|
|
||||||
/* If it's a low surrogate, convert to UTF32. */
|
|
||||||
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
|
|
||||||
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
|
|
||||||
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
|
|
||||||
++source;
|
|
||||||
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else { /* We don't have the 16 bits following the high surrogate. */
|
|
||||||
--source; /* return to the high surrogate */
|
|
||||||
result = sourceExhausted;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (flags == strictConversion) {
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32 */
|
|
||||||
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target >= targetEnd) {
|
|
||||||
source = oldSource; /* Back up source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
*target++ = ch;
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
#ifdef CVTUTF_DEBUG
|
|
||||||
if (result == sourceIllegal) {
|
|
||||||
fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Index into the table below with the first byte of a UTF-8 sequence to
|
|
||||||
* get the number of trailing bytes that are supposed to follow it.
|
|
||||||
* Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
|
|
||||||
* left as-is for anyone who may want to do such conversion, which was
|
|
||||||
* allowed in earlier algorithms.
|
|
||||||
*/
|
|
||||||
static const char trailingBytesForUTF8[256] = {
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
||||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Magic values subtracted from a buffer value during UTF8 conversion.
|
|
||||||
* This table contains as many values as there might be trailing bytes
|
|
||||||
* in a UTF-8 sequence.
|
|
||||||
*/
|
|
||||||
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
|
||||||
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
|
|
||||||
* into the first byte, depending on how many bytes follow. There are
|
|
||||||
* as many entries in this table as there are UTF-8 sequence types.
|
|
||||||
* (I.e., one byte sequence, two byte... etc.). Remember that sequencs
|
|
||||||
* for *legal* UTF-8 will be 4 or fewer bytes total.
|
|
||||||
*/
|
|
||||||
static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* The interface converts a whole buffer to avoid function-call overhead.
|
|
||||||
* Constants have been gathered. Loops & conditionals have been removed as
|
|
||||||
* much as possible for efficiency, in favor of drop-through switches.
|
|
||||||
* (See "Note A" at the bottom of the file for equivalent code.)
|
|
||||||
* If your compiler supports it, the "isLegalUTF8" call can be turned
|
|
||||||
* into an inline function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF16toUTF8 (
|
|
||||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
|
||||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF16* source = *sourceStart;
|
|
||||||
UTF8* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch;
|
|
||||||
unsigned short bytesToWrite = 0;
|
|
||||||
const UTF32 byteMask = 0xBF;
|
|
||||||
const UTF32 byteMark = 0x80;
|
|
||||||
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
|
|
||||||
ch = *source++;
|
|
||||||
/* If we have a surrogate pair, convert to UTF32 first. */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
|
|
||||||
/* If the 16 bits following the high surrogate are in the source buffer... */
|
|
||||||
if (source < sourceEnd) {
|
|
||||||
UTF32 ch2 = *source;
|
|
||||||
/* If it's a low surrogate, convert to UTF32. */
|
|
||||||
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
|
|
||||||
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
|
|
||||||
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
|
|
||||||
++source;
|
|
||||||
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else { /* We don't have the 16 bits following the high surrogate. */
|
|
||||||
--source; /* return to the high surrogate */
|
|
||||||
result = sourceExhausted;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (flags == strictConversion) {
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32 */
|
|
||||||
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Figure out how many bytes the result will require */
|
|
||||||
if (ch < (UTF32)0x80) { bytesToWrite = 1;
|
|
||||||
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
|
|
||||||
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
|
|
||||||
} else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
|
|
||||||
} else { bytesToWrite = 3;
|
|
||||||
ch = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
target += bytesToWrite;
|
|
||||||
if (target > targetEnd) {
|
|
||||||
source = oldSource; /* Back up source pointer! */
|
|
||||||
target -= bytesToWrite; result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
switch (bytesToWrite) { /* note: everything falls through. */
|
|
||||||
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
|
|
||||||
}
|
|
||||||
target += bytesToWrite;
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
|
|
||||||
* This must be called with the length pre-determined by the first byte.
|
|
||||||
* If not calling this from ConvertUTF8to*, then the length can be set by:
|
|
||||||
* length = trailingBytesForUTF8[*source]+1;
|
|
||||||
* and the sequence is illegal right away if there aren't that many bytes
|
|
||||||
* available.
|
|
||||||
* If presented with a length > 4, this returns false. The Unicode
|
|
||||||
* definition of UTF-8 goes up to 4-byte sequences.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static Boolean isLegalUTF8(const UTF8 *source, int length) {
|
|
||||||
UTF8 a;
|
|
||||||
const UTF8 *srcptr = source+length;
|
|
||||||
switch (length) {
|
|
||||||
default: return false;
|
|
||||||
/* Everything else falls through when "true"... */
|
|
||||||
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
|
|
||||||
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
|
|
||||||
case 2: if ((a = (*--srcptr)) > 0xBF) return false;
|
|
||||||
|
|
||||||
switch (*source) {
|
|
||||||
/* no fall-through in this inner switch */
|
|
||||||
case 0xE0: if (a < 0xA0) return false; break;
|
|
||||||
case 0xED: if (a > 0x9F) return false; break;
|
|
||||||
case 0xF0: if (a < 0x90) return false; break;
|
|
||||||
case 0xF4: if (a > 0x8F) return false; break;
|
|
||||||
default: if (a < 0x80) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
|
|
||||||
}
|
|
||||||
if (*source > 0xF4) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Exported function to return whether a UTF-8 sequence is legal or not.
|
|
||||||
* This is not used here; it's just exported.
|
|
||||||
*/
|
|
||||||
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
|
|
||||||
int length = trailingBytesForUTF8[*source]+1;
|
|
||||||
if (source+length > sourceEnd) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isLegalUTF8(source, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF8toUTF16 (
|
|
||||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
|
||||||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF8* source = *sourceStart;
|
|
||||||
UTF16* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch = 0;
|
|
||||||
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
|
|
||||||
if (source + extraBytesToRead >= sourceEnd) {
|
|
||||||
result = sourceExhausted; break;
|
|
||||||
}
|
|
||||||
/* Do this check whether lenient or strict */
|
|
||||||
if (! isLegalUTF8(source, extraBytesToRead+1)) {
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* The cases all fall through. See "Note A" below.
|
|
||||||
*/
|
|
||||||
switch (extraBytesToRead) {
|
|
||||||
case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
|
|
||||||
case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
|
|
||||||
case 3: ch += *source++; ch <<= 6;
|
|
||||||
case 2: ch += *source++; ch <<= 6;
|
|
||||||
case 1: ch += *source++; ch <<= 6;
|
|
||||||
case 0: ch += *source++;
|
|
||||||
}
|
|
||||||
ch -= offsetsFromUTF8[extraBytesToRead];
|
|
||||||
|
|
||||||
if (target >= targetEnd) {
|
|
||||||
source -= (extraBytesToRead+1); /* Back up source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32 */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
source -= (extraBytesToRead+1); /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*target++ = (UTF16)ch; /* normal case */
|
|
||||||
}
|
|
||||||
} else if (ch > UNI_MAX_UTF16) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
result = sourceIllegal;
|
|
||||||
source -= (extraBytesToRead+1); /* return to the start */
|
|
||||||
break; /* Bail out; shouldn't continue */
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* target is a character in range 0xFFFF - 0x10FFFF. */
|
|
||||||
if (target + 1 >= targetEnd) {
|
|
||||||
source -= (extraBytesToRead+1); /* Back up source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
ch -= halfBase;
|
|
||||||
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
|
|
||||||
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF32toUTF8 (
|
|
||||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
|
||||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF32* source = *sourceStart;
|
|
||||||
UTF8* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch;
|
|
||||||
unsigned short bytesToWrite = 0;
|
|
||||||
const UTF32 byteMask = 0xBF;
|
|
||||||
const UTF32 byteMark = 0x80;
|
|
||||||
ch = *source++;
|
|
||||||
if (flags == strictConversion ) {
|
|
||||||
/* UTF-16 surrogate values are illegal in UTF-32 */
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
--source; /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Figure out how many bytes the result will require. Turn any
|
|
||||||
* illegally large UTF32 things (> Plane 17) into replacement chars.
|
|
||||||
*/
|
|
||||||
if (ch < (UTF32)0x80) { bytesToWrite = 1;
|
|
||||||
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
|
|
||||||
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
|
|
||||||
} else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
|
|
||||||
} else { bytesToWrite = 3;
|
|
||||||
ch = UNI_REPLACEMENT_CHAR;
|
|
||||||
result = sourceIllegal;
|
|
||||||
}
|
|
||||||
|
|
||||||
target += bytesToWrite;
|
|
||||||
if (target > targetEnd) {
|
|
||||||
--source; /* Back up source pointer! */
|
|
||||||
target -= bytesToWrite; result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
switch (bytesToWrite) { /* note: everything falls through. */
|
|
||||||
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
|
|
||||||
case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
|
|
||||||
}
|
|
||||||
target += bytesToWrite;
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF8toUTF32 (
|
|
||||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
|
||||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
|
|
||||||
ConversionResult result = conversionOK;
|
|
||||||
const UTF8* source = *sourceStart;
|
|
||||||
UTF32* target = *targetStart;
|
|
||||||
while (source < sourceEnd) {
|
|
||||||
UTF32 ch = 0;
|
|
||||||
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
|
|
||||||
if (source + extraBytesToRead >= sourceEnd) {
|
|
||||||
result = sourceExhausted; break;
|
|
||||||
}
|
|
||||||
/* Do this check whether lenient or strict */
|
|
||||||
if (! isLegalUTF8(source, extraBytesToRead+1)) {
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* The cases all fall through. See "Note A" below.
|
|
||||||
*/
|
|
||||||
switch (extraBytesToRead) {
|
|
||||||
case 5: ch += *source++; ch <<= 6;
|
|
||||||
case 4: ch += *source++; ch <<= 6;
|
|
||||||
case 3: ch += *source++; ch <<= 6;
|
|
||||||
case 2: ch += *source++; ch <<= 6;
|
|
||||||
case 1: ch += *source++; ch <<= 6;
|
|
||||||
case 0: ch += *source++;
|
|
||||||
}
|
|
||||||
ch -= offsetsFromUTF8[extraBytesToRead];
|
|
||||||
|
|
||||||
if (target >= targetEnd) {
|
|
||||||
source -= (extraBytesToRead+1); /* Back up the source pointer! */
|
|
||||||
result = targetExhausted; break;
|
|
||||||
}
|
|
||||||
if (ch <= UNI_MAX_LEGAL_UTF32) {
|
|
||||||
/*
|
|
||||||
* UTF-16 surrogate values are illegal in UTF-32, and anything
|
|
||||||
* over Plane 17 (> 0x10FFFF) is illegal.
|
|
||||||
*/
|
|
||||||
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
|
|
||||||
if (flags == strictConversion) {
|
|
||||||
source -= (extraBytesToRead+1); /* return to the illegal value itself */
|
|
||||||
result = sourceIllegal;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*target++ = ch;
|
|
||||||
}
|
|
||||||
} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
|
|
||||||
result = sourceIllegal;
|
|
||||||
*target++ = UNI_REPLACEMENT_CHAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*sourceStart = source;
|
|
||||||
*targetStart = target;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
Note A.
|
|
||||||
The fall-through switches in UTF-8 reading code save a
|
|
||||||
temp variable, some decrements & conditionals. The switches
|
|
||||||
are equivalent to the following loop:
|
|
||||||
{
|
|
||||||
int tmpBytesToRead = extraBytesToRead+1;
|
|
||||||
do {
|
|
||||||
ch += *source++;
|
|
||||||
--tmpBytesToRead;
|
|
||||||
if (tmpBytesToRead) ch <<= 6;
|
|
||||||
} while (tmpBytesToRead > 0);
|
|
||||||
}
|
|
||||||
In UTF-8 writing code, the switches on "bytesToWrite" are
|
|
||||||
similarly unrolled loops.
|
|
||||||
|
|
||||||
--------------------------------------------------------------------- */
|
|
|
@ -1,151 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2001-2004 Unicode, Inc.
|
|
||||||
*
|
|
||||||
* Disclaimer
|
|
||||||
*
|
|
||||||
* This source code is provided as is by Unicode, Inc. No claims are
|
|
||||||
* made as to fitness for any particular purpose. No warranties of any
|
|
||||||
* kind are expressed or implied. The recipient agrees to determine
|
|
||||||
* applicability of information provided. If this file has been
|
|
||||||
* purchased on magnetic or optical media from Unicode, Inc., the
|
|
||||||
* sole remedy for any claim will be exchange of defective media
|
|
||||||
* within 90 days of receipt.
|
|
||||||
*
|
|
||||||
* Limitations on Rights to Redistribute This Code
|
|
||||||
*
|
|
||||||
* Unicode, Inc. hereby grants the right to freely use the information
|
|
||||||
* supplied in this file in the creation of products supporting the
|
|
||||||
* Unicode Standard, and to make copies of this file in any form
|
|
||||||
* for internal or external distribution as long as this notice
|
|
||||||
* remains attached.
|
|
||||||
*/
|
|
||||||
#ifndef CONVERTUTF_H
|
|
||||||
#define CONVERTUTF_H
|
|
||||||
/* ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
Conversions between UTF32, UTF-16, and UTF-8. Header file.
|
|
||||||
|
|
||||||
Several funtions are included here, forming a complete set of
|
|
||||||
conversions between the three formats. UTF-7 is not included
|
|
||||||
here, but is handled in a separate source file.
|
|
||||||
|
|
||||||
Each of these routines takes pointers to input buffers and output
|
|
||||||
buffers. The input buffers are const.
|
|
||||||
|
|
||||||
Each routine converts the text between *sourceStart and sourceEnd,
|
|
||||||
putting the result into the buffer between *targetStart and
|
|
||||||
targetEnd. Note: the end pointers are *after* the last item: e.g.
|
|
||||||
*(sourceEnd - 1) is the last item.
|
|
||||||
|
|
||||||
The return result indicates whether the conversion was successful,
|
|
||||||
and if not, whether the problem was in the source or target buffers.
|
|
||||||
(Only the first encountered problem is indicated.)
|
|
||||||
|
|
||||||
After the conversion, *sourceStart and *targetStart are both
|
|
||||||
updated to point to the end of last text successfully converted in
|
|
||||||
the respective buffers.
|
|
||||||
|
|
||||||
Input parameters:
|
|
||||||
sourceStart - pointer to a pointer to the source buffer.
|
|
||||||
The contents of this are modified on return so that
|
|
||||||
it points at the next thing to be converted.
|
|
||||||
targetStart - similarly, pointer to pointer to the target buffer.
|
|
||||||
sourceEnd, targetEnd - respectively pointers to the ends of the
|
|
||||||
two buffers, for overflow checking only.
|
|
||||||
|
|
||||||
These conversion functions take a ConversionFlags argument. When this
|
|
||||||
flag is set to strict, both irregular sequences and isolated surrogates
|
|
||||||
will cause an error. When the flag is set to lenient, both irregular
|
|
||||||
sequences and isolated surrogates are converted.
|
|
||||||
|
|
||||||
Whether the flag is strict or lenient, all illegal sequences will cause
|
|
||||||
an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
|
|
||||||
or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
|
|
||||||
must check for illegal sequences.
|
|
||||||
|
|
||||||
When the flag is set to lenient, characters over 0x10FFFF are converted
|
|
||||||
to the replacement character; otherwise (when the flag is set to strict)
|
|
||||||
they constitute an error.
|
|
||||||
|
|
||||||
Output parameters:
|
|
||||||
The value "sourceIllegal" is returned from some routines if the input
|
|
||||||
sequence is malformed. When "sourceIllegal" is returned, the source
|
|
||||||
value will point to the illegal value that caused the problem. E.g.,
|
|
||||||
in UTF-8 when a sequence is malformed, it points to the start of the
|
|
||||||
malformed sequence.
|
|
||||||
|
|
||||||
Author: Mark E. Davis, 1994.
|
|
||||||
Rev History: Rick McGowan, fixes & updates May 2001.
|
|
||||||
Fixes & updates, Sept 2001.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
|
||||||
The following 4 definitions are compiler-specific.
|
|
||||||
The C standard does not guarantee that wchar_t has at least
|
|
||||||
16 bits, so wchar_t is no less portable than unsigned short!
|
|
||||||
All should be unsigned values to avoid sign extension during
|
|
||||||
bit mask & shift operations.
|
|
||||||
------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
typedef unsigned long UTF32; /* at least 32 bits */
|
|
||||||
typedef unsigned short UTF16; /* at least 16 bits */
|
|
||||||
typedef unsigned char UTF8; /* typically 8 bits */
|
|
||||||
typedef unsigned char Boolean; /* 0 or 1 */
|
|
||||||
|
|
||||||
/* Some fundamental constants */
|
|
||||||
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
|
|
||||||
#define UNI_MAX_BMP (UTF32)0x0000FFFF
|
|
||||||
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
|
|
||||||
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
|
|
||||||
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
conversionOK, /* conversion successful */
|
|
||||||
sourceExhausted, /* partial character in source, but hit end */
|
|
||||||
targetExhausted, /* insuff. room in target for conversion */
|
|
||||||
sourceIllegal /* source sequence is illegal/malformed */
|
|
||||||
} ConversionResult;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
strictConversion = 0,
|
|
||||||
lenientConversion
|
|
||||||
} ConversionFlags;
|
|
||||||
|
|
||||||
/* This is for C++ and does no harm in C */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF8toUTF16 (
|
|
||||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
|
||||||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF16toUTF8 (
|
|
||||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
|
||||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF8toUTF32 (
|
|
||||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
|
||||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF32toUTF8 (
|
|
||||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
|
||||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF16toUTF32 (
|
|
||||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
|
||||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
ConversionResult ConvertUTF32toUTF16 (
|
|
||||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
|
||||||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
|
|
||||||
|
|
||||||
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
#endif // CONVERTUTF_H
|
|
|
@ -1,43 +0,0 @@
|
||||||
|
|
||||||
The accompanying C source code file "ConvertUTF.c" and the associated header
|
|
||||||
file "ConvertUTF.h" provide for conversion between various transformation
|
|
||||||
formats of Unicode characters. The following conversions are supported:
|
|
||||||
|
|
||||||
UTF-32 to UTF-16
|
|
||||||
UTF-32 to UTF-8
|
|
||||||
UTF-16 to UTF-32
|
|
||||||
UTF-16 to UTF-8
|
|
||||||
UTF-8 to UTF-16
|
|
||||||
UTF-8 to UTF-32
|
|
||||||
|
|
||||||
In addition, there is a test harness which runs various tests.
|
|
||||||
|
|
||||||
The files "CVTUTF7.C" and "CVTUTF7.H" are for archival and historical purposes
|
|
||||||
only. They have not been updated to Unicode 3.0 or later and should be
|
|
||||||
considered obsolescent. "CVTUTF7.C" contains two functions that can convert
|
|
||||||
between UCS2 (i.e., the BMP characters only) and UTF-7. Surrogates are
|
|
||||||
not supported, the code has not been tested, and should be considered
|
|
||||||
unsuitable for general purpose use.
|
|
||||||
|
|
||||||
Please submit any bug reports about these programs here:
|
|
||||||
|
|
||||||
http://www.unicode.org/unicode/reporting.html
|
|
||||||
|
|
||||||
Version 1.0: initial version.
|
|
||||||
|
|
||||||
Version 1.1: corrected some minor problems; added stricter checks.
|
|
||||||
|
|
||||||
Version 1.2: corrected switch statements associated with "extraBytesToRead"
|
|
||||||
in 4 & 5 byte cases, in functions for conversion from UTF8.
|
|
||||||
Note: formally, the 4 & 5 byte cases are illegal in the latest
|
|
||||||
UTF8, but the table and this code has always catered for those,
|
|
||||||
cases since at one time they were legal.
|
|
||||||
|
|
||||||
Version 1.3: Updated UTF-8 legality check;
|
|
||||||
updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions
|
|
||||||
Updated UTF-8 legality tests in harness.c
|
|
||||||
|
|
||||||
|
|
||||||
Last update: October 19, 2004
|
|
||||||
|
|
||||||
|
|
|
@ -3,18 +3,40 @@ PROJECT( OpenDDL-Parser )
|
||||||
SET ( OPENDDL_PARSER_VERSION_MAJOR 0 )
|
SET ( OPENDDL_PARSER_VERSION_MAJOR 0 )
|
||||||
SET ( OPENDDL_PARSER_VERSION_MINOR 1 )
|
SET ( OPENDDL_PARSER_VERSION_MINOR 1 )
|
||||||
SET ( OPENDDL_PARSER_VERSION_PATCH 0 )
|
SET ( OPENDDL_PARSER_VERSION_PATCH 0 )
|
||||||
SET ( OPENDDL_PARSER_VERSION ${CPPCORE_VERSION_MAJOR}.${CPPCORE_VERSION_MINOR}.${CPPCORE_VERSION_PATCH} )
|
SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} )
|
||||||
SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
|
SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
|
||||||
|
|
||||||
|
option( DDL_USE_CPP11 "Set to ON to use C++11 features ( always on on windows )." ON )
|
||||||
|
option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF )
|
||||||
|
option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON )
|
||||||
|
option( COVERALLS "Generate coveralls data" OFF )
|
||||||
|
|
||||||
|
if ( DDL_USE_CPP11 )
|
||||||
|
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
set( OPENDDL_CXXFLAGS -std=c++0x )
|
||||||
|
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
set( OPENDDL_CXXFLAGS --std=c++11 )
|
||||||
|
endif()
|
||||||
|
else( DDL_USE_CPP11 )
|
||||||
|
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||||
|
endif( DDL_USE_CPP11)
|
||||||
|
|
||||||
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||||
find_package(Threads)
|
find_package(Threads)
|
||||||
else()
|
else()
|
||||||
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
|
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if ( DDL_STATIC_LIBRARY )
|
||||||
|
add_definitions( -DOPENDDL_STATIC_LIBARY )
|
||||||
|
endif()
|
||||||
|
|
||||||
add_definitions( -DOPENDDLPARSER_BUILD )
|
add_definitions( -DOPENDDLPARSER_BUILD )
|
||||||
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
|
||||||
add_definitions( -D_VARIADIC_MAX=10 )
|
add_definitions( -D_VARIADIC_MAX=10 )
|
||||||
|
add_definitions( -DGTEST_HAS_PTHREAD=0 )
|
||||||
|
if ( DDL_DEBUG_OUTPUT )
|
||||||
|
add_definitions( -DDDL_DEBUG_HEADER_NAME)
|
||||||
|
endif()
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
./
|
./
|
||||||
|
@ -24,9 +46,10 @@ INCLUDE_DIRECTORIES(
|
||||||
)
|
)
|
||||||
|
|
||||||
link_directories(
|
link_directories(
|
||||||
./
|
${CMAKE_HOME_DIRECTORY}/lib
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake )
|
||||||
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
||||||
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
||||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
|
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
|
||||||
|
@ -40,18 +63,38 @@ if( WIN32 AND NOT CYGWIN )
|
||||||
endif()
|
endif()
|
||||||
elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||||
# Update if necessary
|
# Update if necessary
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++0x")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS}")
|
||||||
elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS} -Wwrite-strings")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (COVERALLS)
|
||||||
|
include(Coveralls)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Include the doc component.
|
||||||
|
FIND_PACKAGE( doxygen )
|
||||||
|
IF ( DOXYGEN_FOUND )
|
||||||
|
CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY )
|
||||||
|
ADD_CUSTOM_TARGET( doc ALL ${DOXYGEN_EXECUTABLE} doc/doxygenfile
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMENT "Generating API documentation with Doxygen" VERBATIM )
|
||||||
|
ENDIF ( DOXYGEN_FOUND )
|
||||||
|
|
||||||
SET ( openddl_parser_src
|
SET ( openddl_parser_src
|
||||||
|
code/OpenDDLCommon.cpp
|
||||||
|
code/OpenDDLExport.cpp
|
||||||
code/OpenDDLParser.cpp
|
code/OpenDDLParser.cpp
|
||||||
|
code/OpenDDLStream.cpp
|
||||||
code/DDLNode.cpp
|
code/DDLNode.cpp
|
||||||
code/Value.cpp
|
code/Value.cpp
|
||||||
|
include/openddlparser/OpenDDLCommon.h
|
||||||
|
include/openddlparser/OpenDDLExport.h
|
||||||
include/openddlparser/OpenDDLParser.h
|
include/openddlparser/OpenDDLParser.h
|
||||||
include/openddlparser/OpenDDLParserUtils.h
|
include/openddlparser/OpenDDLParserUtils.h
|
||||||
include/openddlparser/OpenDDLCommon.h
|
include/openddlparser/OpenDDLStream.h
|
||||||
include/openddlparser/DDLNode.h
|
include/openddlparser/DDLNode.h
|
||||||
include/openddlparser/Value.h
|
include/openddlparser/Value.h
|
||||||
README.md
|
README.md
|
||||||
|
@ -59,6 +102,69 @@ SET ( openddl_parser_src
|
||||||
|
|
||||||
SOURCE_GROUP( code FILES ${openddl_parser_src} )
|
SOURCE_GROUP( code FILES ${openddl_parser_src} )
|
||||||
|
|
||||||
ADD_LIBRARY( openddl_parser SHARED
|
if ( DDL_STATIC_LIBRARY )
|
||||||
${openddl_parser_src}
|
ADD_LIBRARY( openddl_parser STATIC
|
||||||
|
${openddl_parser_src}
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
ADD_LIBRARY( openddl_parser SHARED
|
||||||
|
${openddl_parser_src}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
SET ( GTEST_PATH contrib/gtest-1.7.0 )
|
||||||
|
|
||||||
|
SET ( gtest_src
|
||||||
|
${GTEST_PATH}/src/gtest-death-test.cc
|
||||||
|
${GTEST_PATH}/src/gtest-filepath.cc
|
||||||
|
${GTEST_PATH}/src/gtest-internal-inl.h
|
||||||
|
${GTEST_PATH}/src/gtest-port.cc
|
||||||
|
${GTEST_PATH}/src/gtest-printers.cc
|
||||||
|
${GTEST_PATH}/src/gtest-test-part.cc
|
||||||
|
${GTEST_PATH}/src/gtest-typed-test.cc
|
||||||
|
${GTEST_PATH}/src/gtest.cc
|
||||||
|
${GTEST_PATH}/src/gtest_main.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SET( openddl_parser_unittest_src
|
||||||
|
test/UnitTestCommon.h
|
||||||
|
test/DDLNodeTest.cpp
|
||||||
|
test/OpenDDLCommonTest.cpp
|
||||||
|
test/OpenDDLExportTest.cpp
|
||||||
|
test/OpenDDLParserTest.cpp
|
||||||
|
test/OpenDDLParserUtilsTest.cpp
|
||||||
|
test/OpenDDLStreamTest.cpp
|
||||||
|
test/OpenDDLIntegrationTest.cpp
|
||||||
|
test/ValueTest.cpp
|
||||||
|
test/OpenDDLDefectsTest.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} )
|
||||||
|
SOURCE_GROUP( gtest FILES ${gtest_src} )
|
||||||
|
|
||||||
|
ADD_EXECUTABLE( openddl_parser_unittest
|
||||||
|
${gtest_src}
|
||||||
|
${openddl_parser_unittest_src}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries( openddl_parser_unittest openddl_parser ${CMAKE_THREAD_LIBS_INIT} )
|
||||||
|
|
||||||
|
SET( openddl_parser_demo_src
|
||||||
|
demo/main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if (COVERALLS)
|
||||||
|
set(COVERAGE_SRCS ${gtest_src} ${openddl_parser_unittest_src} )
|
||||||
|
|
||||||
|
# Create the coveralls target.
|
||||||
|
coveralls_setup(
|
||||||
|
"${COVERAGE_SRCS}" # The source files.
|
||||||
|
ON # If we should upload.
|
||||||
|
"${PROJECT_SOURCE_DIR}/cmake/") # (Optional) Alternate project cmake module path.
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ADD_EXECUTABLE( openddl_parser_demo
|
||||||
|
${openddl_parser_demo_src}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries( openddl_parser_demo openddl_parser )
|
||||||
|
|
|
@ -12,5 +12,8 @@ Improvements value interface, serveral bugfixes.
|
||||||
- Henry Read ( henrya2 ):
|
- Henry Read ( henrya2 ):
|
||||||
Static build option, Interface improvements
|
Static build option, Interface improvements
|
||||||
|
|
||||||
|
- (wise86-android)
|
||||||
|
fix several mem-leaks
|
||||||
|
|
||||||
- Paul Holland ( pkholland ):
|
- Paul Holland ( pkholland ):
|
||||||
Bugfixes.
|
Bugfixes.
|
||||||
|
|
|
@ -11,7 +11,7 @@ Current coverity check status:
|
||||||
<img alt="Coverity Scan Build Status"
|
<img alt="Coverity Scan Build Status"
|
||||||
src="https://scan.coverity.com/projects/5606/badge.svg"/>
|
src="https://scan.coverity.com/projects/5606/badge.svg"/>
|
||||||
</a>
|
</a>
|
||||||
|
Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls)
|
||||||
Get the source code
|
Get the source code
|
||||||
===================
|
===================
|
||||||
You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
|
You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
|
||||||
|
@ -25,7 +25,7 @@ After installing it you can open a console and enter:
|
||||||
|
|
||||||
> cmake CMakeLists.txt
|
> cmake CMakeLists.txt
|
||||||
|
|
||||||
This command will generate a build environment for your installed build enrironment ( for Visual-Studio-users the project files will be generated, for gcc-users the makefiles will be generated ).
|
This command will generate a build environment for your preferred build tool ( for Visual-Studio-users the project files will be generated, for gcc-users the makefiles will be generated ).
|
||||||
When using an IDE open the IDE and run the build. When using GNU-make type in your console:
|
When using an IDE open the IDE and run the build. When using GNU-make type in your console:
|
||||||
|
|
||||||
> make
|
> make
|
||||||
|
|
|
@ -68,8 +68,8 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
DDLNode::~DDLNode() {
|
DDLNode::~DDLNode() {
|
||||||
releaseDataType<Property>( m_properties );
|
delete m_properties;
|
||||||
releaseDataType<Value>( m_value );
|
delete m_value;
|
||||||
releaseReferencedNames( m_references );
|
releaseReferencedNames( m_references );
|
||||||
|
|
||||||
delete m_dtArrayList;
|
delete m_dtArrayList;
|
||||||
|
@ -77,6 +77,9 @@ DDLNode::~DDLNode() {
|
||||||
if( s_allocatedNodes[ m_idx ] == this ) {
|
if( s_allocatedNodes[ m_idx ] == this ) {
|
||||||
s_allocatedNodes[ m_idx ] = ddl_nullptr;
|
s_allocatedNodes[ m_idx ] = ddl_nullptr;
|
||||||
}
|
}
|
||||||
|
for ( size_t i = 0; i<m_children.size(); i++ ){
|
||||||
|
delete m_children[ i ];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DDLNode::attachParent( DDLNode *parent ) {
|
void DDLNode::attachParent( DDLNode *parent ) {
|
||||||
|
@ -91,9 +94,8 @@ void DDLNode::attachParent( DDLNode *parent ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DDLNode::detachParent() {
|
void DDLNode::detachParent() {
|
||||||
if( m_parent ) {
|
if( ddl_nullptr != m_parent ) {
|
||||||
std::vector<DDLNode*>::iterator it;
|
DDLNodeIt it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this );
|
||||||
it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this );
|
|
||||||
if( m_parent->m_children.end() != it ) {
|
if( m_parent->m_children.end() != it ) {
|
||||||
m_parent->m_children.erase( it );
|
m_parent->m_children.erase( it );
|
||||||
}
|
}
|
||||||
|
@ -126,6 +128,8 @@ const std::string &DDLNode::getName() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DDLNode::setProperties( Property *prop ) {
|
void DDLNode::setProperties( Property *prop ) {
|
||||||
|
if(m_properties!=ddl_nullptr)
|
||||||
|
delete m_properties;
|
||||||
m_properties = prop;
|
m_properties = prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +191,10 @@ Reference *DDLNode::getReferences() const {
|
||||||
return m_references;
|
return m_references;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DDLNode::dump(IOStreamBase &stream) {
|
||||||
|
// Todo!
|
||||||
|
}
|
||||||
|
|
||||||
DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) {
|
DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) {
|
||||||
const size_t idx( s_allocatedNodes.size() );
|
const size_t idx( s_allocatedNodes.size() );
|
||||||
DDLNode *node = new DDLNode( type, name, idx, parent );
|
DDLNode *node = new DDLNode( type, name, idx, parent );
|
||||||
|
@ -197,7 +205,7 @@ DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLN
|
||||||
|
|
||||||
void DDLNode::releaseNodes() {
|
void DDLNode::releaseNodes() {
|
||||||
if( s_allocatedNodes.size() > 0 ) {
|
if( s_allocatedNodes.size() > 0 ) {
|
||||||
for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
|
for( DDLNodeIt it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
|
||||||
if( *it ) {
|
if( *it ) {
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
-----------------------------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------------------------*/
|
||||||
#include <openddlparser/OpenDDLCommon.h>
|
#include <openddlparser/OpenDDLCommon.h>
|
||||||
#include <openddlparser/DDLNode.h>
|
#include <openddlparser/DDLNode.h>
|
||||||
|
#include <openddlparser/Value.h>
|
||||||
|
|
||||||
BEGIN_ODDLPARSER_NS
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
@ -84,7 +85,14 @@ Name::~Name() {
|
||||||
m_id = ddl_nullptr;
|
m_id = ddl_nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference::Reference()
|
Name::Name( const Name &name ){
|
||||||
|
m_type=name.m_type;
|
||||||
|
m_id=new Text(name.m_id->m_buffer,name.m_id->m_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference::Reference()
|
||||||
: m_numRefs( 0 )
|
: m_numRefs( 0 )
|
||||||
, m_referencedName( ddl_nullptr ) {
|
, m_referencedName( ddl_nullptr ) {
|
||||||
// empty
|
// empty
|
||||||
|
@ -96,8 +104,16 @@ Reference::Reference( size_t numrefs, Name **names )
|
||||||
if ( numrefs > 0 ) {
|
if ( numrefs > 0 ) {
|
||||||
m_referencedName = new Name *[ numrefs ];
|
m_referencedName = new Name *[ numrefs ];
|
||||||
for ( size_t i = 0; i < numrefs; i++ ) {
|
for ( size_t i = 0; i < numrefs; i++ ) {
|
||||||
Name *name = new Name( names[ i ]->m_type, names[ i ]->m_id );
|
m_referencedName[ i ] = names[i];
|
||||||
m_referencedName[ i ] = name;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference::Reference(const Reference &ref) {
|
||||||
|
m_numRefs=ref.m_numRefs;
|
||||||
|
if(m_numRefs!=0){
|
||||||
|
m_referencedName = new Name*[m_numRefs];
|
||||||
|
for ( size_t i = 0; i < m_numRefs; i++ ) {
|
||||||
|
m_referencedName[i] = new Name(*ref.m_referencedName[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,6 +123,7 @@ Reference::~Reference() {
|
||||||
delete m_referencedName[ i ];
|
delete m_referencedName[ i ];
|
||||||
}
|
}
|
||||||
m_numRefs = 0;
|
m_numRefs = 0;
|
||||||
|
delete [] m_referencedName;
|
||||||
m_referencedName = ddl_nullptr;
|
m_referencedName = ddl_nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,21 +152,30 @@ Property::Property( Text *id )
|
||||||
}
|
}
|
||||||
|
|
||||||
Property::~Property() {
|
Property::~Property() {
|
||||||
m_key = ddl_nullptr;
|
delete m_key;
|
||||||
m_value = ddl_nullptr;
|
if(m_value!=ddl_nullptr)
|
||||||
m_ref = ddl_nullptr;;
|
delete m_value;
|
||||||
m_next = ddl_nullptr;;
|
if(m_ref!=ddl_nullptr)
|
||||||
|
delete(m_ref);
|
||||||
|
if(m_next!=ddl_nullptr)
|
||||||
|
delete m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList::DataArrayList()
|
DataArrayList::DataArrayList()
|
||||||
: m_numItems( 0 )
|
: m_numItems( 0 )
|
||||||
, m_dataList( ddl_nullptr )
|
, m_dataList( ddl_nullptr )
|
||||||
, m_next( ddl_nullptr ) {
|
, m_next( ddl_nullptr )
|
||||||
|
, m_refs(ddl_nullptr)
|
||||||
|
, m_numRefs(0){
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList::~DataArrayList() {
|
DataArrayList::~DataArrayList() {
|
||||||
// empty
|
delete m_dataList;
|
||||||
|
if(m_next!=ddl_nullptr)
|
||||||
|
delete m_next;
|
||||||
|
if(m_refs!=ddl_nullptr)
|
||||||
|
delete m_refs;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DataArrayList::size() {
|
size_t DataArrayList::size() {
|
||||||
|
|
|
@ -29,60 +29,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
BEGIN_ODDLPARSER_NS
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
StreamFormatterBase::StreamFormatterBase() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamFormatterBase::~StreamFormatterBase() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string StreamFormatterBase::format( const std::string &statement ) {
|
|
||||||
std::string tmp( statement );
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStreamBase::IOStreamBase( StreamFormatterBase *formatter )
|
|
||||||
: m_formatter( formatter )
|
|
||||||
, m_file( ddl_nullptr ) {
|
|
||||||
if (ddl_nullptr == m_formatter) {
|
|
||||||
m_formatter = new StreamFormatterBase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStreamBase::~IOStreamBase() {
|
|
||||||
delete m_formatter;
|
|
||||||
m_formatter = ddl_nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IOStreamBase::open( const std::string &name ) {
|
|
||||||
m_file = ::fopen( name.c_str(), "a" );
|
|
||||||
if (m_file == ddl_nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IOStreamBase::close() {
|
|
||||||
if (ddl_nullptr == m_file) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
::fclose( m_file );
|
|
||||||
m_file = ddl_nullptr;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t IOStreamBase::write( const std::string &statement ) {
|
|
||||||
if (ddl_nullptr == m_file) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
std::string formatStatement = m_formatter->format( statement );
|
|
||||||
return ::fwrite( formatStatement.c_str(), sizeof( char ), formatStatement.size(), m_file );
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DDLNodeIterator {
|
struct DDLNodeIterator {
|
||||||
const DDLNode::DllNodeList &m_childs;
|
const DDLNode::DllNodeList &m_childs;
|
||||||
size_t m_idx;
|
size_t m_idx;
|
||||||
|
@ -280,7 +226,7 @@ bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std:
|
||||||
statement += "[";
|
statement += "[";
|
||||||
char buffer[ 256 ];
|
char buffer[ 256 ];
|
||||||
::memset( buffer, '\0', 256 * sizeof( char ) );
|
::memset( buffer, '\0', 256 * sizeof( char ) );
|
||||||
sprintf( buffer, "%d", int(numItems) );
|
sprintf( buffer, "%d", static_cast<int>( numItems ) );
|
||||||
statement += buffer;
|
statement += buffer;
|
||||||
statement += "]";
|
statement += "]";
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
BEGIN_ODDLPARSER_NS
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
static const char *Version = "0.3.0";
|
static const char *Version = "0.4.0";
|
||||||
|
|
||||||
namespace Grammar {
|
namespace Grammar {
|
||||||
static const char *OpenBracketToken = "{";
|
static const char *OpenBracketToken = "{";
|
||||||
|
@ -49,7 +49,7 @@ namespace Grammar {
|
||||||
static const char *BoolFalse = "false";
|
static const char *BoolFalse = "false";
|
||||||
static const char *CommaSeparator = ",";
|
static const char *CommaSeparator = ",";
|
||||||
|
|
||||||
static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
|
static const char *PrimitiveTypeToken[ Value::ddl_types_max ] = {
|
||||||
"bool",
|
"bool",
|
||||||
"int8",
|
"int8",
|
||||||
"int16",
|
"int16",
|
||||||
|
@ -74,8 +74,8 @@ const char *getTypeToken( Value::ValueType type ) {
|
||||||
static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
|
static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl;
|
stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl;
|
||||||
std::string full(in);
|
std::string full( in );
|
||||||
std::string part(full.substr(0,50));
|
std::string part( full.substr( 0, 50 ) );
|
||||||
stream << part;
|
stream << part;
|
||||||
callback( ddl_error_msg, stream.str() );
|
callback( ddl_error_msg, stream.str() );
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,7 @@ static bool isIntegerType( Value::ValueType integerType ) {
|
||||||
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
|
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +106,7 @@ static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
|
||||||
const std::string type( id->m_buffer );
|
const std::string type( id->m_buffer );
|
||||||
DDLNode *parent( parser->top() );
|
DDLNode *parent( parser->top() );
|
||||||
DDLNode *node = DDLNode::create( type, "", parent );
|
DDLNode *node = DDLNode::create( type, "", parent );
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,10 +194,11 @@ size_t OpenDDLParser::getBufferSize() const {
|
||||||
void OpenDDLParser::clear() {
|
void OpenDDLParser::clear() {
|
||||||
m_buffer.resize( 0 );
|
m_buffer.resize( 0 );
|
||||||
if( ddl_nullptr != m_context ) {
|
if( ddl_nullptr != m_context ) {
|
||||||
m_context->m_root = ddl_nullptr;
|
delete m_context;
|
||||||
|
m_context=ddl_nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDLNode::releaseNodes();
|
// DDLNode::releaseNodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenDDLParser::parse() {
|
bool OpenDDLParser::parse() {
|
||||||
|
@ -212,11 +214,11 @@ bool OpenDDLParser::parse() {
|
||||||
|
|
||||||
// do the main parsing
|
// do the main parsing
|
||||||
char *current( &m_buffer[ 0 ] );
|
char *current( &m_buffer[ 0 ] );
|
||||||
char *end( &m_buffer[ m_buffer.size() - 1 ] + 1 );
|
char *end( &m_buffer[m_buffer.size() - 1 ] + 1 );
|
||||||
size_t pos( current - &m_buffer[ 0 ] );
|
size_t pos( current - &m_buffer[ 0 ] );
|
||||||
while( pos < m_buffer.size() ) {
|
while( pos < m_buffer.size() ) {
|
||||||
current = parseNextNode( current, end );
|
current = parseNextNode( current, end );
|
||||||
if(current==ddl_nullptr) {
|
if ( current == ddl_nullptr ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pos = current - &m_buffer[ 0 ];
|
pos = current - &m_buffer[ 0 ];
|
||||||
|
@ -245,7 +247,7 @@ static void dumpId( Identifier *id ) {
|
||||||
if( ddl_nullptr != id ) {
|
if( ddl_nullptr != id ) {
|
||||||
if ( ddl_nullptr != id->m_text.m_buffer ) {
|
if ( ddl_nullptr != id->m_text.m_buffer ) {
|
||||||
std::cout << id->m_text.m_buffer << std::endl;
|
std::cout << id->m_text.m_buffer << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -271,14 +273,17 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "nullptr returned by creating DDLNode." << std::endl;
|
std::cerr << "nullptr returned by creating DDLNode." << std::endl;
|
||||||
}
|
}
|
||||||
|
delete id;
|
||||||
|
|
||||||
Name *name(ddl_nullptr);
|
Name *name(ddl_nullptr);
|
||||||
in = OpenDDLParser::parseName(in, end, &name);
|
in = OpenDDLParser::parseName(in, end, &name);
|
||||||
if( ddl_nullptr != name && ddl_nullptr != node ) {
|
if( ddl_nullptr != name && ddl_nullptr != node ) {
|
||||||
const std::string nodeName( name->m_id->m_buffer );
|
const std::string nodeName( name->m_id->m_buffer );
|
||||||
node->setName( nodeName );
|
node->setName( nodeName );
|
||||||
|
delete name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Property *first(ddl_nullptr);
|
Property *first(ddl_nullptr);
|
||||||
in = lookForNextToken(in, end);
|
in = lookForNextToken(in, end);
|
||||||
if (*in == Grammar::OpenPropertyToken[0]) {
|
if (*in == Grammar::OpenPropertyToken[0]) {
|
||||||
|
@ -303,7 +308,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
||||||
prev = prop;
|
prev = prop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the properties
|
// set the properties
|
||||||
|
@ -322,17 +327,17 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
|
||||||
|
|
||||||
bool error( false );
|
bool error( false );
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
if( *in == '{' ) {
|
if( *in == *Grammar::OpenBracketToken) {
|
||||||
// loop over all children ( data and nodes )
|
// loop over all children ( data and nodes )
|
||||||
do {
|
do {
|
||||||
in = parseStructureBody( in, end, error );
|
in = parseStructureBody( in, end, error );
|
||||||
if(in == ddl_nullptr){
|
if(in == ddl_nullptr){
|
||||||
return ddl_nullptr;
|
return ddl_nullptr;
|
||||||
}
|
}
|
||||||
} while ( *in != '}' );
|
} while ( *in != *Grammar::CloseBracketToken);
|
||||||
in++;
|
++in;
|
||||||
} else {
|
} else {
|
||||||
in++;
|
++in;
|
||||||
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
|
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
|
||||||
error = true;
|
error = true;
|
||||||
return ddl_nullptr;
|
return ddl_nullptr;
|
||||||
|
@ -373,7 +378,7 @@ static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayLi
|
||||||
|
|
||||||
char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
|
char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
|
||||||
if( !isNumeric( *in ) && !isCharacter( *in ) ) {
|
if( !isNumeric( *in ) && !isCharacter( *in ) ) {
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
|
@ -431,7 +436,6 @@ DDLNode *OpenDDLParser::popNode() {
|
||||||
|
|
||||||
DDLNode *topNode( top() );
|
DDLNode *topNode( top() );
|
||||||
m_stack.pop_back();
|
m_stack.pop_back();
|
||||||
|
|
||||||
return topNode;
|
return topNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +471,14 @@ void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
|
||||||
for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
|
for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
|
||||||
char *c( &buffer[readIdx] );
|
char *c( &buffer[readIdx] );
|
||||||
// check for a comment
|
// check for a comment
|
||||||
if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
|
if (isCommentOpenTag(c, end)) {
|
||||||
|
++readIdx;
|
||||||
|
while (!isCommentCloseTag(&buffer[readIdx], end)) {
|
||||||
|
++readIdx;
|
||||||
|
}
|
||||||
|
++readIdx;
|
||||||
|
++readIdx;
|
||||||
|
} else if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
|
||||||
newBuffer.push_back( buffer[ readIdx ] );
|
newBuffer.push_back( buffer[ readIdx ] );
|
||||||
} else {
|
} else {
|
||||||
if( isComment<char>( c, end ) ) {
|
if( isComment<char>( c, end ) ) {
|
||||||
|
@ -529,14 +540,17 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Text **id ) {
|
||||||
// get size of id
|
// get size of id
|
||||||
size_t idLen( 0 );
|
size_t idLen( 0 );
|
||||||
char *start( in );
|
char *start( in );
|
||||||
while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != Grammar::OpenPropertyToken[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] && *in != '$' ) {
|
while( !isSeparator( *in ) &&
|
||||||
|
!isNewLine( *in ) && ( in != end ) &&
|
||||||
|
*in != Grammar::OpenPropertyToken[ 0 ] &&
|
||||||
|
*in != Grammar::ClosePropertyToken[ 0 ] &&
|
||||||
|
*in != '$' ) {
|
||||||
++in;
|
++in;
|
||||||
++idLen;
|
++idLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t len( idLen );
|
const size_t len( idLen );
|
||||||
Text *newId = new Text( start, len );
|
*id = new Text( start, len );
|
||||||
*id = newId;
|
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
@ -552,7 +566,7 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
|
||||||
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
|
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
|
||||||
prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
|
prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
|
||||||
if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
|
if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
|
||||||
type = ( Value::ValueType ) i;
|
type = static_cast<Value::ValueType>( i );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -567,14 +581,14 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
|
||||||
bool ok( true );
|
bool ok( true );
|
||||||
if( *in == Grammar::OpenArrayToken[ 0 ] ) {
|
if( *in == Grammar::OpenArrayToken[ 0 ] ) {
|
||||||
ok = false;
|
ok = false;
|
||||||
in++;
|
++in;
|
||||||
char *start( in );
|
char *start( in );
|
||||||
while ( in != end ) {
|
while ( in != end ) {
|
||||||
in++;
|
++in;
|
||||||
if( *in == Grammar::CloseArrayToken[ 0 ] ) {
|
if( *in == Grammar::CloseArrayToken[ 0 ] ) {
|
||||||
len = ::atoi( start );
|
len = ::atoi( start );
|
||||||
ok = true;
|
ok = true;
|
||||||
in++;
|
++in;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,10 +637,10 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean )
|
||||||
char *start( in );
|
char *start( in );
|
||||||
size_t len( 0 );
|
size_t len( 0 );
|
||||||
while( !isSeparator( *in ) && in != end ) {
|
while( !isSeparator( *in ) && in != end ) {
|
||||||
in++;
|
++in;
|
||||||
len++;
|
++len;
|
||||||
}
|
}
|
||||||
len++;
|
++len;
|
||||||
int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
|
int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
|
||||||
if( 0 != res ) {
|
if( 0 != res ) {
|
||||||
res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
|
res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
|
||||||
|
@ -657,7 +671,7 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
char *start( in );
|
char *start( in );
|
||||||
while( !isSeparator( *in ) && in != end ) {
|
while( !isSeparator( *in ) && in != end ) {
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isNumeric( *start ) ) {
|
if( isNumeric( *start ) ) {
|
||||||
|
@ -671,29 +685,29 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
|
||||||
*integer = ValueAllocator::allocPrimData( integerType );
|
*integer = ValueAllocator::allocPrimData( integerType );
|
||||||
switch( integerType ) {
|
switch( integerType ) {
|
||||||
case Value::ddl_int8:
|
case Value::ddl_int8:
|
||||||
( *integer )->setInt8( (int8) value );
|
( *integer )->setInt8( (int8) value );
|
||||||
break;
|
break;
|
||||||
case Value::ddl_int16:
|
case Value::ddl_int16:
|
||||||
( *integer )->setInt16( ( int16 ) value );
|
( *integer )->setInt16( ( int16 ) value );
|
||||||
break;
|
break;
|
||||||
case Value::ddl_int32:
|
case Value::ddl_int32:
|
||||||
( *integer )->setInt32( ( int32 ) value );
|
( *integer )->setInt32( ( int32 ) value );
|
||||||
break;
|
break;
|
||||||
case Value::ddl_int64:
|
case Value::ddl_int64:
|
||||||
( *integer )->setInt64( ( int64 ) value );
|
( *integer )->setInt64( ( int64 ) value );
|
||||||
break;
|
break;
|
||||||
case Value::ddl_unsigned_int8:
|
case Value::ddl_unsigned_int8:
|
||||||
( *integer )->setUnsignedInt8( (uint8) uvalue );
|
( *integer )->setUnsignedInt8( (uint8) uvalue );
|
||||||
break;
|
break;
|
||||||
case Value::ddl_unsigned_int16:
|
case Value::ddl_unsigned_int16:
|
||||||
( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
|
( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
|
||||||
break;
|
break;
|
||||||
case Value::ddl_unsigned_int32:
|
case Value::ddl_unsigned_int32:
|
||||||
( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
|
( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
|
||||||
break;
|
break;
|
||||||
case Value::ddl_unsigned_int64:
|
case Value::ddl_unsigned_int64:
|
||||||
( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
|
( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -711,7 +725,7 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
char *start( in );
|
char *start( in );
|
||||||
while( !isSeparator( *in ) && in != end ) {
|
while( !isSeparator( *in ) && in != end ) {
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the float value
|
// parse the float value
|
||||||
|
@ -732,8 +746,7 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ok ) {
|
if( ok ) {
|
||||||
if(floatType == Value::ddl_double)
|
if ( floatType == Value::ddl_double ) {
|
||||||
{
|
|
||||||
const double value( atof( start ) );
|
const double value( atof( start ) );
|
||||||
*floating = ValueAllocator::allocPrimData( Value::ddl_double );
|
*floating = ValueAllocator::allocPrimData( Value::ddl_double );
|
||||||
( *floating )->setDouble( value );
|
( *floating )->setDouble( value );
|
||||||
|
@ -757,17 +770,17 @@ char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData
|
||||||
size_t len( 0 );
|
size_t len( 0 );
|
||||||
char *start( in );
|
char *start( in );
|
||||||
if( *start == '\"' ) {
|
if( *start == '\"' ) {
|
||||||
start++;
|
++start;
|
||||||
in++;
|
++in;
|
||||||
while( *in != '\"' && in != end ) {
|
while( *in != '\"' && in != end ) {
|
||||||
in++;
|
++in;
|
||||||
len++;
|
++len;
|
||||||
}
|
}
|
||||||
|
|
||||||
*stringData = ValueAllocator::allocPrimData( Value::ddl_string, len );
|
*stringData = ValueAllocator::allocPrimData( Value::ddl_string, len );
|
||||||
::strncpy( ( char* ) ( *stringData )->m_data, start, len );
|
::strncpy( ( char* ) ( *stringData )->m_data, start, len );
|
||||||
( *stringData )->m_data[len] = '\0';
|
( *stringData )->m_data[len] = '\0';
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
|
@ -791,12 +804,12 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
in++;
|
++in;
|
||||||
if( *in != 'x' && *in != 'X' ) {
|
if( *in != 'x' && *in != 'X' ) {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
in++;
|
++in;
|
||||||
bool ok( true );
|
bool ok( true );
|
||||||
char *start( in );
|
char *start( in );
|
||||||
int pos( 0 );
|
int pos( 0 );
|
||||||
|
@ -805,8 +818,8 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
|
||||||
ok = false;
|
ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pos++;
|
++pos;
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !ok ) {
|
if( !ok ) {
|
||||||
|
@ -816,9 +829,9 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
|
||||||
int value( 0 );
|
int value( 0 );
|
||||||
while( pos > 0 ) {
|
while( pos > 0 ) {
|
||||||
int v = hex2Decimal( *start );
|
int v = hex2Decimal( *start );
|
||||||
pos--;
|
--pos;
|
||||||
value = ( value << 4 ) | v;
|
value = ( value << 4 ) | v;
|
||||||
start++;
|
++start;
|
||||||
}
|
}
|
||||||
|
|
||||||
*data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 );
|
*data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 );
|
||||||
|
@ -841,7 +854,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
|
||||||
if( ddl_nullptr != id ) {
|
if( ddl_nullptr != id ) {
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
if( *in == '=' ) {
|
if( *in == '=' ) {
|
||||||
in++;
|
++in;
|
||||||
in = getNextToken( in, end );
|
in = getNextToken( in, end );
|
||||||
Value *primData( ddl_nullptr );
|
Value *primData( ddl_nullptr );
|
||||||
if( isInteger( in, end ) ) {
|
if( isInteger( in, end ) ) {
|
||||||
|
@ -862,6 +875,8 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
|
||||||
( *prop )->m_ref = ref;
|
( *prop )->m_ref = ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
delete id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,7 +893,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
|
||||||
|
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
if( *in == '{' ) {
|
if( *in == '{' ) {
|
||||||
in++;
|
++in;
|
||||||
Value *current( ddl_nullptr ), *prev( ddl_nullptr );
|
Value *current( ddl_nullptr ), *prev( ddl_nullptr );
|
||||||
while( '}' != *in ) {
|
while( '}' != *in ) {
|
||||||
current = ddl_nullptr;
|
current = ddl_nullptr;
|
||||||
|
@ -934,7 +949,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
|
||||||
prev->setNext( current );
|
prev->setNext( current );
|
||||||
prev = current;
|
prev = current;
|
||||||
}
|
}
|
||||||
numValues++;
|
++numValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
in = getNextSeparator( in, end );
|
in = getNextSeparator( in, end );
|
||||||
|
@ -942,7 +957,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
|
@ -972,7 +987,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType ty
|
||||||
|
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
if( *in == Grammar::OpenBracketToken[ 0 ] ) {
|
if( *in == Grammar::OpenBracketToken[ 0 ] ) {
|
||||||
in++;
|
++in;
|
||||||
Value *currentValue( ddl_nullptr );
|
Value *currentValue( ddl_nullptr );
|
||||||
Reference *refs( ddl_nullptr );
|
Reference *refs( ddl_nullptr );
|
||||||
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
|
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
|
||||||
|
@ -995,7 +1010,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType ty
|
||||||
}
|
}
|
||||||
} while( Grammar::CommaSeparator[ 0 ] == *in && in != end );
|
} while( Grammar::CommaSeparator[ 0 ] == *in && in != end );
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2015 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#include <openddlparser/OpenDDLStream.h>
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
StreamFormatterBase::StreamFormatterBase() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamFormatterBase::~StreamFormatterBase() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StreamFormatterBase::format(const std::string &statement) {
|
||||||
|
std::string tmp(statement);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOStreamBase::IOStreamBase(StreamFormatterBase *formatter)
|
||||||
|
: m_formatter(formatter)
|
||||||
|
, m_file(ddl_nullptr) {
|
||||||
|
if (ddl_nullptr == m_formatter) {
|
||||||
|
m_formatter = new StreamFormatterBase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IOStreamBase::~IOStreamBase() {
|
||||||
|
delete m_formatter;
|
||||||
|
m_formatter = ddl_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOStreamBase::open(const std::string &name) {
|
||||||
|
m_file = ::fopen(name.c_str(), "a");
|
||||||
|
if (m_file == ddl_nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOStreamBase::close() {
|
||||||
|
if (ddl_nullptr == m_file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
::fclose(m_file);
|
||||||
|
m_file = ddl_nullptr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOStreamBase::isOpen() const {
|
||||||
|
return ( ddl_nullptr != m_file );
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IOStreamBase::read( size_t sizeToRead, std::string &statement ) {
|
||||||
|
if (ddl_nullptr == m_file) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
statement.resize(sizeToRead);
|
||||||
|
const size_t readBytes = ::fread( &statement[0], 1, sizeToRead, m_file );
|
||||||
|
|
||||||
|
return readBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IOStreamBase::write(const std::string &statement) {
|
||||||
|
if (ddl_nullptr == m_file) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::string formatStatement = m_formatter->format(statement);
|
||||||
|
return ::fwrite(formatStatement.c_str(), sizeof(char), formatStatement.size(), m_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
|
@ -110,7 +110,17 @@ Value::Value( ValueType type )
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::~Value() {
|
Value::~Value() {
|
||||||
// empty
|
if(m_data!=ddl_nullptr) {
|
||||||
|
if (m_type == ddl_ref ) {
|
||||||
|
Reference *tmp = (Reference *) m_data;
|
||||||
|
if (tmp != ddl_nullptr)
|
||||||
|
delete tmp;
|
||||||
|
}else
|
||||||
|
delete[] m_data;
|
||||||
|
|
||||||
|
}
|
||||||
|
if(m_next!=ddl_nullptr)
|
||||||
|
delete m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::setBool( bool value ) {
|
void Value::setBool( bool value ) {
|
||||||
|
@ -273,13 +283,7 @@ void Value::setRef( Reference *ref ) {
|
||||||
delete [] m_data;
|
delete [] m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data = new unsigned char[ sizeof( Reference ) ];
|
m_data = (unsigned char*) new Reference(*ref);
|
||||||
Reference *myRef = ( Reference * ) m_data;
|
|
||||||
myRef->m_numRefs = ref->m_numRefs;
|
|
||||||
myRef->m_referencedName = new Name *[ myRef->m_numRefs ];
|
|
||||||
for ( size_t i = 0; i < myRef->m_numRefs; i++ ) {
|
|
||||||
myRef->m_referencedName[ i ] = new Name( ref->m_referencedName[ i ]->m_type, ref->m_referencedName[ i ]->m_id );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +294,7 @@ Reference *Value::getRef() const {
|
||||||
return (Reference*) m_data;
|
return (Reference*) m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::dump() {
|
void Value::dump( IOStreamBase &stream ) {
|
||||||
switch( m_type ) {
|
switch( m_type ) {
|
||||||
case ddl_none:
|
case ddl_none:
|
||||||
std::cout << "None" << std::endl;
|
std::cout << "None" << std::endl;
|
||||||
|
@ -350,7 +354,7 @@ Value *Value::getNext() const {
|
||||||
return m_next;
|
return m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Value::size(){
|
size_t Value::size() const{
|
||||||
size_t result=1;
|
size_t result=1;
|
||||||
Value *n=m_next;
|
Value *n=m_next;
|
||||||
while( n!=ddl_nullptr) {
|
while( n!=ddl_nullptr) {
|
||||||
|
@ -366,7 +370,6 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *data = new Value( type );
|
Value *data = new Value( type );
|
||||||
data->m_type = type;
|
|
||||||
switch( type ) {
|
switch( type ) {
|
||||||
case Value::ddl_bool:
|
case Value::ddl_bool:
|
||||||
data->m_size = sizeof( bool );
|
data->m_size = sizeof( bool );
|
||||||
|
@ -405,10 +408,10 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
|
||||||
data->m_size = sizeof( double );
|
data->m_size = sizeof( double );
|
||||||
break;
|
break;
|
||||||
case Value::ddl_string:
|
case Value::ddl_string:
|
||||||
data->m_size = sizeof( char );
|
data->m_size = sizeof( char )*(len+1);
|
||||||
break;
|
break;
|
||||||
case Value::ddl_ref:
|
case Value::ddl_ref:
|
||||||
data->m_size = sizeof( char );
|
data->m_size = 0;
|
||||||
break;
|
break;
|
||||||
case Value::ddl_none:
|
case Value::ddl_none:
|
||||||
case Value::ddl_types_max:
|
case Value::ddl_types_max:
|
||||||
|
@ -417,12 +420,8 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if( data->m_size ) {
|
if( data->m_size ) {
|
||||||
size_t len1( len );
|
|
||||||
if( Value::ddl_string == type ) {
|
|
||||||
len1++;
|
|
||||||
}
|
|
||||||
data->m_size *= len1;
|
|
||||||
data->m_data = new unsigned char[ data->m_size ];
|
data->m_data = new unsigned char[ data->m_size ];
|
||||||
|
::memset(data->m_data,0,data->m_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -29,6 +29,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
BEGIN_ODDLPARSER_NS
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
class IOStreamBase;
|
||||||
class Value;
|
class Value;
|
||||||
class OpenDDLParser;
|
class OpenDDLParser;
|
||||||
|
|
||||||
|
@ -53,6 +55,9 @@ public:
|
||||||
/// @brief The child-node-list type.
|
/// @brief The child-node-list type.
|
||||||
typedef std::vector<DDLNode*> DllNodeList;
|
typedef std::vector<DDLNode*> DllNodeList;
|
||||||
|
|
||||||
|
/// @brief The child-node-list iterator.
|
||||||
|
typedef std::vector<DDLNode*>::iterator DDLNodeIt;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @brief The class destructor.
|
/// @brief The class destructor.
|
||||||
~DDLNode();
|
~DDLNode();
|
||||||
|
@ -81,7 +86,7 @@ public:
|
||||||
const std::string &getType() const;
|
const std::string &getType() const;
|
||||||
|
|
||||||
/// Set the name of the DDLNode instance.
|
/// Set the name of the DDLNode instance.
|
||||||
/// @param type [in] The name.
|
/// @param name [in] The name.
|
||||||
void setName( const std::string &name );
|
void setName( const std::string &name );
|
||||||
|
|
||||||
/// @brief Returns the name of the DDLNode instance.
|
/// @brief Returns the name of the DDLNode instance.
|
||||||
|
@ -89,7 +94,7 @@ public:
|
||||||
const std::string &getName() const;
|
const std::string &getName() const;
|
||||||
|
|
||||||
/// @brief Set a new property set.
|
/// @brief Set a new property set.
|
||||||
/// @param prop [in] The first element of the property set.
|
/// @param prop [in] The first element of the property set.
|
||||||
void setProperties( Property *prop );
|
void setProperties( Property *prop );
|
||||||
|
|
||||||
/// @brief Returns the first element of the assigned property set.
|
/// @brief Returns the first element of the assigned property set.
|
||||||
|
@ -97,7 +102,7 @@ public:
|
||||||
Property *getProperties() const;
|
Property *getProperties() const;
|
||||||
|
|
||||||
/// @brief Looks for a given property.
|
/// @brief Looks for a given property.
|
||||||
/// @param name [in] The name for the property to look for.
|
/// @param name [in] The name for the property to look for.
|
||||||
/// @return true, if a corresponding property is assigned to the node, false if not.
|
/// @return true, if a corresponding property is assigned to the node, false if not.
|
||||||
bool hasProperty( const std::string &name );
|
bool hasProperty( const std::string &name );
|
||||||
|
|
||||||
|
@ -106,12 +111,12 @@ public:
|
||||||
bool hasProperties() const;
|
bool hasProperties() const;
|
||||||
|
|
||||||
/// @brief Search for a given property and returns it. Will return ddl_nullptr if no property was found.
|
/// @brief Search for a given property and returns it. Will return ddl_nullptr if no property was found.
|
||||||
/// @param name [in] The name for the property to look for.
|
/// @param name [in] The name for the property to look for.
|
||||||
/// @return The property or ddl_nullptr if no property was found.
|
/// @return The property or ddl_nullptr if no property was found.
|
||||||
Property *findPropertyByName( const std::string &name );
|
Property *findPropertyByName( const std::string &name );
|
||||||
|
|
||||||
/// @brief Set a new value set.
|
/// @brief Set a new value set.
|
||||||
/// @param val [in] The first value instance of the value set.
|
/// @param val [in] The first value instance of the value set.
|
||||||
void setValue( Value *val );
|
void setValue( Value *val );
|
||||||
|
|
||||||
/// @brief Returns the first element of the assigned value set.
|
/// @brief Returns the first element of the assigned value set.
|
||||||
|
@ -119,7 +124,7 @@ public:
|
||||||
Value *getValue() const;
|
Value *getValue() const;
|
||||||
|
|
||||||
/// @brief Set a new DataArrayList.
|
/// @brief Set a new DataArrayList.
|
||||||
/// @param val [in] The DataArrayList instance.
|
/// @param dtArrayList [in] The DataArrayList instance.
|
||||||
void setDataArrayList( DataArrayList *dtArrayList );
|
void setDataArrayList( DataArrayList *dtArrayList );
|
||||||
|
|
||||||
/// @brief Returns the DataArrayList.
|
/// @brief Returns the DataArrayList.
|
||||||
|
@ -127,17 +132,21 @@ public:
|
||||||
DataArrayList *getDataArrayList() const;
|
DataArrayList *getDataArrayList() const;
|
||||||
|
|
||||||
/// @brief Set a new Reference set.
|
/// @brief Set a new Reference set.
|
||||||
/// @param val [in] The first value instance of the Reference set.
|
/// @param refs [in] The first value instance of the Reference set.
|
||||||
void setReferences( Reference *refs );
|
void setReferences( Reference *refs );
|
||||||
|
|
||||||
/// @brief Returns the first element of the assigned Reference set.
|
/// @brief Returns the first element of the assigned Reference set.
|
||||||
/// @return The first property of the assigned Reference set.
|
/// @return The first property of the assigned Reference set.
|
||||||
Reference *getReferences() const;
|
Reference *getReferences() const;
|
||||||
|
|
||||||
|
/// @brief Will dump the node into the stream.
|
||||||
|
/// @param stream [in] The stream to write to.
|
||||||
|
void dump(IOStreamBase &stream);
|
||||||
|
|
||||||
/// @brief The creation method.
|
/// @brief The creation method.
|
||||||
/// @param type [in] The DDLNode type.
|
/// @param type [in] The DDLNode type.
|
||||||
/// @param name [in] The name for the new DDLNode instance.
|
/// @param name [in] The name for the new DDLNode instance.
|
||||||
/// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there.
|
/// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there.
|
||||||
/// @return The new created node instance.
|
/// @return The new created node instance.
|
||||||
static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr );
|
static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr );
|
||||||
|
|
||||||
|
|
|
@ -148,12 +148,12 @@ struct DLL_ODDLPARSER_EXPORT Name {
|
||||||
/// @param type [in] The name type.
|
/// @param type [in] The name type.
|
||||||
/// @param id [in] The id.
|
/// @param id [in] The id.
|
||||||
Name( NameType type, Text *id );
|
Name( NameType type, Text *id );
|
||||||
|
Name( const Name &name );
|
||||||
/// @brief The destructor.
|
/// @brief The destructor.
|
||||||
~Name();
|
~Name();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Name( const Name & ) ddl_no_copy;
|
|
||||||
Name &operator = ( const Name& ) ddl_no_copy;
|
Name &operator = ( const Name& ) ddl_no_copy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ struct DLL_ODDLPARSER_EXPORT Reference {
|
||||||
|
|
||||||
/// @brief The default constructor.
|
/// @brief The default constructor.
|
||||||
Reference();
|
Reference();
|
||||||
|
Reference( const Reference &ref );
|
||||||
/// @brief The constructor with an array of ref names.
|
/// @brief The constructor with an array of ref names.
|
||||||
/// @param numrefs [in] The number of ref names.
|
/// @param numrefs [in] The number of ref names.
|
||||||
/// @param names [in] The ref names.
|
/// @param names [in] The ref names.
|
||||||
|
@ -178,7 +178,6 @@ struct DLL_ODDLPARSER_EXPORT Reference {
|
||||||
size_t sizeInBytes();
|
size_t sizeInBytes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Reference( const Reference & ) ddl_no_copy;
|
|
||||||
Reference &operator = ( const Reference & ) ddl_no_copy;
|
Reference &operator = ( const Reference & ) ddl_no_copy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,37 +23,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <openddlparser/OpenDDLCommon.h>
|
#include <openddlparser/OpenDDLCommon.h>
|
||||||
|
#include <openddlparser/OpenDDLStream.h>
|
||||||
#include <openddlparser/Value.h>
|
#include <openddlparser/Value.h>
|
||||||
|
|
||||||
BEGIN_ODDLPARSER_NS
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------------
|
// Forward declarations
|
||||||
/// @ingroup IOStreamBase
|
class IOStreamBase;
|
||||||
/// @brief This class represents the stream to write out.
|
|
||||||
//-------------------------------------------------------------------------------------------------
|
|
||||||
class DLL_ODDLPARSER_EXPORT StreamFormatterBase {
|
|
||||||
public:
|
|
||||||
StreamFormatterBase();
|
|
||||||
virtual ~StreamFormatterBase();
|
|
||||||
virtual std::string format( const std::string &statement );
|
|
||||||
};
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------------
|
|
||||||
/// @ingroup IOStreamBase
|
|
||||||
/// @brief This class represents the stream to write out.
|
|
||||||
//-------------------------------------------------------------------------------------------------
|
|
||||||
class DLL_ODDLPARSER_EXPORT IOStreamBase {
|
|
||||||
public:
|
|
||||||
IOStreamBase( StreamFormatterBase *formatter = ddl_nullptr );
|
|
||||||
virtual ~IOStreamBase();
|
|
||||||
virtual bool open( const std::string &anme );
|
|
||||||
virtual bool close();
|
|
||||||
virtual size_t write( const std::string &statement );
|
|
||||||
|
|
||||||
private:
|
|
||||||
StreamFormatterBase *m_formatter;
|
|
||||||
FILE *m_file;
|
|
||||||
};
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
|
|
@ -39,6 +39,16 @@ struct Identifier;
|
||||||
struct Reference;
|
struct Reference;
|
||||||
struct Property;
|
struct Property;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isEmbeddedCommentOpenTag( T *in, T *end ) {
|
||||||
|
if ( in == '/' && in+1 == '*' ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Utility function to search for the next token or the end of the buffer.
|
/// @brief Utility function to search for the next token or the end of the buffer.
|
||||||
/// @param in [in] The start position in the buffer.
|
/// @param in [in] The start position in the buffer.
|
||||||
/// @param end [in] The end position in the buffer.
|
/// @param end [in] The end position in the buffer.
|
||||||
|
@ -47,7 +57,7 @@ struct Property;
|
||||||
template<class T>
|
template<class T>
|
||||||
inline
|
inline
|
||||||
T *lookForNextToken( T *in, T *end ) {
|
T *lookForNextToken( T *in, T *end ) {
|
||||||
while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
|
while( ( in != end ) && ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) ) {
|
||||||
in++;
|
in++;
|
||||||
}
|
}
|
||||||
return in;
|
return in;
|
||||||
|
|
|
@ -84,7 +84,7 @@ static const unsigned char chartype_table[ 256 ] = {
|
||||||
template<class T>
|
template<class T>
|
||||||
inline
|
inline
|
||||||
bool isNumeric( const T in ) {
|
bool isNumeric( const T in ) {
|
||||||
return ( chartype_table[ static_cast<int>( in ) ] == 1 );
|
return ( chartype_table[ static_cast<size_t>( in ) ] == 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -98,7 +98,7 @@ inline
|
||||||
bool isInteger( T *in, T *end ) {
|
bool isInteger( T *in, T *end ) {
|
||||||
if( in != end ) {
|
if( in != end ) {
|
||||||
if( *in == '-' ) {
|
if( *in == '-' ) {
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ bool isInteger( T *in, T *end ) {
|
||||||
if( !result ) {
|
if( !result ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -119,7 +119,7 @@ inline
|
||||||
bool isFloat( T *in, T *end ) {
|
bool isFloat( T *in, T *end ) {
|
||||||
if( in != end ) {
|
if( in != end ) {
|
||||||
if( *in == '-' ) {
|
if( *in == '-' ) {
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,12 +134,12 @@ bool isFloat( T *in, T *end ) {
|
||||||
if( !result ) {
|
if( !result ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for 1<.>0f
|
// check for 1<.>0f
|
||||||
if( *in == '.' ) {
|
if( *in == '.' ) {
|
||||||
in++;
|
++in;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ bool isFloat( T *in, T *end ) {
|
||||||
if( !result ) {
|
if( !result ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -208,7 +208,7 @@ template<class T>
|
||||||
inline
|
inline
|
||||||
static T *getNextSeparator( T *in, T *end ) {
|
static T *getNextSeparator( T *in, T *end ) {
|
||||||
while( !isSeparator( *in ) || in == end ) {
|
while( !isSeparator( *in ) || in == end ) {
|
||||||
in++;
|
++in;
|
||||||
}
|
}
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
@ -250,5 +250,33 @@ bool isComment( T *in, T *end ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isCommentOpenTag(T *in, T *end ) {
|
||||||
|
if (*in == '/') {
|
||||||
|
if (in + 1 != end) {
|
||||||
|
if (*(in + 1) == '*') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool isCommentCloseTag(T *in, T *end) {
|
||||||
|
if (*in == '*') {
|
||||||
|
if (in + 1 != end) {
|
||||||
|
if (*(in + 1) == '/') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
END_ODDLPARSER_NS
|
END_ODDLPARSER_NS
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*-----------------------------------------------------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2015 Kim Kulling
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
-----------------------------------------------------------------------------------------------*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <openddlparser/OpenDDLCommon.h>
|
||||||
|
|
||||||
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
/// @ingroup IOStreamBase
|
||||||
|
/// @brief This class represents the stream to write out.
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
class DLL_ODDLPARSER_EXPORT StreamFormatterBase {
|
||||||
|
public:
|
||||||
|
/// @brief The class constructor.
|
||||||
|
StreamFormatterBase();
|
||||||
|
|
||||||
|
/// @brief The class destructor, virtual.
|
||||||
|
virtual ~StreamFormatterBase();
|
||||||
|
|
||||||
|
/// @brief Will format the sring and return the new formatted result.
|
||||||
|
/// @param statement [in] The string to reformat.
|
||||||
|
/// @return The reformatted result.
|
||||||
|
virtual std::string format(const std::string &statement);
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
/// @ingroup IOStreamBase
|
||||||
|
/// @brief This class represents the stream to write out.
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
class DLL_ODDLPARSER_EXPORT IOStreamBase {
|
||||||
|
public:
|
||||||
|
/// @brief The class constructor with the formatter.
|
||||||
|
/// @param formatter [in] The formatter to use.
|
||||||
|
explicit IOStreamBase(StreamFormatterBase *formatter = ddl_nullptr);
|
||||||
|
|
||||||
|
/// @brief The class destructor, virtual.
|
||||||
|
virtual ~IOStreamBase();
|
||||||
|
|
||||||
|
/// @brief Will open the stream.
|
||||||
|
/// @param name [in] The name for the stream.
|
||||||
|
/// @return true, if the stream was opened successfully, false if not.
|
||||||
|
virtual bool open(const std::string &name);
|
||||||
|
|
||||||
|
/// @brief Will close the stream.
|
||||||
|
/// @return true, if the stream was closed successfully, false if not.
|
||||||
|
virtual bool close();
|
||||||
|
|
||||||
|
/// @brief Returns true, if the stream is open.
|
||||||
|
/// @return true, if the stream is open, false if not.
|
||||||
|
virtual bool isOpen() const;
|
||||||
|
|
||||||
|
/// @brief Will read a string from the stream.
|
||||||
|
/// @param sizeToRead [in] The size to read in bytes.
|
||||||
|
/// @param statement [out] The read statements.
|
||||||
|
/// @return The bytes read from the stream.
|
||||||
|
virtual size_t read( size_t sizeToRead, std::string &statement );
|
||||||
|
|
||||||
|
/// @brief Will write a string into the stream.
|
||||||
|
/// @param statement [in] The string to write.
|
||||||
|
/// @return The bytes written into the stream.
|
||||||
|
virtual size_t write(const std::string &statement);
|
||||||
|
|
||||||
|
private:
|
||||||
|
StreamFormatterBase *m_formatter;
|
||||||
|
FILE *m_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_ODDLPARSER_NS
|
|
@ -28,8 +28,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
BEGIN_ODDLPARSER_NS
|
BEGIN_ODDLPARSER_NS
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
struct ValueAllocator;
|
struct ValueAllocator;
|
||||||
|
|
||||||
|
class IOStreamBase;
|
||||||
|
|
||||||
///------------------------------------------------------------------------------------------------
|
///------------------------------------------------------------------------------------------------
|
||||||
/// @brief This class implements a value.
|
/// @brief This class implements a value.
|
||||||
///
|
///
|
||||||
|
@ -213,7 +216,7 @@ public:
|
||||||
double getDouble() const;
|
double getDouble() const;
|
||||||
|
|
||||||
/// @brief Assigns a std::string to the value.
|
/// @brief Assigns a std::string to the value.
|
||||||
/// @param value [in] The value.
|
/// @param str [in] The value.
|
||||||
void setString( const std::string &str );
|
void setString( const std::string &str );
|
||||||
|
|
||||||
/// @brief Returns the std::string value.
|
/// @brief Returns the std::string value.
|
||||||
|
@ -229,7 +232,8 @@ public:
|
||||||
Reference *getRef() const;
|
Reference *getRef() const;
|
||||||
|
|
||||||
/// @brief Dumps the value.
|
/// @brief Dumps the value.
|
||||||
void dump();
|
/// @param stream [in] The stream to write in.
|
||||||
|
void dump( IOStreamBase &stream );
|
||||||
|
|
||||||
/// @brief Assigns the next value.
|
/// @brief Assigns the next value.
|
||||||
/// @param next [n] The next value.
|
/// @param next [n] The next value.
|
||||||
|
@ -241,7 +245,7 @@ public:
|
||||||
|
|
||||||
/// @brief Gets the length of the array.
|
/// @brief Gets the length of the array.
|
||||||
/// @return The number of items in the array.
|
/// @return The number of items in the array.
|
||||||
size_t size();
|
size_t size() const;
|
||||||
|
|
||||||
ValueType m_type;
|
ValueType m_type;
|
||||||
size_t m_size;
|
size_t m_size;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||||
* http://code.google.com/p/poly2tri/
|
* http://code.google.com/p/poly2tri/
|
||||||
*
|
*
|
||||||
|
@ -88,7 +88,7 @@ void Triangle::Clear()
|
||||||
points_[0]=points_[1]=points_[2] = NULL;
|
points_[0]=points_[1]=points_[2] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Triangle::ClearNeighbor(Triangle *triangle )
|
void Triangle::ClearNeighbor(const Triangle *triangle )
|
||||||
{
|
{
|
||||||
if( neighbors_[0] == triangle )
|
if( neighbors_[0] == triangle )
|
||||||
{
|
{
|
||||||
|
@ -96,14 +96,14 @@ void Triangle::ClearNeighbor(Triangle *triangle )
|
||||||
}
|
}
|
||||||
else if( neighbors_[1] == triangle )
|
else if( neighbors_[1] == triangle )
|
||||||
{
|
{
|
||||||
neighbors_[1] = NULL;
|
neighbors_[1] = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
neighbors_[2] = NULL;
|
neighbors_[2] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Triangle::ClearNeighbors()
|
void Triangle::ClearNeighbors()
|
||||||
{
|
{
|
||||||
neighbors_[0] = NULL;
|
neighbors_[0] = NULL;
|
||||||
|
@ -116,13 +116,9 @@ void Triangle::ClearDelunayEdges()
|
||||||
delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
|
delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point* Triangle::OppositePoint(Triangle& t, Point& p)
|
Point* Triangle::OppositePoint(Triangle& t, const Point& p)
|
||||||
{
|
{
|
||||||
Point *cw = t.PointCW(p);
|
Point *cw = t.PointCW(p);
|
||||||
//double x = cw->x;
|
|
||||||
//double y = cw->y;
|
|
||||||
//x = p.x;
|
|
||||||
//y = p.y;
|
|
||||||
return PointCW(*cw);
|
return PointCW(*cw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,8 +160,7 @@ int Triangle::Index(const Point* p)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
return -1;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
||||||
|
@ -192,7 +187,7 @@ int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Triangle::MarkConstrainedEdge(const int index)
|
void Triangle::MarkConstrainedEdge(int index)
|
||||||
{
|
{
|
||||||
constrained_edge[index] = true;
|
constrained_edge[index] = true;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +210,7 @@ void Triangle::MarkConstrainedEdge(Point* p, Point* q)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The point counter-clockwise to given point
|
// The point counter-clockwise to given point
|
||||||
Point* Triangle::PointCW(Point& point)
|
Point* Triangle::PointCW(const Point& point)
|
||||||
{
|
{
|
||||||
if (&point == points_[0]) {
|
if (&point == points_[0]) {
|
||||||
return points_[2];
|
return points_[2];
|
||||||
|
@ -225,12 +220,11 @@ Point* Triangle::PointCW(Point& point)
|
||||||
return points_[1];
|
return points_[1];
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
return NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The point counter-clockwise to given point
|
// The point counter-clockwise to given point
|
||||||
Point* Triangle::PointCCW(Point& point)
|
Point* Triangle::PointCCW(const Point& point)
|
||||||
{
|
{
|
||||||
if (&point == points_[0]) {
|
if (&point == points_[0]) {
|
||||||
return points_[1];
|
return points_[1];
|
||||||
|
@ -240,12 +234,11 @@ Point* Triangle::PointCCW(Point& point)
|
||||||
return points_[0];
|
return points_[0];
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
return NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The neighbor clockwise to given point
|
// The neighbor clockwise to given point
|
||||||
Triangle* Triangle::NeighborCW(Point& point)
|
Triangle* Triangle::NeighborCW(const Point& point)
|
||||||
{
|
{
|
||||||
if (&point == points_[0]) {
|
if (&point == points_[0]) {
|
||||||
return neighbors_[1];
|
return neighbors_[1];
|
||||||
|
@ -256,7 +249,7 @@ Triangle* Triangle::NeighborCW(Point& point)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The neighbor counter-clockwise to given point
|
// The neighbor counter-clockwise to given point
|
||||||
Triangle* Triangle::NeighborCCW(Point& point)
|
Triangle* Triangle::NeighborCCW(const Point& point)
|
||||||
{
|
{
|
||||||
if (&point == points_[0]) {
|
if (&point == points_[0]) {
|
||||||
return neighbors_[2];
|
return neighbors_[2];
|
||||||
|
@ -266,7 +259,7 @@ Triangle* Triangle::NeighborCCW(Point& point)
|
||||||
return neighbors_[1];
|
return neighbors_[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Triangle::GetConstrainedEdgeCCW(Point& p)
|
bool Triangle::GetConstrainedEdgeCCW(const Point& p)
|
||||||
{
|
{
|
||||||
if (&p == points_[0]) {
|
if (&p == points_[0]) {
|
||||||
return constrained_edge[2];
|
return constrained_edge[2];
|
||||||
|
@ -276,7 +269,7 @@ bool Triangle::GetConstrainedEdgeCCW(Point& p)
|
||||||
return constrained_edge[1];
|
return constrained_edge[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Triangle::GetConstrainedEdgeCW(Point& p)
|
bool Triangle::GetConstrainedEdgeCW(const Point& p)
|
||||||
{
|
{
|
||||||
if (&p == points_[0]) {
|
if (&p == points_[0]) {
|
||||||
return constrained_edge[1];
|
return constrained_edge[1];
|
||||||
|
@ -286,7 +279,7 @@ bool Triangle::GetConstrainedEdgeCW(Point& p)
|
||||||
return constrained_edge[0];
|
return constrained_edge[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Triangle::SetConstrainedEdgeCCW(Point& p, bool ce)
|
void Triangle::SetConstrainedEdgeCCW(const Point& p, bool ce)
|
||||||
{
|
{
|
||||||
if (&p == points_[0]) {
|
if (&p == points_[0]) {
|
||||||
constrained_edge[2] = ce;
|
constrained_edge[2] = ce;
|
||||||
|
@ -297,7 +290,7 @@ void Triangle::SetConstrainedEdgeCCW(Point& p, bool ce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Triangle::SetConstrainedEdgeCW(Point& p, bool ce)
|
void Triangle::SetConstrainedEdgeCW(const Point& p, bool ce)
|
||||||
{
|
{
|
||||||
if (&p == points_[0]) {
|
if (&p == points_[0]) {
|
||||||
constrained_edge[1] = ce;
|
constrained_edge[1] = ce;
|
||||||
|
@ -308,7 +301,7 @@ void Triangle::SetConstrainedEdgeCW(Point& p, bool ce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Triangle::GetDelunayEdgeCCW(Point& p)
|
bool Triangle::GetDelunayEdgeCCW(const Point& p)
|
||||||
{
|
{
|
||||||
if (&p == points_[0]) {
|
if (&p == points_[0]) {
|
||||||
return delaunay_edge[2];
|
return delaunay_edge[2];
|
||||||
|
@ -318,7 +311,7 @@ bool Triangle::GetDelunayEdgeCCW(Point& p)
|
||||||
return delaunay_edge[1];
|
return delaunay_edge[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Triangle::GetDelunayEdgeCW(Point& p)
|
bool Triangle::GetDelunayEdgeCW(const Point& p)
|
||||||
{
|
{
|
||||||
if (&p == points_[0]) {
|
if (&p == points_[0]) {
|
||||||
return delaunay_edge[1];
|
return delaunay_edge[1];
|
||||||
|
@ -328,7 +321,7 @@ bool Triangle::GetDelunayEdgeCW(Point& p)
|
||||||
return delaunay_edge[0];
|
return delaunay_edge[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Triangle::SetDelunayEdgeCCW(Point& p, bool e)
|
void Triangle::SetDelunayEdgeCCW(const Point& p, bool e)
|
||||||
{
|
{
|
||||||
if (&p == points_[0]) {
|
if (&p == points_[0]) {
|
||||||
delaunay_edge[2] = e;
|
delaunay_edge[2] = e;
|
||||||
|
@ -339,7 +332,7 @@ void Triangle::SetDelunayEdgeCCW(Point& p, bool e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Triangle::SetDelunayEdgeCW(Point& p, bool e)
|
void Triangle::SetDelunayEdgeCW(const Point& p, bool e)
|
||||||
{
|
{
|
||||||
if (&p == points_[0]) {
|
if (&p == points_[0]) {
|
||||||
delaunay_edge[1] = e;
|
delaunay_edge[1] = e;
|
||||||
|
@ -351,7 +344,7 @@ void Triangle::SetDelunayEdgeCW(Point& p, bool e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The neighbor across to given point
|
// The neighbor across to given point
|
||||||
Triangle& Triangle::NeighborAcross(Point& opoint)
|
Triangle& Triangle::NeighborAcross(const Point& opoint)
|
||||||
{
|
{
|
||||||
if (&opoint == points_[0]) {
|
if (&opoint == points_[0]) {
|
||||||
return *neighbors_[0];
|
return *neighbors_[0];
|
||||||
|
@ -369,5 +362,4 @@ void Triangle::DebugPrint()
|
||||||
cout << points_[2]->x << "," << points_[2]->y << endl;
|
cout << points_[2]->x << "," << points_[2]->y << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ struct Point {
|
||||||
/// Convert this point into a unit point. Returns the Length.
|
/// Convert this point into a unit point. Returns the Length.
|
||||||
double Normalize()
|
double Normalize()
|
||||||
{
|
{
|
||||||
double len = Length();
|
const double len = Length();
|
||||||
x /= len;
|
x /= len;
|
||||||
y /= len;
|
y /= len;
|
||||||
return len;
|
return len;
|
||||||
|
@ -162,50 +162,50 @@ bool constrained_edge[3];
|
||||||
/// Flags to determine if an edge is a Delauney edge
|
/// Flags to determine if an edge is a Delauney edge
|
||||||
bool delaunay_edge[3];
|
bool delaunay_edge[3];
|
||||||
|
|
||||||
Point* GetPoint(const int& index);
|
Point* GetPoint(int index);
|
||||||
Point* PointCW(Point& point);
|
Point* PointCW(const Point& point);
|
||||||
Point* PointCCW(Point& point);
|
Point* PointCCW(const Point& point);
|
||||||
Point* OppositePoint(Triangle& t, Point& p);
|
Point* OppositePoint(Triangle& t, const Point& p);
|
||||||
|
|
||||||
Triangle* GetNeighbor(const int& index);
|
Triangle* GetNeighbor(int index);
|
||||||
void MarkNeighbor(Point* p1, Point* p2, Triangle* t);
|
void MarkNeighbor(Point* p1, Point* p2, Triangle* t);
|
||||||
void MarkNeighbor(Triangle& t);
|
void MarkNeighbor(Triangle& t);
|
||||||
|
|
||||||
void MarkConstrainedEdge(const int index);
|
void MarkConstrainedEdge(int index);
|
||||||
void MarkConstrainedEdge(Edge& edge);
|
void MarkConstrainedEdge(Edge& edge);
|
||||||
void MarkConstrainedEdge(Point* p, Point* q);
|
void MarkConstrainedEdge(Point* p, Point* q);
|
||||||
|
|
||||||
int Index(const Point* p);
|
int Index(const Point* p);
|
||||||
int EdgeIndex(const Point* p1, const Point* p2);
|
int EdgeIndex(const Point* p1, const Point* p2);
|
||||||
|
|
||||||
Triangle* NeighborCW(Point& point);
|
Triangle* NeighborCW(const Point& point);
|
||||||
Triangle* NeighborCCW(Point& point);
|
Triangle* NeighborCCW(const Point& point);
|
||||||
bool GetConstrainedEdgeCCW(Point& p);
|
bool GetConstrainedEdgeCCW(const Point& p);
|
||||||
bool GetConstrainedEdgeCW(Point& p);
|
bool GetConstrainedEdgeCW(const Point& p);
|
||||||
void SetConstrainedEdgeCCW(Point& p, bool ce);
|
void SetConstrainedEdgeCCW(const Point& p, bool ce);
|
||||||
void SetConstrainedEdgeCW(Point& p, bool ce);
|
void SetConstrainedEdgeCW(const Point& p, bool ce);
|
||||||
bool GetDelunayEdgeCCW(Point& p);
|
bool GetDelunayEdgeCCW(const Point& p);
|
||||||
bool GetDelunayEdgeCW(Point& p);
|
bool GetDelunayEdgeCW(const Point& p);
|
||||||
void SetDelunayEdgeCCW(Point& p, bool e);
|
void SetDelunayEdgeCCW(const Point& p, bool e);
|
||||||
void SetDelunayEdgeCW(Point& p, bool e);
|
void SetDelunayEdgeCW(const Point& p, bool e);
|
||||||
|
|
||||||
bool Contains(Point* p);
|
bool Contains(const Point* p);
|
||||||
bool Contains(const Edge& e);
|
bool Contains(const Edge& e);
|
||||||
bool Contains(Point* p, Point* q);
|
bool Contains(const Point* p, const Point* q);
|
||||||
void Legalize(Point& point);
|
void Legalize(Point& point);
|
||||||
void Legalize(Point& opoint, Point& npoint);
|
void Legalize(Point& opoint, Point& npoint);
|
||||||
/**
|
/**
|
||||||
* Clears all references to all other triangles and points
|
* Clears all references to all other triangles and points
|
||||||
*/
|
*/
|
||||||
void Clear();
|
void Clear();
|
||||||
void ClearNeighbor(Triangle *triangle );
|
void ClearNeighbor(const Triangle *triangle);
|
||||||
void ClearNeighbors();
|
void ClearNeighbors();
|
||||||
void ClearDelunayEdges();
|
void ClearDelunayEdges();
|
||||||
|
|
||||||
inline bool IsInterior();
|
inline bool IsInterior();
|
||||||
inline void IsInterior(bool b);
|
inline void IsInterior(bool b);
|
||||||
|
|
||||||
Triangle& NeighborAcross(Point& opoint);
|
Triangle& NeighborAcross(const Point& opoint);
|
||||||
|
|
||||||
void DebugPrint();
|
void DebugPrint();
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ inline bool operator ==(const Point& a, const Point& b)
|
||||||
|
|
||||||
inline bool operator !=(const Point& a, const Point& b)
|
inline bool operator !=(const Point& a, const Point& b)
|
||||||
{
|
{
|
||||||
return a.x != b.x || a.y != b.y;
|
return !(a.x == b.x) && !(a.y == b.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peform the dot product on two vectors.
|
/// Peform the dot product on two vectors.
|
||||||
|
@ -282,22 +282,22 @@ inline Point Cross(const Point& a, double s)
|
||||||
|
|
||||||
/// Perform the cross product on a scalar and a point. In 2D this produces
|
/// Perform the cross product on a scalar and a point. In 2D this produces
|
||||||
/// a point.
|
/// a point.
|
||||||
inline Point Cross(const double s, const Point& a)
|
inline Point Cross(double s, const Point& a)
|
||||||
{
|
{
|
||||||
return Point(-s * a.y, s * a.x);
|
return Point(-s * a.y, s * a.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Point* Triangle::GetPoint(const int& index)
|
inline Point* Triangle::GetPoint(int index)
|
||||||
{
|
{
|
||||||
return points_[index];
|
return points_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Triangle* Triangle::GetNeighbor(const int& index)
|
inline Triangle* Triangle::GetNeighbor(int index)
|
||||||
{
|
{
|
||||||
return neighbors_[index];
|
return neighbors_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Triangle::Contains(Point* p)
|
inline bool Triangle::Contains(const Point* p)
|
||||||
{
|
{
|
||||||
return p == points_[0] || p == points_[1] || p == points_[2];
|
return p == points_[0] || p == points_[1] || p == points_[2];
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ inline bool Triangle::Contains(const Edge& e)
|
||||||
return Contains(e.p) && Contains(e.q);
|
return Contains(e.p) && Contains(e.q);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Triangle::Contains(Point* p, Point* q)
|
inline bool Triangle::Contains(const Point* p, const Point* q)
|
||||||
{
|
{
|
||||||
return Contains(p) && Contains(q);
|
return Contains(p) && Contains(q);
|
||||||
}
|
}
|
||||||
|
@ -324,6 +324,4 @@ inline void Triangle::IsInterior(bool b)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||||
* http://code.google.com/p/poly2tri/
|
* http://code.google.com/p/poly2tri/
|
||||||
*
|
*
|
||||||
|
@ -28,18 +28,26 @@
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UTILS_H
|
#ifndef UTILS_H
|
||||||
#define UTILS_H
|
#define UTILS_H
|
||||||
|
|
||||||
|
// Otherwise #defines like M_PI are undeclared under Visual Studio
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// C99 removes M_PI from math.h
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846264338327
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace p2t {
|
namespace p2t {
|
||||||
|
|
||||||
const double PI = 3.1415926535897932384626433832795029;
|
const double PI_3div4 = 3 * M_PI / 4;
|
||||||
const double PI_2 = 2 * PI;
|
const double PI_div2 = 1.57079632679489661923;
|
||||||
const double PI_3div4 = 3 * PI / 4;
|
const double EPSILON = 1e-12;
|
||||||
const double EPSILON = 1e-15;
|
|
||||||
|
|
||||||
enum Orientation { CW, CCW, COLLINEAR };
|
enum Orientation { CW, CCW, COLLINEAR };
|
||||||
|
|
||||||
|
@ -53,7 +61,7 @@ enum Orientation { CW, CCW, COLLINEAR };
|
||||||
* = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
|
* = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
Orientation Orient2d(Point& pa, Point& pb, Point& pc)
|
Orientation Orient2d(const Point& pa, const Point& pb, const Point& pc)
|
||||||
{
|
{
|
||||||
double detleft = (pa.x - pc.x) * (pb.y - pc.y);
|
double detleft = (pa.x - pc.x) * (pb.y - pc.y);
|
||||||
double detright = (pa.y - pc.y) * (pb.x - pc.x);
|
double detright = (pa.y - pc.y) * (pb.x - pc.x);
|
||||||
|
@ -66,6 +74,7 @@ Orientation Orient2d(Point& pa, Point& pb, Point& pc)
|
||||||
return CW;
|
return CW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
|
bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
|
||||||
{
|
{
|
||||||
double pdx = pd.x;
|
double pdx = pd.x;
|
||||||
|
@ -97,7 +106,22 @@ bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool InScanArea(const Point& pa, const Point& pb, const Point& pc, const Point& pd)
|
||||||
|
{
|
||||||
|
double oadb = (pa.x - pb.x)*(pd.y - pb.y) - (pd.x - pb.x)*(pa.y - pb.y);
|
||||||
|
if (oadb >= -EPSILON) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double oadc = (pa.x - pc.x)*(pd.y - pc.y) - (pd.x - pc.x)*(pa.y - pc.y);
|
||||||
|
if (oadc <= EPSILON) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||||
* http://code.google.com/p/poly2tri/
|
* http://code.google.com/p/poly2tri/
|
||||||
*
|
*
|
||||||
|
@ -35,5 +35,4 @@
|
||||||
#include "common/shapes.h"
|
#include "common/shapes.h"
|
||||||
#include "sweep/cdt.h"
|
#include "sweep/cdt.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,7 +39,7 @@ AdvancingFront::AdvancingFront(Node& head, Node& tail)
|
||||||
search_node_ = &head;
|
search_node_ = &head;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* AdvancingFront::LocateNode(const double& x)
|
Node* AdvancingFront::LocateNode(double x)
|
||||||
{
|
{
|
||||||
Node* node = search_node_;
|
Node* node = search_node_;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ Node* AdvancingFront::LocateNode(const double& x)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* AdvancingFront::FindSearchNode(const double& x)
|
Node* AdvancingFront::FindSearchNode(double x)
|
||||||
{
|
{
|
||||||
(void)x; // suppress compiler warnings "unused parameter 'x'"
|
(void)x; // suppress compiler warnings "unused parameter 'x'"
|
||||||
// TODO: implement BST index
|
// TODO: implement BST index
|
||||||
|
@ -105,5 +105,4 @@ AdvancingFront::~AdvancingFront()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ Node* search();
|
||||||
void set_search(Node* node);
|
void set_search(Node* node);
|
||||||
|
|
||||||
/// Locate insertion point along advancing front
|
/// Locate insertion point along advancing front
|
||||||
Node* LocateNode(const double& x);
|
Node* LocateNode(double x);
|
||||||
|
|
||||||
Node* LocatePoint(const Point* point);
|
Node* LocatePoint(const Point* point);
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ private:
|
||||||
|
|
||||||
Node* head_, *tail_, *search_node_;
|
Node* head_, *tail_, *search_node_;
|
||||||
|
|
||||||
Node* FindSearchNode(const double& x);
|
Node* FindSearchNode(double x);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Node* AdvancingFront::head()
|
inline Node* AdvancingFront::head()
|
||||||
|
@ -115,4 +115,4 @@ inline void AdvancingFront::set_search(Node* node)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||||
* http://code.google.com/p/poly2tri/
|
* http://code.google.com/p/poly2tri/
|
||||||
*
|
*
|
||||||
|
@ -32,13 +32,13 @@
|
||||||
|
|
||||||
namespace p2t {
|
namespace p2t {
|
||||||
|
|
||||||
CDT::CDT(std::vector<Point*> polyline)
|
CDT::CDT(const std::vector<Point*>& polyline)
|
||||||
{
|
{
|
||||||
sweep_context_ = new SweepContext(polyline);
|
sweep_context_ = new SweepContext(polyline);
|
||||||
sweep_ = new Sweep;
|
sweep_ = new Sweep;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDT::AddHole(std::vector<Point*> polyline)
|
void CDT::AddHole(const std::vector<Point*>& polyline)
|
||||||
{
|
{
|
||||||
sweep_context_->AddHole(polyline);
|
sweep_context_->AddHole(polyline);
|
||||||
}
|
}
|
||||||
|
@ -68,5 +68,4 @@ CDT::~CDT()
|
||||||
delete sweep_;
|
delete sweep_;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||||
* http://code.google.com/p/poly2tri/
|
* http://code.google.com/p/poly2tri/
|
||||||
*
|
*
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CDT_H
|
#ifndef CDT_H
|
||||||
#define CDT_H
|
#define CDT_H
|
||||||
|
|
||||||
|
@ -37,11 +37,11 @@
|
||||||
#include "sweep.h"
|
#include "sweep.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Mason Green <mason.green@gmail.com>
|
* @author Mason Green <mason.green@gmail.com>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace p2t {
|
namespace p2t {
|
||||||
|
|
||||||
class CDT
|
class CDT
|
||||||
|
@ -50,40 +50,40 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor - add polyline with non repeating points
|
* Constructor - add polyline with non repeating points
|
||||||
*
|
*
|
||||||
* @param polyline
|
* @param polyline
|
||||||
*/
|
*/
|
||||||
CDT(std::vector<Point*> polyline);
|
CDT(const std::vector<Point*>& polyline);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor - clean up memory
|
* Destructor - clean up memory
|
||||||
*/
|
*/
|
||||||
~CDT();
|
~CDT();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a hole
|
* Add a hole
|
||||||
*
|
*
|
||||||
* @param polyline
|
* @param polyline
|
||||||
*/
|
*/
|
||||||
void AddHole(std::vector<Point*> polyline);
|
void AddHole(const std::vector<Point*>& polyline);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a steiner point
|
* Add a steiner point
|
||||||
*
|
*
|
||||||
* @param point
|
* @param point
|
||||||
*/
|
*/
|
||||||
void AddPoint(Point* point);
|
void AddPoint(Point* point);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
|
* Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
|
||||||
*/
|
*/
|
||||||
void Triangulate();
|
void Triangulate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get CDT triangles
|
* Get CDT triangles
|
||||||
*/
|
*/
|
||||||
std::vector<Triangle*> GetTriangles();
|
std::vector<Triangle*> GetTriangles();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get triangle map
|
* Get triangle map
|
||||||
*/
|
*/
|
||||||
|
@ -94,7 +94,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Internals
|
* Internals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SweepContext* sweep_context_;
|
SweepContext* sweep_context_;
|
||||||
Sweep* sweep_;
|
Sweep* sweep_;
|
||||||
|
|
||||||
|
@ -102,4 +102,4 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -49,7 +49,7 @@ void Sweep::Triangulate(SweepContext& tcx)
|
||||||
|
|
||||||
void Sweep::SweepPoints(SweepContext& tcx)
|
void Sweep::SweepPoints(SweepContext& tcx)
|
||||||
{
|
{
|
||||||
for (int i = 1; i < tcx.point_count(); i++) {
|
for (size_t i = 1; i < tcx.point_count(); i++) {
|
||||||
Point& point = *tcx.GetPoint(i);
|
Point& point = *tcx.GetPoint(i);
|
||||||
Node* node = &PointEvent(tcx, point);
|
Node* node = &PointEvent(tcx, point);
|
||||||
for (unsigned int i = 0; i < point.edge_list.size(); i++) {
|
for (unsigned int i = 0; i < point.edge_list.size(); i++) {
|
||||||
|
@ -117,7 +117,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
|
||||||
throw std::runtime_error("EdgeEvent - collinear points not supported");
|
throw std::runtime_error("EdgeEvent - collinear points not supported");
|
||||||
if( triangle->Contains(&eq, p1)) {
|
if( triangle->Contains(&eq, p1)) {
|
||||||
triangle->MarkConstrainedEdge(&eq, p1 );
|
triangle->MarkConstrainedEdge(&eq, p1 );
|
||||||
// We are modifying the constraint maybe it would be better to
|
// We are modifying the constraint maybe it would be better to
|
||||||
// not change the given constraint and just keep a variable for the new constraint
|
// not change the given constraint and just keep a variable for the new constraint
|
||||||
tcx.edge_event.constrained_edge->q = p1;
|
tcx.edge_event.constrained_edge->q = p1;
|
||||||
triangle = &triangle->NeighborAcross(point);
|
triangle = &triangle->NeighborAcross(point);
|
||||||
|
@ -137,7 +137,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
|
||||||
|
|
||||||
if( triangle->Contains(&eq, p2)) {
|
if( triangle->Contains(&eq, p2)) {
|
||||||
triangle->MarkConstrainedEdge(&eq, p2 );
|
triangle->MarkConstrainedEdge(&eq, p2 );
|
||||||
// We are modifying the constraint maybe it would be better to
|
// We are modifying the constraint maybe it would be better to
|
||||||
// not change the given constraint and just keep a variable for the new constraint
|
// not change the given constraint and just keep a variable for the new constraint
|
||||||
tcx.edge_event.constrained_edge->q = p2;
|
tcx.edge_event.constrained_edge->q = p2;
|
||||||
triangle = &triangle->NeighborAcross(point);
|
triangle = &triangle->NeighborAcross(point);
|
||||||
|
@ -166,7 +166,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
|
||||||
|
|
||||||
bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq)
|
bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq)
|
||||||
{
|
{
|
||||||
int index = triangle.EdgeIndex(&ep, &eq);
|
const int index = triangle.EdgeIndex(&ep, &eq);
|
||||||
|
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
triangle.MarkConstrainedEdge(index);
|
triangle.MarkConstrainedEdge(index);
|
||||||
|
@ -230,8 +230,8 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
|
||||||
Node* node = n.next;
|
Node* node = n.next;
|
||||||
|
|
||||||
while (node->next) {
|
while (node->next) {
|
||||||
double angle = HoleAngle(*node);
|
// if HoleAngle exceeds 90 degrees then break.
|
||||||
if (angle > PI_2 || angle < -PI_2) break;
|
if (LargeHole_DontFill(node)) break;
|
||||||
Fill(tcx, *node);
|
Fill(tcx, *node);
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
|
@ -240,29 +240,81 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
|
||||||
node = n.prev;
|
node = n.prev;
|
||||||
|
|
||||||
while (node->prev) {
|
while (node->prev) {
|
||||||
double angle = HoleAngle(*node);
|
// if HoleAngle exceeds 90 degrees then break.
|
||||||
if (angle > PI_2 || angle < -PI_2) break;
|
if (LargeHole_DontFill(node)) break;
|
||||||
Fill(tcx, *node);
|
Fill(tcx, *node);
|
||||||
node = node->prev;
|
node = node->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill right basins
|
// Fill right basins
|
||||||
if (n.next && n.next->next) {
|
if (n.next && n.next->next) {
|
||||||
double angle = BasinAngle(n);
|
const double angle = BasinAngle(n);
|
||||||
if (angle < PI_3div4) {
|
if (angle < PI_3div4) {
|
||||||
FillBasin(tcx, n);
|
FillBasin(tcx, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double Sweep::BasinAngle(Node& node)
|
// True if HoleAngle exceeds 90 degrees.
|
||||||
|
bool Sweep::LargeHole_DontFill(const Node* node) const {
|
||||||
|
|
||||||
|
const Node* nextNode = node->next;
|
||||||
|
const Node* prevNode = node->prev;
|
||||||
|
if (!AngleExceeds90Degrees(node->point, nextNode->point, prevNode->point))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check additional points on front.
|
||||||
|
const Node* next2Node = nextNode->next;
|
||||||
|
// "..Plus.." because only want angles on same side as point being added.
|
||||||
|
if ((next2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, next2Node->point, prevNode->point))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const Node* prev2Node = prevNode->prev;
|
||||||
|
// "..Plus.." because only want angles on same side as point being added.
|
||||||
|
if ((prev2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, prev2Node->point))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sweep::AngleExceeds90Degrees(const Point* origin, const Point* pa, const Point* pb) const {
|
||||||
|
const double angle = Angle(origin, pa, pb);
|
||||||
|
return ((angle > PI_div2) || (angle < -PI_div2));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sweep::AngleExceedsPlus90DegreesOrIsNegative(const Point* origin, const Point* pa, const Point* pb) const {
|
||||||
|
const double angle = Angle(origin, pa, pb);
|
||||||
|
return (angle > PI_div2) || (angle < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Sweep::Angle(const Point* origin, const Point* pa, const Point* pb) const {
|
||||||
|
/* Complex plane
|
||||||
|
* ab = cosA +i*sinA
|
||||||
|
* ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
|
||||||
|
* atan2(y,x) computes the principal value of the argument function
|
||||||
|
* applied to the complex number x+iy
|
||||||
|
* Where x = ax*bx + ay*by
|
||||||
|
* y = ax*by - ay*bx
|
||||||
|
*/
|
||||||
|
const double px = origin->x;
|
||||||
|
const double py = origin->y;
|
||||||
|
const double ax = pa->x- px;
|
||||||
|
const double ay = pa->y - py;
|
||||||
|
const double bx = pb->x - px;
|
||||||
|
const double by = pb->y - py;
|
||||||
|
const double x = ax * by - ay * bx;
|
||||||
|
const double y = ax * bx + ay * by;
|
||||||
|
return atan2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Sweep::BasinAngle(const Node& node) const
|
||||||
{
|
{
|
||||||
double ax = node.point->x - node.next->next->point->x;
|
const double ax = node.point->x - node.next->next->point->x;
|
||||||
double ay = node.point->y - node.next->next->point->y;
|
const double ay = node.point->y - node.next->next->point->y;
|
||||||
return atan2(ay, ax);
|
return atan2(ay, ax);
|
||||||
}
|
}
|
||||||
|
|
||||||
double Sweep::HoleAngle(Node& node)
|
double Sweep::HoleAngle(const Node& node) const
|
||||||
{
|
{
|
||||||
/* Complex plane
|
/* Complex plane
|
||||||
* ab = cosA +i*sinA
|
* ab = cosA +i*sinA
|
||||||
|
@ -272,10 +324,10 @@ double Sweep::HoleAngle(Node& node)
|
||||||
* Where x = ax*bx + ay*by
|
* Where x = ax*bx + ay*by
|
||||||
* y = ax*by - ay*bx
|
* y = ax*by - ay*bx
|
||||||
*/
|
*/
|
||||||
double ax = node.next->point->x - node.point->x;
|
const double ax = node.next->point->x - node.point->x;
|
||||||
double ay = node.next->point->y - node.point->y;
|
const double ay = node.next->point->y - node.point->y;
|
||||||
double bx = node.prev->point->x - node.point->x;
|
const double bx = node.prev->point->x - node.point->x;
|
||||||
double by = node.prev->point->y - node.point->y;
|
const double by = node.prev->point->y - node.point->y;
|
||||||
return atan2(ax * by - ay * bx, ax * bx + ay * by);
|
return atan2(ax * by - ay * bx, ax * bx + ay * by);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,43 +392,43 @@ bool Sweep::Legalize(SweepContext& tcx, Triangle& t)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sweep::Incircle(Point& pa, Point& pb, Point& pc, Point& pd)
|
bool Sweep::Incircle(const Point& pa, const Point& pb, const Point& pc, const Point& pd) const
|
||||||
{
|
{
|
||||||
double adx = pa.x - pd.x;
|
const double adx = pa.x - pd.x;
|
||||||
double ady = pa.y - pd.y;
|
const double ady = pa.y - pd.y;
|
||||||
double bdx = pb.x - pd.x;
|
const double bdx = pb.x - pd.x;
|
||||||
double bdy = pb.y - pd.y;
|
const double bdy = pb.y - pd.y;
|
||||||
|
|
||||||
double adxbdy = adx * bdy;
|
const double adxbdy = adx * bdy;
|
||||||
double bdxady = bdx * ady;
|
const double bdxady = bdx * ady;
|
||||||
double oabd = adxbdy - bdxady;
|
const double oabd = adxbdy - bdxady;
|
||||||
|
|
||||||
if (oabd <= 0)
|
if (oabd <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
double cdx = pc.x - pd.x;
|
const double cdx = pc.x - pd.x;
|
||||||
double cdy = pc.y - pd.y;
|
const double cdy = pc.y - pd.y;
|
||||||
|
|
||||||
double cdxady = cdx * ady;
|
const double cdxady = cdx * ady;
|
||||||
double adxcdy = adx * cdy;
|
const double adxcdy = adx * cdy;
|
||||||
double ocad = cdxady - adxcdy;
|
const double ocad = cdxady - adxcdy;
|
||||||
|
|
||||||
if (ocad <= 0)
|
if (ocad <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
double bdxcdy = bdx * cdy;
|
const double bdxcdy = bdx * cdy;
|
||||||
double cdxbdy = cdx * bdy;
|
const double cdxbdy = cdx * bdy;
|
||||||
|
|
||||||
double alift = adx * adx + ady * ady;
|
const double alift = adx * adx + ady * ady;
|
||||||
double blift = bdx * bdx + bdy * bdy;
|
const double blift = bdx * bdx + bdy * bdy;
|
||||||
double clift = cdx * cdx + cdy * cdy;
|
const double clift = cdx * cdx + cdy * cdy;
|
||||||
|
|
||||||
double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
|
const double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
|
||||||
|
|
||||||
return det > 0;
|
return det > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sweep::RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op)
|
void Sweep::RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op) const
|
||||||
{
|
{
|
||||||
Triangle* n1, *n2, *n3, *n4;
|
Triangle* n1, *n2, *n3, *n4;
|
||||||
n1 = t.NeighborCCW(p);
|
n1 = t.NeighborCCW(p);
|
||||||
|
@ -708,11 +760,8 @@ Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op)
|
||||||
} else if (o2d == CCW) {
|
} else if (o2d == CCW) {
|
||||||
// Left
|
// Left
|
||||||
return *ot.PointCW(op);
|
return *ot.PointCW(op);
|
||||||
} else{
|
|
||||||
//throw new RuntimeException("[Unsupported] Opposing point on constrained edge");
|
|
||||||
// ASSIMP_CHANGE (aramis_acg)
|
|
||||||
throw std::runtime_error("[Unsupported] Opposing point on constrained edge");
|
|
||||||
}
|
}
|
||||||
|
throw std::runtime_error("[Unsupported] Opposing point on constrained edge");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle,
|
void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle,
|
||||||
|
@ -740,7 +789,7 @@ void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle&
|
||||||
Sweep::~Sweep() {
|
Sweep::~Sweep() {
|
||||||
|
|
||||||
// Clean up memory
|
// Clean up memory
|
||||||
for(unsigned int i = 0; i < nodes_.size(); i++) {
|
for(size_t i = 0; i < nodes_.size(); i++) {
|
||||||
delete nodes_[i];
|
delete nodes_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
* Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation',
|
* Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation',
|
||||||
* International Journal of Geographical Information Science
|
* International Journal of Geographical Information Science
|
||||||
*
|
*
|
||||||
* "FlipScan" Constrained Edge Algorithm invented by Thomas Åhlén, thahlen@gmail.com
|
* "FlipScan" Constrained Edge Algorithm invented by Thomas ?hl?n, thahlen@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SWEEP_H
|
#ifndef SWEEP_H
|
||||||
|
@ -49,17 +49,17 @@ struct Point;
|
||||||
struct Edge;
|
struct Edge;
|
||||||
class Triangle;
|
class Triangle;
|
||||||
|
|
||||||
class Sweep
|
class Sweep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triangulate
|
* Triangulate
|
||||||
*
|
*
|
||||||
* @param tcx
|
* @param tcx
|
||||||
*/
|
*/
|
||||||
void Triangulate(SweepContext& tcx);
|
void Triangulate(SweepContext& tcx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor - clean up memory
|
* Destructor - clean up memory
|
||||||
*/
|
*/
|
||||||
|
@ -69,7 +69,7 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start sweeping the Y-sorted point set from bottom to top
|
* Start sweeping the Y-sorted point set from bottom to top
|
||||||
*
|
*
|
||||||
* @param tcx
|
* @param tcx
|
||||||
*/
|
*/
|
||||||
void SweepPoints(SweepContext& tcx);
|
void SweepPoints(SweepContext& tcx);
|
||||||
|
@ -86,8 +86,8 @@ private:
|
||||||
Node& PointEvent(SweepContext& tcx, Point& point);
|
Node& PointEvent(SweepContext& tcx, Point& point);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param tcx
|
* @param tcx
|
||||||
* @param edge
|
* @param edge
|
||||||
* @param node
|
* @param node
|
||||||
|
@ -98,7 +98,7 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new front triangle and legalize it
|
* Creates a new front triangle and legalize it
|
||||||
*
|
*
|
||||||
* @param tcx
|
* @param tcx
|
||||||
* @param point
|
* @param point
|
||||||
* @param node
|
* @param node
|
||||||
|
@ -142,7 +142,7 @@ private:
|
||||||
* @param d - point opposite a
|
* @param d - point opposite a
|
||||||
* @return true if d is inside circle, false if on circle edge
|
* @return true if d is inside circle, false if on circle edge
|
||||||
*/
|
*/
|
||||||
bool Incircle(Point& pa, Point& pb, Point& pc, Point& pd);
|
bool Incircle(const Point& pa, const Point& pb, const Point& pc, const Point& pd) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotates a triangle pair one vertex CW
|
* Rotates a triangle pair one vertex CW
|
||||||
|
@ -158,7 +158,7 @@ private:
|
||||||
* n4 n4
|
* n4 n4
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
void RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op);
|
void RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills holes in the Advancing Front
|
* Fills holes in the Advancing Front
|
||||||
|
@ -169,17 +169,24 @@ private:
|
||||||
*/
|
*/
|
||||||
void FillAdvancingFront(SweepContext& tcx, Node& n);
|
void FillAdvancingFront(SweepContext& tcx, Node& n);
|
||||||
|
|
||||||
|
// Decision-making about when to Fill hole.
|
||||||
|
// Contributed by ToolmakerSteve2
|
||||||
|
bool LargeHole_DontFill(const Node* node) const;
|
||||||
|
bool AngleExceeds90Degrees(const Point* origin, const Point* pa, const Point* pb) const;
|
||||||
|
bool AngleExceedsPlus90DegreesOrIsNegative(const Point* origin, const Point* pa, const Point* pb) const;
|
||||||
|
double Angle(const Point* origin, const Point* pa, const Point* pb) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param node - middle node
|
* @param node - middle node
|
||||||
* @return the angle between 3 front nodes
|
* @return the angle between 3 front nodes
|
||||||
*/
|
*/
|
||||||
double HoleAngle(Node& node);
|
double HoleAngle(const Node& node) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The basin angle is decided against the horizontal line [1,0]
|
* The basin angle is decided against the horizontal line [1,0]
|
||||||
*/
|
*/
|
||||||
double BasinAngle(Node& node);
|
double BasinAngle(const Node& node) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills a basin that has formed on the Advancing Front to the right
|
* Fills a basin that has formed on the Advancing Front to the right
|
||||||
|
@ -228,22 +235,22 @@ private:
|
||||||
/**
|
/**
|
||||||
* After a flip we have two triangles and know that only one will still be
|
* After a flip we have two triangles and know that only one will still be
|
||||||
* intersecting the edge. So decide which to contiune with and legalize the other
|
* intersecting the edge. So decide which to contiune with and legalize the other
|
||||||
*
|
*
|
||||||
* @param tcx
|
* @param tcx
|
||||||
* @param o - should be the result of an orient2d( eq, op, ep )
|
* @param o - should be the result of an orient2d( eq, op, ep )
|
||||||
* @param t - triangle 1
|
* @param t - triangle 1
|
||||||
* @param ot - triangle 2
|
* @param ot - triangle 2
|
||||||
* @param p - a point shared by both triangles
|
* @param p - a point shared by both triangles
|
||||||
* @param op - another point shared by both triangles
|
* @param op - another point shared by both triangles
|
||||||
* @return returns the triangle still intersecting the edge
|
* @return returns the triangle still intersecting the edge
|
||||||
*/
|
*/
|
||||||
Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op);
|
Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When we need to traverse from one triangle to the next we need
|
* When we need to traverse from one triangle to the next we need
|
||||||
* the point in current triangle that is the opposite point to the next
|
* the point in current triangle that is the opposite point to the next
|
||||||
* triangle.
|
* triangle.
|
||||||
*
|
*
|
||||||
* @param ep
|
* @param ep
|
||||||
* @param eq
|
* @param eq
|
||||||
* @param ot
|
* @param ot
|
||||||
|
@ -254,10 +261,10 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan part of the FlipScan algorithm<br>
|
* Scan part of the FlipScan algorithm<br>
|
||||||
* When a triangle pair isn't flippable we will scan for the next
|
* When a triangle pair isn't flippable we will scan for the next
|
||||||
* point that is inside the flip triangle scan area. When found
|
* point that is inside the flip triangle scan area. When found
|
||||||
* we generate a new flipEdgeEvent
|
* we generate a new flipEdgeEvent
|
||||||
*
|
*
|
||||||
* @param tcx
|
* @param tcx
|
||||||
* @param ep - last point on the edge we are traversing
|
* @param ep - last point on the edge we are traversing
|
||||||
* @param eq - first point on the edge we are traversing
|
* @param eq - first point on the edge we are traversing
|
||||||
|
@ -275,4 +282,4 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -34,17 +34,18 @@
|
||||||
|
|
||||||
namespace p2t {
|
namespace p2t {
|
||||||
|
|
||||||
SweepContext::SweepContext(std::vector<Point*> polyline)
|
SweepContext::SweepContext(const std::vector<Point*>& polyline) : points_(polyline),
|
||||||
|
front_(0),
|
||||||
|
head_(0),
|
||||||
|
tail_(0),
|
||||||
|
af_head_(0),
|
||||||
|
af_middle_(0),
|
||||||
|
af_tail_(0)
|
||||||
{
|
{
|
||||||
basin = Basin();
|
|
||||||
edge_event = EdgeEvent();
|
|
||||||
|
|
||||||
points_ = polyline;
|
|
||||||
|
|
||||||
InitEdges(points_);
|
InitEdges(points_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SweepContext::AddHole(std::vector<Point*> polyline)
|
void SweepContext::AddHole(const std::vector<Point*>& polyline)
|
||||||
{
|
{
|
||||||
InitEdges(polyline);
|
InitEdges(polyline);
|
||||||
for(unsigned int i = 0; i < polyline.size(); i++) {
|
for(unsigned int i = 0; i < polyline.size(); i++) {
|
||||||
|
@ -56,12 +57,12 @@ void SweepContext::AddPoint(Point* point) {
|
||||||
points_.push_back(point);
|
points_.push_back(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Triangle*> SweepContext::GetTriangles()
|
std::vector<Triangle*> &SweepContext::GetTriangles()
|
||||||
{
|
{
|
||||||
return triangles_;
|
return triangles_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<Triangle*> SweepContext::GetMap()
|
std::list<Triangle*> &SweepContext::GetMap()
|
||||||
{
|
{
|
||||||
return map_;
|
return map_;
|
||||||
}
|
}
|
||||||
|
@ -94,16 +95,16 @@ void SweepContext::InitTriangulation()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SweepContext::InitEdges(std::vector<Point*> polyline)
|
void SweepContext::InitEdges(const std::vector<Point*>& polyline)
|
||||||
{
|
{
|
||||||
int num_points = static_cast<int>(polyline.size());
|
size_t num_points = polyline.size();
|
||||||
for (int i = 0; i < num_points; i++) {
|
for (size_t i = 0; i < num_points; i++) {
|
||||||
int j = i < num_points - 1 ? i + 1 : 0;
|
size_t j = i < num_points - 1 ? i + 1 : 0;
|
||||||
edge_list.push_back(new Edge(*polyline[i], *polyline[j]));
|
edge_list.push_back(new Edge(*polyline[i], *polyline[j]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Point* SweepContext::GetPoint(const int& index)
|
Point* SweepContext::GetPoint(size_t index)
|
||||||
{
|
{
|
||||||
return points_[index];
|
return points_[index];
|
||||||
}
|
}
|
||||||
|
@ -113,13 +114,13 @@ void SweepContext::AddToMap(Triangle* triangle)
|
||||||
map_.push_back(triangle);
|
map_.push_back(triangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node& SweepContext::LocateNode(Point& point)
|
Node& SweepContext::LocateNode(const Point& point)
|
||||||
{
|
{
|
||||||
// TODO implement search tree
|
// TODO implement search tree
|
||||||
return *front_->LocateNode(point.x);
|
return *front_->LocateNode(point.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SweepContext::CreateAdvancingFront(std::vector<Node*> nodes)
|
void SweepContext::CreateAdvancingFront(const std::vector<Node*>& nodes)
|
||||||
{
|
{
|
||||||
|
|
||||||
(void) nodes;
|
(void) nodes;
|
||||||
|
@ -164,12 +165,20 @@ void SweepContext::RemoveFromMap(Triangle* triangle)
|
||||||
|
|
||||||
void SweepContext::MeshClean(Triangle& triangle)
|
void SweepContext::MeshClean(Triangle& triangle)
|
||||||
{
|
{
|
||||||
if (!triangle.IsInterior()) {
|
std::vector<Triangle *> triangles;
|
||||||
triangle.IsInterior(true);
|
triangles.push_back(&triangle);
|
||||||
triangles_.push_back(&triangle);
|
|
||||||
for (int i = 0; i < 3; i++) {
|
while(!triangles.empty()){
|
||||||
if (!triangle.constrained_edge[i])
|
Triangle *t = triangles.back();
|
||||||
MeshClean(*triangle.GetNeighbor(i));
|
triangles.pop_back();
|
||||||
|
|
||||||
|
if (t != NULL && !t->IsInterior()) {
|
||||||
|
t->IsInterior(true);
|
||||||
|
triangles_.push_back(t);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (!t->constrained_edge[i])
|
||||||
|
triangles.push_back(t->GetNeighbor(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,47 +52,47 @@ class SweepContext {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
SweepContext(std::vector<Point*> polyline);
|
SweepContext(const std::vector<Point*>& polyline);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~SweepContext();
|
~SweepContext();
|
||||||
|
|
||||||
void set_head(Point* p1);
|
void set_head(Point* p1);
|
||||||
|
|
||||||
Point* head();
|
Point* head() const;
|
||||||
|
|
||||||
void set_tail(Point* p1);
|
void set_tail(Point* p1);
|
||||||
|
|
||||||
Point* tail();
|
Point* tail() const;
|
||||||
|
|
||||||
int point_count();
|
size_t point_count() const;
|
||||||
|
|
||||||
Node& LocateNode(Point& point);
|
Node& LocateNode(const Point& point);
|
||||||
|
|
||||||
void RemoveNode(Node* node);
|
void RemoveNode(Node* node);
|
||||||
|
|
||||||
void CreateAdvancingFront(std::vector<Node*> nodes);
|
void CreateAdvancingFront(const std::vector<Node*>& nodes);
|
||||||
|
|
||||||
/// Try to map a node to all sides of this triangle that don't have a neighbor
|
/// Try to map a node to all sides of this triangle that don't have a neighbor
|
||||||
void MapTriangleToNodes(Triangle& t);
|
void MapTriangleToNodes(Triangle& t);
|
||||||
|
|
||||||
void AddToMap(Triangle* triangle);
|
void AddToMap(Triangle* triangle);
|
||||||
|
|
||||||
Point* GetPoint(const int& index);
|
Point* GetPoint(size_t index);
|
||||||
|
|
||||||
Point* GetPoints();
|
Point* GetPoints();
|
||||||
|
|
||||||
void RemoveFromMap(Triangle* triangle);
|
void RemoveFromMap(Triangle* triangle);
|
||||||
|
|
||||||
void AddHole(std::vector<Point*> polyline);
|
void AddHole(const std::vector<Point*>& polyline);
|
||||||
|
|
||||||
void AddPoint(Point* point);
|
void AddPoint(Point* point);
|
||||||
|
|
||||||
AdvancingFront* front();
|
AdvancingFront* front() const;
|
||||||
|
|
||||||
void MeshClean(Triangle& triangle);
|
void MeshClean(Triangle& triangle);
|
||||||
|
|
||||||
std::vector<Triangle*> GetTriangles();
|
std::vector<Triangle*> &GetTriangles();
|
||||||
std::list<Triangle*> GetMap();
|
std::list<Triangle*> &GetMap();
|
||||||
|
|
||||||
std::vector<Edge*> edge_list;
|
std::vector<Edge*> edge_list;
|
||||||
|
|
||||||
|
@ -147,18 +147,18 @@ Point* tail_;
|
||||||
Node *af_head_, *af_middle_, *af_tail_;
|
Node *af_head_, *af_middle_, *af_tail_;
|
||||||
|
|
||||||
void InitTriangulation();
|
void InitTriangulation();
|
||||||
void InitEdges(std::vector<Point*> polyline);
|
void InitEdges(const std::vector<Point*>& polyline);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline AdvancingFront* SweepContext::front()
|
inline AdvancingFront* SweepContext::front() const
|
||||||
{
|
{
|
||||||
return front_;
|
return front_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int SweepContext::point_count()
|
inline size_t SweepContext::point_count() const
|
||||||
{
|
{
|
||||||
return static_cast<int>(points_.size());
|
return points_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SweepContext::set_head(Point* p1)
|
inline void SweepContext::set_head(Point* p1)
|
||||||
|
@ -166,7 +166,7 @@ inline void SweepContext::set_head(Point* p1)
|
||||||
head_ = p1;
|
head_ = p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Point* SweepContext::head()
|
inline Point* SweepContext::head() const
|
||||||
{
|
{
|
||||||
return head_;
|
return head_;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ inline void SweepContext::set_tail(Point* p1)
|
||||||
tail_ = p1;
|
tail_ = p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Point* SweepContext::tail()
|
inline Point* SweepContext::tail() const
|
||||||
{
|
{
|
||||||
return tail_;
|
return tail_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
utf8 cpp library
|
||||||
|
Release 2.3.4
|
||||||
|
|
||||||
|
A minor bug fix release. Thanks to all who reported bugs.
|
||||||
|
|
||||||
|
Note: Version 2.3.3 contained a regression, and therefore was removed.
|
||||||
|
|
||||||
|
Changes from version 2.3.2
|
||||||
|
- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
|
||||||
|
- Bug fix [36]: replace_invalid() only works with back_inserter
|
||||||
|
|
||||||
|
Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "utf8/checked.h"
|
||||||
|
#include "utf8/unchecked.h"
|
||||||
|
|
||||||
|
#endif // header guard
|
|
@ -0,0 +1,327 @@
|
||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
// Base for the exceptions that may be thrown from the library
|
||||||
|
class exception : public ::std::exception {
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exceptions that may be thrown from the library functions.
|
||||||
|
class invalid_code_point : public exception {
|
||||||
|
uint32_t cp;
|
||||||
|
public:
|
||||||
|
invalid_code_point(uint32_t cp) : cp(cp) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid code point"; }
|
||||||
|
uint32_t code_point() const {return cp;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class invalid_utf8 : public exception {
|
||||||
|
uint8_t u8;
|
||||||
|
public:
|
||||||
|
invalid_utf8 (uint8_t u) : u8(u) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid UTF-8"; }
|
||||||
|
uint8_t utf8_octet() const {return u8;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class invalid_utf16 : public exception {
|
||||||
|
uint16_t u16;
|
||||||
|
public:
|
||||||
|
invalid_utf16 (uint16_t u) : u16(u) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid UTF-16"; }
|
||||||
|
uint16_t utf16_word() const {return u16;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class not_enough_room : public exception {
|
||||||
|
public:
|
||||||
|
virtual const char* what() const throw() { return "Not enough space"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The library API - functions intended to be called by the users
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||||
|
{
|
||||||
|
if (!utf8::internal::is_code_point_valid(cp))
|
||||||
|
throw invalid_code_point(cp);
|
||||||
|
|
||||||
|
if (cp < 0x80) // one octet
|
||||||
|
*(result++) = static_cast<uint8_t>(cp);
|
||||||
|
else if (cp < 0x800) { // two octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) { // three octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else { // four octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename output_iterator>
|
||||||
|
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
octet_iterator sequence_start = start;
|
||||||
|
internal::utf_error err_code = utf8::internal::validate_next(start, end);
|
||||||
|
switch (err_code) {
|
||||||
|
case internal::UTF8_OK :
|
||||||
|
for (octet_iterator it = sequence_start; it != start; ++it)
|
||||||
|
*out++ = *it;
|
||||||
|
break;
|
||||||
|
case internal::NOT_ENOUGH_ROOM:
|
||||||
|
throw not_enough_room();
|
||||||
|
case internal::INVALID_LEAD:
|
||||||
|
out = utf8::append (replacement, out);
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
case internal::INCOMPLETE_SEQUENCE:
|
||||||
|
case internal::OVERLONG_SEQUENCE:
|
||||||
|
case internal::INVALID_CODE_POINT:
|
||||||
|
out = utf8::append (replacement, out);
|
||||||
|
++start;
|
||||||
|
// just one replacement mark for the sequence
|
||||||
|
while (start != end && utf8::internal::is_trail(*start))
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename output_iterator>
|
||||||
|
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
|
||||||
|
{
|
||||||
|
static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
|
||||||
|
return utf8::replace_invalid(start, end, out, replacement_marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t next(octet_iterator& it, octet_iterator end)
|
||||||
|
{
|
||||||
|
uint32_t cp = 0;
|
||||||
|
internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
|
||||||
|
switch (err_code) {
|
||||||
|
case internal::UTF8_OK :
|
||||||
|
break;
|
||||||
|
case internal::NOT_ENOUGH_ROOM :
|
||||||
|
throw not_enough_room();
|
||||||
|
case internal::INVALID_LEAD :
|
||||||
|
case internal::INCOMPLETE_SEQUENCE :
|
||||||
|
case internal::OVERLONG_SEQUENCE :
|
||||||
|
throw invalid_utf8(*it);
|
||||||
|
case internal::INVALID_CODE_POINT :
|
||||||
|
throw invalid_code_point(cp);
|
||||||
|
}
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t peek_next(octet_iterator it, octet_iterator end)
|
||||||
|
{
|
||||||
|
return utf8::next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t prior(octet_iterator& it, octet_iterator start)
|
||||||
|
{
|
||||||
|
// can't do much if it == start
|
||||||
|
if (it == start)
|
||||||
|
throw not_enough_room();
|
||||||
|
|
||||||
|
octet_iterator end = it;
|
||||||
|
// Go back until we hit either a lead octet or start
|
||||||
|
while (utf8::internal::is_trail(*(--it)))
|
||||||
|
if (it == start)
|
||||||
|
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||||
|
return utf8::peek_next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deprecated in versions that include "prior"
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t previous(octet_iterator& it, octet_iterator pass_start)
|
||||||
|
{
|
||||||
|
octet_iterator end = it;
|
||||||
|
while (utf8::internal::is_trail(*(--it)))
|
||||||
|
if (it == pass_start)
|
||||||
|
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::next(temp, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename distance_type>
|
||||||
|
void advance (octet_iterator& it, distance_type n, octet_iterator end)
|
||||||
|
{
|
||||||
|
for (distance_type i = 0; i < n; ++i)
|
||||||
|
utf8::next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
distance (octet_iterator first, octet_iterator last)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||||
|
for (dist = 0; first < last; ++dist)
|
||||||
|
utf8::next(first, last);
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::internal::mask16(*start++);
|
||||||
|
// Take care of surrogate pairs first
|
||||||
|
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||||
|
if (start != end) {
|
||||||
|
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||||
|
if (utf8::internal::is_trail_surrogate(trail_surrogate))
|
||||||
|
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||||
|
else
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||||
|
|
||||||
|
}
|
||||||
|
// Lone trail surrogate
|
||||||
|
else if (utf8::internal::is_trail_surrogate(cp))
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||||
|
|
||||||
|
result = utf8::append(cp, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::next(start, end);
|
||||||
|
if (cp > 0xffff) { //make a surrogate pair
|
||||||
|
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||||
|
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*result++ = static_cast<uint16_t>(cp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
result = utf8::append(*(start++), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
(*result++) = utf8::next(start, end);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The iterator class
|
||||||
|
template <typename octet_iterator>
|
||||||
|
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||||
|
octet_iterator it;
|
||||||
|
octet_iterator range_start;
|
||||||
|
octet_iterator range_end;
|
||||||
|
public:
|
||||||
|
iterator () {}
|
||||||
|
explicit iterator (const octet_iterator& octet_it,
|
||||||
|
const octet_iterator& range_start,
|
||||||
|
const octet_iterator& range_end) :
|
||||||
|
it(octet_it), range_start(range_start), range_end(range_end)
|
||||||
|
{
|
||||||
|
if (it < range_start || it > range_end)
|
||||||
|
throw std::out_of_range("Invalid utf-8 iterator position");
|
||||||
|
}
|
||||||
|
// the default "big three" are OK
|
||||||
|
octet_iterator base () const { return it; }
|
||||||
|
uint32_t operator * () const
|
||||||
|
{
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::next(temp, range_end);
|
||||||
|
}
|
||||||
|
bool operator == (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
if (range_start != rhs.range_start || range_end != rhs.range_end)
|
||||||
|
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
|
||||||
|
return (it == rhs.it);
|
||||||
|
}
|
||||||
|
bool operator != (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return !(operator == (rhs));
|
||||||
|
}
|
||||||
|
iterator& operator ++ ()
|
||||||
|
{
|
||||||
|
utf8::next(it, range_end);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator ++ (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::next(it, range_end);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
iterator& operator -- ()
|
||||||
|
{
|
||||||
|
utf8::prior(it, range_start);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator -- (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::prior(it, range_start);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}; // class iterator
|
||||||
|
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
#endif //header guard
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,329 @@
|
||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
// The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
|
||||||
|
// You may need to change them to match your system.
|
||||||
|
// These typedefs have the same names as ones from cstdint, or boost/cstdint
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
|
||||||
|
// Helper code - not intended to be directly called by the library users. May be changed at any time
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
// Unicode constants
|
||||||
|
// Leading (high) surrogates: 0xd800 - 0xdbff
|
||||||
|
// Trailing (low) surrogates: 0xdc00 - 0xdfff
|
||||||
|
const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
|
||||||
|
const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
|
||||||
|
const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
|
||||||
|
const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
|
||||||
|
const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
|
||||||
|
const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
|
||||||
|
|
||||||
|
// Maximum valid value for a Unicode code point
|
||||||
|
const uint32_t CODE_POINT_MAX = 0x0010ffffu;
|
||||||
|
|
||||||
|
template<typename octet_type>
|
||||||
|
inline uint8_t mask8(octet_type oc)
|
||||||
|
{
|
||||||
|
return static_cast<uint8_t>(0xff & oc);
|
||||||
|
}
|
||||||
|
template<typename u16_type>
|
||||||
|
inline uint16_t mask16(u16_type oc)
|
||||||
|
{
|
||||||
|
return static_cast<uint16_t>(0xffff & oc);
|
||||||
|
}
|
||||||
|
template<typename octet_type>
|
||||||
|
inline bool is_trail(octet_type oc)
|
||||||
|
{
|
||||||
|
return ((utf8::internal::mask8(oc) >> 6) == 0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_lead_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_trail_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u32>
|
||||||
|
inline bool is_code_point_valid(u32 cp)
|
||||||
|
{
|
||||||
|
return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
sequence_length(octet_iterator lead_it)
|
||||||
|
{
|
||||||
|
uint8_t lead = utf8::internal::mask8(*lead_it);
|
||||||
|
if (lead < 0x80)
|
||||||
|
return 1;
|
||||||
|
else if ((lead >> 5) == 0x6)
|
||||||
|
return 2;
|
||||||
|
else if ((lead >> 4) == 0xe)
|
||||||
|
return 3;
|
||||||
|
else if ((lead >> 3) == 0x1e)
|
||||||
|
return 4;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_difference_type>
|
||||||
|
inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
|
||||||
|
{
|
||||||
|
if (cp < 0x80) {
|
||||||
|
if (length != 1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (cp < 0x800) {
|
||||||
|
if (length != 2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) {
|
||||||
|
if (length != 3)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
|
||||||
|
|
||||||
|
/// Helper for get_sequence_x
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error increase_safely(octet_iterator& it, octet_iterator end)
|
||||||
|
{
|
||||||
|
if (++it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
if (!utf8::internal::is_trail(*it))
|
||||||
|
return INCOMPLETE_SEQUENCE;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
|
||||||
|
|
||||||
|
/// get_sequence_x functions decode utf-8 sequences of the length x
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (*it) & 0x3f;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (*it) & 0x3f;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
// Save the original value of it so we can go back in case of failure
|
||||||
|
// Of course, it does not make much sense with i.e. stream iterators
|
||||||
|
octet_iterator original_it = it;
|
||||||
|
|
||||||
|
uint32_t cp = 0;
|
||||||
|
// Determine the sequence length based on the lead octet
|
||||||
|
typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
|
||||||
|
const octet_difference_type length = utf8::internal::sequence_length(it);
|
||||||
|
|
||||||
|
// Get trail octets and calculate the code point
|
||||||
|
utf_error err = UTF8_OK;
|
||||||
|
switch (length) {
|
||||||
|
case 0:
|
||||||
|
return INVALID_LEAD;
|
||||||
|
case 1:
|
||||||
|
err = utf8::internal::get_sequence_1(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
err = utf8::internal::get_sequence_2(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
err = utf8::internal::get_sequence_3(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
err = utf8::internal::get_sequence_4(it, end, cp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == UTF8_OK) {
|
||||||
|
// Decoding succeeded. Now, security checks...
|
||||||
|
if (utf8::internal::is_code_point_valid(cp)) {
|
||||||
|
if (!utf8::internal::is_overlong_sequence(cp, length)){
|
||||||
|
// Passed! Return here.
|
||||||
|
code_point = cp;
|
||||||
|
++it;
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = OVERLONG_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = INVALID_CODE_POINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failure branch - restore the original value of the iterator
|
||||||
|
it = original_it;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
|
||||||
|
uint32_t ignored;
|
||||||
|
return utf8::internal::validate_next(it, end, ignored);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/// The library API - functions intended to be called by the users
|
||||||
|
|
||||||
|
// Byte order mark
|
||||||
|
const uint8_t bom[] = {0xef, 0xbb, 0xbf};
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator find_invalid(octet_iterator start, octet_iterator end)
|
||||||
|
{
|
||||||
|
octet_iterator result = start;
|
||||||
|
while (result != end) {
|
||||||
|
utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
|
||||||
|
if (err_code != internal::UTF8_OK)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool is_valid(octet_iterator start, octet_iterator end)
|
||||||
|
{
|
||||||
|
return (utf8::find_invalid(start, end) == end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool starts_with_bom (octet_iterator it, octet_iterator end)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
|
||||||
|
((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
|
||||||
|
((it != end) && (utf8::internal::mask8(*it)) == bom[2])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Deprecated in release 2.3
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool is_bom (octet_iterator it)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(utf8::internal::mask8(*it++)) == bom[0] &&
|
||||||
|
(utf8::internal::mask8(*it++)) == bom[1] &&
|
||||||
|
(utf8::internal::mask8(*it)) == bom[2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
namespace unchecked
|
||||||
|
{
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||||
|
{
|
||||||
|
if (cp < 0x80) // one octet
|
||||||
|
*(result++) = static_cast<uint8_t>(cp);
|
||||||
|
else if (cp < 0x800) { // two octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) { // three octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else { // four octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t next(octet_iterator& it)
|
||||||
|
{
|
||||||
|
uint32_t cp = utf8::internal::mask8(*it);
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
it++;
|
||||||
|
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
++it;
|
||||||
|
cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||||
|
++it;
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
++it;
|
||||||
|
cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||||
|
++it;
|
||||||
|
cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||||
|
++it;
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t peek_next(octet_iterator it)
|
||||||
|
{
|
||||||
|
return utf8::unchecked::next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t prior(octet_iterator& it)
|
||||||
|
{
|
||||||
|
while (utf8::internal::is_trail(*(--it))) ;
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::unchecked::next(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline uint32_t previous(octet_iterator& it)
|
||||||
|
{
|
||||||
|
return utf8::unchecked::prior(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename distance_type>
|
||||||
|
void advance (octet_iterator& it, distance_type n)
|
||||||
|
{
|
||||||
|
for (distance_type i = 0; i < n; ++i)
|
||||||
|
utf8::unchecked::next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
distance (octet_iterator first, octet_iterator last)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||||
|
for (dist = 0; first < last; ++dist)
|
||||||
|
utf8::unchecked::next(first);
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::internal::mask16(*start++);
|
||||||
|
// Take care of surrogate pairs first
|
||||||
|
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||||
|
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||||
|
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||||
|
}
|
||||||
|
result = utf8::unchecked::append(cp, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start < end) {
|
||||||
|
uint32_t cp = utf8::unchecked::next(start);
|
||||||
|
if (cp > 0xffff) { //make a surrogate pair
|
||||||
|
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||||
|
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*result++ = static_cast<uint16_t>(cp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
result = utf8::unchecked::append(*(start++), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start < end)
|
||||||
|
(*result++) = utf8::unchecked::next(start);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The iterator class
|
||||||
|
template <typename octet_iterator>
|
||||||
|
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||||
|
octet_iterator it;
|
||||||
|
public:
|
||||||
|
iterator () {}
|
||||||
|
explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
|
||||||
|
// the default "big three" are OK
|
||||||
|
octet_iterator base () const { return it; }
|
||||||
|
uint32_t operator * () const
|
||||||
|
{
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::unchecked::next(temp);
|
||||||
|
}
|
||||||
|
bool operator == (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return (it == rhs.it);
|
||||||
|
}
|
||||||
|
bool operator != (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return !(operator == (rhs));
|
||||||
|
}
|
||||||
|
iterator& operator ++ ()
|
||||||
|
{
|
||||||
|
::std::advance(it, utf8::internal::sequence_length(it));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator ++ (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
::std::advance(it, utf8::internal::sequence_length(it));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
iterator& operator -- ()
|
||||||
|
{
|
||||||
|
utf8::unchecked::prior(it);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator -- (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::unchecked::prior(it);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}; // class iterator
|
||||||
|
|
||||||
|
} // namespace utf8::unchecked
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
|
|
|
@ -143,7 +143,6 @@ struct NodeAttachmentInfo
|
||||||
*/
|
*/
|
||||||
#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10
|
#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10
|
||||||
|
|
||||||
|
|
||||||
typedef std::pair<aiBone*,unsigned int> BoneSrcIndex;
|
typedef std::pair<aiBone*,unsigned int> BoneSrcIndex;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -153,7 +152,6 @@ struct BoneWithHash : public std::pair<uint32_t,aiString*> {
|
||||||
std::vector<BoneSrcIndex> pSrcBones;
|
std::vector<BoneSrcIndex> pSrcBones;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief Utility for SceneCombiner
|
/** @brief Utility for SceneCombiner
|
||||||
*/
|
*/
|
|
@ -77,7 +77,6 @@ AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f)
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <typename TReal>
|
template <typename TReal>
|
||||||
AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
|
AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
|
||||||
//return *(&r + i);
|
|
||||||
switch ( i ) {
|
switch ( i ) {
|
||||||
case 0:
|
case 0:
|
||||||
return r;
|
return r;
|
||||||
|
@ -93,7 +92,6 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <typename TReal>
|
template <typename TReal>
|
||||||
AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
|
AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
|
||||||
// return *(&r + i);
|
|
||||||
switch ( i ) {
|
switch ( i ) {
|
||||||
case 0:
|
case 0:
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -48,6 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_MATERIAL_INL_INC
|
#ifndef AI_MATERIAL_INL_INC
|
||||||
#define AI_MATERIAL_INL_INC
|
#define AI_MATERIAL_INL_INC
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiPropertyTypeInfo ai_real_to_property_type_info(float)
|
||||||
|
{
|
||||||
|
return aiPTI_Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
|
||||||
|
{
|
||||||
|
return aiPTI_Double;
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
//! @cond never
|
//! @cond never
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -223,7 +235,7 @@ inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
|
||||||
{
|
{
|
||||||
return AddBinaryProperty((const void*)pInput,
|
return AddBinaryProperty((const void*)pInput,
|
||||||
pNumValues * sizeof(aiUVTransform),
|
pNumValues * sizeof(aiUVTransform),
|
||||||
pKey,type,index,aiPTI_Float); //TODO could be Double ...
|
pKey,type,index,ai_real_to_property_type_info(pInput->mRotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -235,7 +247,7 @@ inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
|
||||||
{
|
{
|
||||||
return AddBinaryProperty((const void*)pInput,
|
return AddBinaryProperty((const void*)pInput,
|
||||||
pNumValues * sizeof(aiColor4D),
|
pNumValues * sizeof(aiColor4D),
|
||||||
pKey,type,index,aiPTI_Float); //TODO could be Double ...
|
pKey,type,index,ai_real_to_property_type_info(pInput->a));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -247,7 +259,7 @@ inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
|
||||||
{
|
{
|
||||||
return AddBinaryProperty((const void*)pInput,
|
return AddBinaryProperty((const void*)pInput,
|
||||||
pNumValues * sizeof(aiColor3D),
|
pNumValues * sizeof(aiColor3D),
|
||||||
pKey,type,index,aiPTI_Float); //TODO could be Double ...
|
pKey,type,index,ai_real_to_property_type_info(pInput->b));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -259,7 +271,7 @@ inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
|
||||||
{
|
{
|
||||||
return AddBinaryProperty((const void*)pInput,
|
return AddBinaryProperty((const void*)pInput,
|
||||||
pNumValues * sizeof(aiVector3D),
|
pNumValues * sizeof(aiVector3D),
|
||||||
pKey,type,index,aiPTI_Float); //TODO could be Double ...
|
pKey,type,index,ai_real_to_property_type_info(pInput->x));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -224,7 +224,7 @@ public:
|
||||||
* @return Reference to the output matrix
|
* @return Reference to the output matrix
|
||||||
*/
|
*/
|
||||||
static aiMatrix4x4t& Rotation(TReal a, const aiVector3t<TReal>& axis,
|
static aiMatrix4x4t& Rotation(TReal a, const aiVector3t<TReal>& axis,
|
||||||
aiMatrix4x4t& out);
|
aiMatrix4x4t& out);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Returns a translation matrix
|
/** @brief Returns a translation matrix
|
||||||
|
@ -232,7 +232,8 @@ public:
|
||||||
* @param out Receives the output matrix
|
* @param out Receives the output matrix
|
||||||
* @return Reference to the output matrix
|
* @return Reference to the output matrix
|
||||||
*/
|
*/
|
||||||
static aiMatrix4x4t& Translation( const aiVector3t<TReal>& v, aiMatrix4x4t& out);
|
static aiMatrix4x4t& Translation( const aiVector3t<TReal>& v,
|
||||||
|
aiMatrix4x4t& out);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Returns a scaling matrix
|
/** @brief Returns a scaling matrix
|
||||||
|
@ -252,7 +253,7 @@ public:
|
||||||
* Journal of Graphics Tools, 4(4):1-4, 1999
|
* Journal of Graphics Tools, 4(4):1-4, 1999
|
||||||
*/
|
*/
|
||||||
static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from,
|
static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from,
|
||||||
const aiVector3t<TReal>& to, aiMatrix4x4t& out);
|
const aiVector3t<TReal>& to, aiMatrix4x4t& out);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TReal a1, a2, a3, a4;
|
TReal a1, a2, a3, a4;
|
||||||
|
|
|
@ -8,7 +8,6 @@ import os
|
||||||
import ctypes
|
import ctypes
|
||||||
from ctypes import POINTER
|
from ctypes import POINTER
|
||||||
import operator
|
import operator
|
||||||
import sys
|
|
||||||
|
|
||||||
try: import numpy
|
try: import numpy
|
||||||
except: numpy = None
|
except: numpy = None
|
||||||
|
@ -40,9 +39,7 @@ elif os.name=='nt':
|
||||||
for dir_candidate in path_dirs:
|
for dir_candidate in path_dirs:
|
||||||
if 'assimp' in dir_candidate.lower():
|
if 'assimp' in dir_candidate.lower():
|
||||||
additional_dirs.append(dir_candidate)
|
additional_dirs.append(dir_candidate)
|
||||||
|
|
||||||
additional_dirs += sys.path
|
|
||||||
|
|
||||||
#print(additional_dirs)
|
#print(additional_dirs)
|
||||||
def vec2tuple(x):
|
def vec2tuple(x):
|
||||||
""" Converts a VECTOR3D to a Tuple """
|
""" Converts a VECTOR3D to a Tuple """
|
||||||
|
|
|
@ -9,7 +9,5 @@ setup(name='pyassimp',
|
||||||
url='https://github.com/assimp/assimp',
|
url='https://github.com/assimp/assimp',
|
||||||
packages=['pyassimp'],
|
packages=['pyassimp'],
|
||||||
data_files=[('share/pyassimp', ['README.md']),
|
data_files=[('share/pyassimp', ['README.md']),
|
||||||
('share/examples/pyassimp', ['scripts/' + f for f in os.listdir('scripts/')]),
|
('share/examples/pyassimp', ['scripts/' + f for f in os.listdir('scripts/')])], requires=['numpy']
|
||||||
('lib/', [f for f in os.listdir('../../lib') if os.path.isfile(f)])],
|
|
||||||
requires=['numpy']
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|

|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26228.9
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleTexturedDirectx11", "SimpleTexturedDirectx11\SimpleTexturedDirectx11.vcxproj", "{E3B160B5-E71F-4F3F-9310-B8F156F736D8}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E3B160B5-E71F-4F3F-9310-B8F156F736D8}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{E3B160B5-E71F-4F3F-9310-B8F156F736D8}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{E3B160B5-E71F-4F3F-9310-B8F156F736D8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{E3B160B5-E71F-4F3F-9310-B8F156F736D8}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{E3B160B5-E71F-4F3F-9310-B8F156F736D8}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{E3B160B5-E71F-4F3F-9310-B8F156F736D8}.Release|x64.Build.0 = Release|x64
|
||||||
|
{E3B160B5-E71F-4F3F-9310-B8F156F736D8}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{E3B160B5-E71F-4F3F-9310-B8F156F736D8}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,102 @@
|
||||||
|
#ifndef MESH_H
|
||||||
|
#define MESH_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <d3d11_1.h>
|
||||||
|
#include <DirectXMath.h>
|
||||||
|
using namespace DirectX;
|
||||||
|
|
||||||
|
struct VERTEX {
|
||||||
|
FLOAT X, Y, Z;
|
||||||
|
XMFLOAT2 texcoord;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Texture {
|
||||||
|
string type;
|
||||||
|
string path;
|
||||||
|
ID3D11ShaderResourceView *texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Mesh {
|
||||||
|
public:
|
||||||
|
vector<VERTEX> vertices;
|
||||||
|
vector<UINT> indices;
|
||||||
|
vector<Texture> textures;
|
||||||
|
ID3D11Device *dev;
|
||||||
|
|
||||||
|
Mesh(ID3D11Device *dev, vector<VERTEX> vertices, vector<UINT> indices, vector<Texture> textures)
|
||||||
|
{
|
||||||
|
this->vertices = vertices;
|
||||||
|
this->indices = indices;
|
||||||
|
this->textures = textures;
|
||||||
|
|
||||||
|
this->dev = dev;
|
||||||
|
|
||||||
|
this->setupMesh(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Draw(ID3D11DeviceContext *devcon)
|
||||||
|
{
|
||||||
|
UINT stride = sizeof(VERTEX);
|
||||||
|
UINT offset = 0;
|
||||||
|
|
||||||
|
devcon->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
|
||||||
|
devcon->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
|
||||||
|
devcon->PSSetShaderResources(0, 1, &textures[0].texture);
|
||||||
|
|
||||||
|
devcon->DrawIndexed(indices.size(), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Close()
|
||||||
|
{
|
||||||
|
VertexBuffer->Release();
|
||||||
|
IndexBuffer->Release();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
/* Render data */
|
||||||
|
ID3D11Buffer *VertexBuffer, *IndexBuffer;
|
||||||
|
|
||||||
|
/* Functions */
|
||||||
|
// Initializes all the buffer objects/arrays
|
||||||
|
bool setupMesh(ID3D11Device *dev)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
D3D11_BUFFER_DESC vbd;
|
||||||
|
vbd.Usage = D3D11_USAGE_IMMUTABLE;
|
||||||
|
vbd.ByteWidth = sizeof(VERTEX) * vertices.size();
|
||||||
|
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
vbd.CPUAccessFlags = 0;
|
||||||
|
vbd.MiscFlags = 0;
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA initData;
|
||||||
|
initData.pSysMem = &vertices[0];
|
||||||
|
|
||||||
|
hr = dev->CreateBuffer(&vbd, &initData, &VertexBuffer);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
D3D11_BUFFER_DESC ibd;
|
||||||
|
ibd.Usage = D3D11_USAGE_IMMUTABLE;
|
||||||
|
ibd.ByteWidth = sizeof(UINT) * indices.size();
|
||||||
|
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
|
ibd.CPUAccessFlags = 0;
|
||||||
|
ibd.MiscFlags = 0;
|
||||||
|
|
||||||
|
initData.pSysMem = &indices[0];
|
||||||
|
|
||||||
|
hr = dev->CreateBuffer(&ibd, &initData, &IndexBuffer);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,205 @@
|
||||||
|
#include "ModelLoader.h"
|
||||||
|
|
||||||
|
ModelLoader::ModelLoader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModelLoader::~ModelLoader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devcon, std::string filename)
|
||||||
|
{
|
||||||
|
Assimp::Importer importer;
|
||||||
|
|
||||||
|
const aiScene* pScene = importer.ReadFile(filename,
|
||||||
|
aiProcess_Triangulate |
|
||||||
|
aiProcess_ConvertToLeftHanded);
|
||||||
|
|
||||||
|
if (pScene == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this->directory = filename.substr(0, filename.find_last_of('/'));
|
||||||
|
|
||||||
|
this->dev = dev;
|
||||||
|
this->hwnd = hwnd;
|
||||||
|
|
||||||
|
processNode(pScene->mRootNode, pScene);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelLoader::Draw(ID3D11DeviceContext * devcon)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < meshes.size(); i++)
|
||||||
|
{
|
||||||
|
meshes[i].Draw(devcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string textype;
|
||||||
|
|
||||||
|
Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene)
|
||||||
|
{
|
||||||
|
// Data to fill
|
||||||
|
vector<VERTEX> vertices;
|
||||||
|
vector<UINT> indices;
|
||||||
|
vector<Texture> textures;
|
||||||
|
|
||||||
|
if (mesh->mMaterialIndex >= 0)
|
||||||
|
{
|
||||||
|
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
|
||||||
|
|
||||||
|
if (textype.empty()) textype = determineTextureType(scene, mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk through each of the mesh's vertices
|
||||||
|
for (UINT i = 0; i < mesh->mNumVertices; i++)
|
||||||
|
{
|
||||||
|
VERTEX vertex;
|
||||||
|
|
||||||
|
vertex.X = mesh->mVertices[i].x;
|
||||||
|
vertex.Y = mesh->mVertices[i].y;
|
||||||
|
vertex.Z = mesh->mVertices[i].z;
|
||||||
|
|
||||||
|
if (mesh->mTextureCoords[0])
|
||||||
|
{
|
||||||
|
vertex.texcoord.x = (float)mesh->mTextureCoords[0][i].x;
|
||||||
|
vertex.texcoord.y = (float)mesh->mTextureCoords[0][i].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UINT i = 0; i < mesh->mNumFaces; i++)
|
||||||
|
{
|
||||||
|
aiFace face = mesh->mFaces[i];
|
||||||
|
|
||||||
|
for (UINT j = 0; j < face.mNumIndices; j++)
|
||||||
|
indices.push_back(face.mIndices[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh->mMaterialIndex >= 0)
|
||||||
|
{
|
||||||
|
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||||
|
|
||||||
|
vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse", scene);
|
||||||
|
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Mesh(dev, vertices, indices, textures);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureType type, string typeName, const aiScene * scene)
|
||||||
|
{
|
||||||
|
vector<Texture> textures;
|
||||||
|
for (UINT i = 0; i < mat->GetTextureCount(type); i++)
|
||||||
|
{
|
||||||
|
aiString str;
|
||||||
|
mat->GetTexture(type, i, &str);
|
||||||
|
// Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture
|
||||||
|
bool skip = false;
|
||||||
|
for (UINT j = 0; j < textures_loaded.size(); j++)
|
||||||
|
{
|
||||||
|
if (std::strcmp(textures_loaded[j].path.c_str(), str.C_Str()) == 0)
|
||||||
|
{
|
||||||
|
textures.push_back(textures_loaded[j]);
|
||||||
|
skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!skip)
|
||||||
|
{ // If texture hasn't been loaded already, load it
|
||||||
|
HRESULT hr;
|
||||||
|
Texture texture;
|
||||||
|
if (textype == "embedded compressed texture")
|
||||||
|
{
|
||||||
|
int textureindex = getTextureIndex(&str);
|
||||||
|
texture.texture = getTextureFromModel(scene, textureindex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string filename = string(str.C_Str());
|
||||||
|
filename = directory + '/' + filename;
|
||||||
|
wstring filenamews = wstring(filename.begin(), filename.end());
|
||||||
|
hr = CreateWICTextureFromFile(dev, devcon, filenamews.c_str(), nullptr, &texture.texture);
|
||||||
|
if (FAILED(hr))
|
||||||
|
MessageBox(hwnd, "Texture couldn't be loaded", "Error!", MB_ICONERROR | MB_OK);
|
||||||
|
}
|
||||||
|
texture.type = typeName;
|
||||||
|
texture.path = str.C_Str();
|
||||||
|
textures.push_back(texture);
|
||||||
|
this->textures_loaded.push_back(texture); // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelLoader::Close()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < meshes.size(); i++)
|
||||||
|
{
|
||||||
|
meshes[i].Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelLoader::processNode(aiNode * node, const aiScene * scene)
|
||||||
|
{
|
||||||
|
for (UINT i = 0; i < node->mNumMeshes; i++)
|
||||||
|
{
|
||||||
|
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
||||||
|
meshes.push_back(this->processMesh(mesh, scene));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UINT i = 0; i < node->mNumChildren; i++)
|
||||||
|
{
|
||||||
|
this->processNode(node->mChildren[i], scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat)
|
||||||
|
{
|
||||||
|
aiString textypeStr;
|
||||||
|
mat->GetTexture(aiTextureType_DIFFUSE, 0, &textypeStr);
|
||||||
|
string textypeteststr = textypeStr.C_Str();
|
||||||
|
if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5")
|
||||||
|
{
|
||||||
|
if (scene->mTextures[0]->mHeight == 0)
|
||||||
|
{
|
||||||
|
return "embedded compressed texture";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "embedded non-compressed texture";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (textypeteststr.find('.') != string::npos)
|
||||||
|
{
|
||||||
|
return "textures are on disk";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModelLoader::getTextureIndex(aiString * str)
|
||||||
|
{
|
||||||
|
string tistr;
|
||||||
|
tistr = str->C_Str();
|
||||||
|
tistr = tistr.substr(1);
|
||||||
|
return stoi(tistr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
ID3D11ShaderResourceView *texture;
|
||||||
|
|
||||||
|
int* size = reinterpret_cast<int*>(&scene->mTextures[textureindex]->mWidth);
|
||||||
|
|
||||||
|
hr = CreateWICTextureFromMemory(dev, devcon, reinterpret_cast<unsigned char*>(scene->mTextures[textureindex]->pcData), *size, nullptr, &texture);
|
||||||
|
if (FAILED(hr))
|
||||||
|
MessageBox(hwnd, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue