Merge branch 'master' into coverity_scan
commit
e6cfe6b5c8
|
@ -5,7 +5,8 @@ function generate()
|
|||
|
||||
if [ $ANDROID ]; then
|
||||
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
||||
else
|
||||
fi
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
generate \
|
||||
&& make -j4 \
|
||||
&& sudo make install \
|
||||
|
|
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:
|
||||
global:
|
||||
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install cmake
|
||||
- echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
|
||||
|
||||
language: cpp
|
||||
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
|
||||
matrix:
|
||||
- LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON
|
||||
- LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF
|
||||
- LINUX=1 SHARED_BUILD=ON ENABLE_COVERALLS=OFF
|
||||
- LINUX=1 SHARED_BUILD=OFF ENABLE_COVERALLS=OFF
|
||||
#exclude:
|
||||
# - os: linux
|
||||
# compiler: clang
|
||||
# - os: osx
|
||||
# compiler: gcc
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
before_script:
|
||||
cmake .
|
||||
# init coverage to 0 (optional)
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --zerocounters ; fi
|
||||
|
||||
script:
|
||||
make
|
||||
- export COVERALLS_SERVICE_NAME=travis-ci
|
||||
- export COVERALLS_REPO_TOKEN=abc12345
|
||||
- . ./.travis.sh
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
after_success:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --capture --output-file coverage.info && lcov --remove coverage.info '/usr/*' 'contrib/*' 'test/*' --output-file coverage.info && lcov --list coverage.info && coveralls-lcov --source-encoding=ISO-8859-1 --repo-token=${COVERALLS_TOKEN} coverage.info ; fi
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
|
|
|
@ -89,6 +89,10 @@ OPTION ( BUILD_DOCS
|
|||
OFF
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
add_definitions( -DWIN32_LEAN_AND_MEAN )
|
||||
endif()
|
||||
|
||||
IF(MSVC)
|
||||
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
||||
OPTION( ASSIMP_INSTALL_PDB
|
||||
|
@ -141,6 +145,13 @@ IF(ASSIMP_DOUBLE_PRECISION)
|
|||
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
||||
ENDIF(ASSIMP_DOUBLE_PRECISION)
|
||||
|
||||
# Check for OpenMP support
|
||||
find_package(OpenMP)
|
||||
if (OPENMP_FOUND)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
||||
|
@ -157,7 +168,7 @@ include_directories(
|
|||
${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
)
|
||||
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" )
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" )
|
||||
SET(LIBASSIMP_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}" )
|
||||
SET(LIBASSIMP-DEV_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}-dev" )
|
||||
SET(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
|
||||
|
@ -178,7 +189,7 @@ ENDIF( UNIX )
|
|||
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
||||
# hide all not-exported symbols
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -std=c++0x")
|
||||
SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -fPIC)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
||||
ELSEIF(MSVC)
|
||||
# enable multi-core compilation with MSVC
|
||||
|
|
16
Readme.md
16
Readme.md
|
@ -1,6 +1,6 @@
|
|||
Open Asset Import Library (assimp)
|
||||
==================================
|
||||
|
||||
### Current build status ###
|
||||
[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
|
||||
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
|
||||
<a href="https://scan.coverity.com/projects/5607">
|
||||
|
@ -9,22 +9,19 @@ Open Asset Import Library (assimp)
|
|||
</a>
|
||||
<span class="badge-patreon"><a href="https://www.patreon.com/assimp" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
|
||||
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
|
||||
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
<br>
|
||||
|
||||
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
||||
|
||||
Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
||||
|
||||
This is the development trunk containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories.
|
||||
The current build status is:
|
||||
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
|
||||
|
||||
Gitter chat: [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
||||
|
||||
And we also have an IRC-channel at freenode: #assetimporterlib . You can easily join us via: [KiwiIRC/freenote](https://kiwiirc.com/client/irc.freenode.net), choose your nickname and type
|
||||
> /join #assetimporterlib
|
||||
One-off donations via PayPal:
|
||||
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
|
||||
|
||||
<br>
|
||||
__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
|
||||
|
||||
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
||||
|
||||
|
@ -100,6 +97,9 @@ Take a look into the `INSTALL` file. Our build system is CMake, if you used CMak
|
|||
* [Pascal](port/AssimpPascal/Readme.md)
|
||||
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
|
||||
|
||||
### Other tools ###
|
||||
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
||||
|
||||
#### Repository structure ####
|
||||
Open Asset Import Library is implemented in C++. The directory structure is:
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "3DSExporter.h"
|
||||
#include "3DSLoader.h"
|
||||
#include "3DSHelper.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "SplitLargeMeshes.h"
|
||||
#include "StringComparison.h"
|
||||
#include <assimp/IOSystem.hpp>
|
||||
|
|
|
@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "AMFImporter.hpp"
|
||||
|
||||
// Header files, Assimp.
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "StandardShapes.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
|
|
|
@ -66,8 +66,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
using namespace Assimp;
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
// underlying structure for aiPropertyStore
|
||||
typedef BatchLoader::PropertyMap PropertyMap;
|
||||
|
||||
|
@ -110,12 +109,11 @@ static std::mutex gLogStreamMutex;
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Custom LogStream implementation for the C-API
|
||||
class LogToCallbackRedirector : public LogStream
|
||||
{
|
||||
class LogToCallbackRedirector : public LogStream {
|
||||
public:
|
||||
explicit LogToCallbackRedirector(const aiLogStream& s)
|
||||
: stream (s) {
|
||||
ai_assert(NULL != s.callback);
|
||||
: stream (s) {
|
||||
ai_assert(NULL != s.callback);
|
||||
}
|
||||
|
||||
~LogToCallbackRedirector() {
|
||||
|
@ -146,8 +144,7 @@ private:
|
|||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReportSceneNotFoundError()
|
||||
{
|
||||
void ReportSceneNotFoundError() {
|
||||
DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
|
||||
"The C-API does not accept scenes produced by the C++ API and vice versa");
|
||||
|
||||
|
@ -156,22 +153,18 @@ void ReportSceneNotFoundError()
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the given file and returns its content.
|
||||
const aiScene* aiImportFile( const char* pFile, unsigned int pFlags)
|
||||
{
|
||||
const aiScene* aiImportFile( const char* pFile, unsigned int pFlags) {
|
||||
return aiImportFileEx(pFile,pFlags,NULL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS)
|
||||
{
|
||||
const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS) {
|
||||
return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
|
||||
aiFileIO* pFS,
|
||||
const aiPropertyStore* props)
|
||||
{
|
||||
const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
|
||||
aiFileIO* pFS, const aiPropertyStore* props) {
|
||||
ai_assert(NULL != pFile);
|
||||
|
||||
const aiScene* scene = NULL;
|
||||
|
@ -190,7 +183,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
|
|||
pimpl->mMatrixProperties = pp->matrices;
|
||||
}
|
||||
// setup a custom IO system if necessary
|
||||
if (pFS) {
|
||||
if (pFS) {
|
||||
imp->SetIOHandler( new CIOSystemWrapper (pFS) );
|
||||
}
|
||||
|
||||
|
@ -201,8 +194,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
|
|||
if( scene) {
|
||||
ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
||||
priv->mOrigImporter = imp;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// if failed, extract error code and destroy the import
|
||||
gLastErrorString = imp->GetErrorString();
|
||||
delete imp;
|
||||
|
@ -210,6 +202,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
|
|||
|
||||
// return imported data. If the import failed the pointer is NULL anyways
|
||||
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,8 +45,9 @@ Assimp C export interface. See Exporter.cpp for some notes.
|
|||
*/
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
|
||||
#include "CInterfaceIOWrapper.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "ScenePrivate.h"
|
||||
#include <assimp/Exporter.hpp>
|
||||
|
||||
|
|
|
@ -303,24 +303,13 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
|||
return false;
|
||||
}
|
||||
|
||||
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReportResult(ConversionResult res)
|
||||
{
|
||||
if(res == sourceExhausted) {
|
||||
DefaultLogger::get()->error("Source ends with incomplete character sequence, transformation to UTF-8 fails");
|
||||
}
|
||||
else if(res == sourceIllegal) {
|
||||
DefaultLogger::get()->error("Source contains illegal character sequence, transformation to UTF-8 fails");
|
||||
}
|
||||
}
|
||||
#include "../contrib/utf8cpp/source/utf8.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert to UTF8 data
|
||||
void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||
{
|
||||
ConversionResult result;
|
||||
//ConversionResult result;
|
||||
if(data.size() < 8) {
|
||||
throw DeadlyImportError("File is too small");
|
||||
}
|
||||
|
@ -333,7 +322,8 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
|||
data.resize(data.size()-3);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// UTF 32 BE with BOM
|
||||
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
|
||||
|
||||
|
@ -347,21 +337,10 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
|||
if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
|
||||
DefaultLogger::get()->debug("Found UTF-32 BOM ...");
|
||||
|
||||
const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
|
||||
char* dstart,*dend;
|
||||
std::vector<char> output;
|
||||
do {
|
||||
output.resize(output.size()?output.size()*3/2:data.size()/2);
|
||||
dstart = &output.front(),dend = &output.back()+1;
|
||||
|
||||
result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
|
||||
} while(result == targetExhausted);
|
||||
|
||||
ReportResult(result);
|
||||
|
||||
// copy to output buffer.
|
||||
const size_t outlen = (size_t)(dstart-&output.front());
|
||||
data.assign(output.begin(),output.begin()+outlen);
|
||||
int *ptr = (int*)&data[ 0 ];
|
||||
int *end = ptr + ( data.size() / sizeof(int) ) +1;
|
||||
utf8::utf32to8( ptr, end, back_inserter(output));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -378,21 +357,9 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
|||
if(*((uint16_t*)&data.front()) == 0xFEFF) {
|
||||
DefaultLogger::get()->debug("Found UTF-16 BOM ...");
|
||||
|
||||
const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
|
||||
char* dstart,*dend;
|
||||
std::vector<char> output;
|
||||
do {
|
||||
output.resize(output.size()?output.size()*3/2:data.size()*3/4);
|
||||
dstart = &output.front(),dend = &output.back()+1;
|
||||
|
||||
result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
|
||||
} while(result == targetExhausted);
|
||||
|
||||
ReportResult(result);
|
||||
|
||||
// copy to output buffer.
|
||||
const size_t outlen = (size_t)(dstart-&output.front());
|
||||
data.assign(output.begin(),output.begin()+outlen);
|
||||
std::vector<unsigned char> output;
|
||||
int16_t *ptr = (int16_t*) &data[ 0 ];
|
||||
utf8::utf16to8(data.begin(), data.end(), back_inserter(output));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,6 @@ class BaseProcess;
|
|||
class SharedPostProcessInfo;
|
||||
class IOStream;
|
||||
|
||||
|
||||
// utility to do char4 to uint32 in a portable manner
|
||||
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
||||
(string[1] << 16) + (string[2] << 8) + string[3]))
|
||||
|
@ -194,14 +193,11 @@ public:
|
|||
const Importer* pImp
|
||||
);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Called by #Importer::GetImporterInfo to get a description of
|
||||
* some loader features. Importers must provide this information. */
|
||||
virtual const aiImporterDesc* GetInfo() const = 0;
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Called by #Importer::GetExtensionList for each loaded importer.
|
||||
* Take the extension list contained in the structure returned by
|
||||
|
@ -317,7 +313,7 @@ public: // static utilities
|
|||
* @param Size of one token, in bytes. Maximally 16 bytes.
|
||||
* @return true if one of the given tokens was found
|
||||
*
|
||||
* @note For convinence, the check is also performed for the
|
||||
* @note For convenience, the check is also performed for the
|
||||
* byte-swapped variant of all tokens (big endian). Only for
|
||||
* tokens of size 2,4.
|
||||
*/
|
||||
|
|
|
@ -43,10 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
* @brief Implementation of some blender modifiers (i.e subdivision, mirror).
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||
|
||||
#include "BlenderModifier.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "Subdivision.h"
|
||||
#include <assimp/scene.h>
|
||||
#include <memory>
|
||||
|
|
|
@ -96,6 +96,7 @@ SET( PUBLIC_HEADERS
|
|||
${HEADER_PATH}/Exporter.hpp
|
||||
${HEADER_PATH}/DefaultIOStream.h
|
||||
${HEADER_PATH}/DefaultIOSystem.h
|
||||
${HEADER_PATH}/SceneCombiner.h
|
||||
)
|
||||
|
||||
SET( Core_SRCS
|
||||
|
@ -148,7 +149,6 @@ SET( Common_SRCS
|
|||
SpatialSort.cpp
|
||||
SpatialSort.h
|
||||
SceneCombiner.cpp
|
||||
SceneCombiner.h
|
||||
ScenePreprocessor.cpp
|
||||
ScenePreprocessor.h
|
||||
SkeletonMeshBuilder.cpp
|
||||
|
@ -695,11 +695,6 @@ SET( Extra_SRCS
|
|||
)
|
||||
SOURCE_GROUP( Extra FILES ${Extra_SRCS})
|
||||
|
||||
SET( ConvertUTF_SRCS
|
||||
../contrib/ConvertUTF/ConvertUTF.h
|
||||
../contrib/ConvertUTF/ConvertUTF.c
|
||||
)
|
||||
SOURCE_GROUP( ConvertUTF FILES ${ConvertUTF_SRCS})
|
||||
|
||||
SET( Clipper_SRCS
|
||||
../contrib/clipper/clipper.hpp
|
||||
|
@ -737,10 +732,12 @@ SET ( openddl_parser_SRCS
|
|||
../contrib/openddlparser/code/OpenDDLCommon.cpp
|
||||
../contrib/openddlparser/code/OpenDDLExport.cpp
|
||||
../contrib/openddlparser/code/Value.cpp
|
||||
../contrib/openddlparser/code/OpenDDLStream.cpp
|
||||
../contrib/openddlparser/include/openddlparser/OpenDDLParser.h
|
||||
../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
|
||||
../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
|
||||
../contrib/openddlparser/include/openddlparser/OpenDDLExport.h
|
||||
../contrib/openddlparser/include/openddlparser/OpenDDLStream.h
|
||||
../contrib/openddlparser/include/openddlparser/DDLNode.h
|
||||
../contrib/openddlparser/include/openddlparser/Value.h
|
||||
)
|
||||
|
@ -835,7 +832,6 @@ SET( assimp_src
|
|||
|
||||
# Third-party libraries
|
||||
${IrrXML_SRCS}
|
||||
${ConvertUTF_SRCS}
|
||||
${unzip_compile_SRCS}
|
||||
${Poly2Tri_SRCS}
|
||||
${Clipper_SRCS}
|
||||
|
|
|
@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "ColladaExporter.h"
|
||||
#include "Bitmap.h"
|
||||
#include "fast_atof.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "StringUtils.h"
|
||||
#include "XMLTools.h"
|
||||
#include <assimp/DefaultIOSystem.h>
|
||||
|
|
|
@ -1726,6 +1726,8 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
|
|||
aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
|
||||
const Collada::Effect& pEffect, const std::string& pName)
|
||||
{
|
||||
aiString result;
|
||||
|
||||
// recurse through the param references until we end up at an image
|
||||
std::string name = pName;
|
||||
while( 1)
|
||||
|
@ -1744,11 +1746,17 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
|
|||
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
|
||||
if( imIt == pParser.mImageLibrary.end())
|
||||
{
|
||||
throw DeadlyImportError( format() <<
|
||||
"Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
|
||||
}
|
||||
//missing texture should not stop the conversion
|
||||
//throw DeadlyImportError( format() <<
|
||||
// "Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
|
||||
|
||||
aiString result;
|
||||
DefaultLogger::get()->warn("Collada: Unable to resolve effect texture entry \"" + pName + "\", ended up at ID \"" + name + "\".");
|
||||
|
||||
//set default texture file name
|
||||
result.Set(name + ".jpg");
|
||||
ConvertPath(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// if this is an embedded texture image setup an aiTexture for it
|
||||
if (imIt->second.mFileName.empty())
|
||||
|
|
|
@ -54,7 +54,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
|
|||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
|
||||
#include "BlobIOSystem.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "BaseProcess.h"
|
||||
#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
|
||||
|
||||
|
|
|
@ -66,8 +66,7 @@ namespace MDL {
|
|||
* \brief Data structure for the HL2 main header
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Header_HL2
|
||||
{
|
||||
struct Header_HL2 {
|
||||
//! magic number: "IDST"/"IDSQ"
|
||||
char ident[4];
|
||||
|
||||
|
@ -139,7 +138,7 @@ struct Header_HL2
|
|||
//! Number of animation transitions
|
||||
int32_t numtransitions;
|
||||
int32_t transitionindex;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
#include "./../include/assimp/Compiler/poppack1.h"
|
||||
|
||||
|
|
|
@ -882,6 +882,7 @@ void ProcessSpatialStructures(ConversionData& conv)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<aiNode*> nodes;
|
||||
|
||||
for(const STEP::LazyObject* lz : *range) {
|
||||
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():""));
|
||||
|
||||
// the primary site is referenced by an IFCRELAGGREGATES element which assigns it to the IFCPRODUCT
|
||||
// the primary sites are referenced by an IFCRELAGGREGATES element which assigns them to the IFCPRODUCT
|
||||
const STEP::DB::RefMap& refs = conv.db.GetRefs();
|
||||
STEP::DB::RefMapRange range = refs.equal_range(conv.proj.GetID());
|
||||
for(;range.first != range.second; ++range.first) {
|
||||
if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr<IfcRelAggregates>()) {
|
||||
STEP::DB::RefMapRange ref_range = refs.equal_range(conv.proj.GetID());
|
||||
for(; ref_range.first != ref_range.second; ++ref_range.first) {
|
||||
if(const IfcRelAggregates* const aggr = conv.db.GetObject((*ref_range.first).second)->ToPtr<IfcRelAggregates>()) {
|
||||
|
||||
for(const IfcObjectDefinition& def : aggr->RelatedObjects) {
|
||||
// comparing pointer values is not sufficient, we would need to cast them to the same type first
|
||||
// as there is multiple inheritance in the game.
|
||||
if (def.GetID() == prod->GetID()) {
|
||||
IFCImporter::LogDebug("selecting this spatial structure as root structure");
|
||||
// got it, this is the primary site.
|
||||
conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
|
||||
return;
|
||||
// got it, this is one primary site.
|
||||
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -911,19 +911,42 @@ void ProcessSpatialStructures(ConversionData& conv)
|
|||
}
|
||||
}
|
||||
|
||||
size_t nb_nodes = nodes.size();
|
||||
|
||||
IFCImporter::LogWarn("failed to determine primary site element, taking the first IfcSite");
|
||||
for(const STEP::LazyObject* lz : *range) {
|
||||
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
|
||||
if(!prod) {
|
||||
continue;
|
||||
}
|
||||
if (nb_nodes == 0) {
|
||||
IFCImporter::LogWarn("failed to determine primary site element, taking all the IfcSite");
|
||||
for (const STEP::LazyObject* lz : *range) {
|
||||
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
|
||||
if (!prod) {
|
||||
continue;
|
||||
}
|
||||
|
||||
conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
|
||||
return;
|
||||
}
|
||||
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
|
||||
}
|
||||
|
||||
IFCImporter::ThrowException("failed to determine primary site element");
|
||||
nb_nodes = nodes.size();
|
||||
}
|
||||
|
||||
if (nb_nodes == 1) {
|
||||
conv.out->mRootNode = nodes[0];
|
||||
}
|
||||
else if (nb_nodes > 1) {
|
||||
conv.out->mRootNode = new aiNode("Root");
|
||||
conv.out->mRootNode->mParent = NULL;
|
||||
conv.out->mRootNode->mNumChildren = static_cast<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 "ParsingUtils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -69,8 +71,8 @@ public:
|
|||
/// @return true if successful.
|
||||
bool close();
|
||||
|
||||
/// @brief Returns the filesize.
|
||||
/// @return The filesize.
|
||||
/// @brief Returns the file-size.
|
||||
/// @return The file-size.
|
||||
size_t size() const;
|
||||
|
||||
/// @brief Returns the cache size.
|
||||
|
@ -96,7 +98,17 @@ public:
|
|||
/// @brief Will read the next line.
|
||||
/// @param buffer The buffer for the next line.
|
||||
/// @return true if successful.
|
||||
bool getNextLine( std::vector<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:
|
||||
IOStream *m_stream;
|
||||
|
@ -227,15 +239,35 @@ size_t IOStreamBuffer<T>::getFilePos() const {
|
|||
|
||||
template<class T>
|
||||
inline
|
||||
bool IOStreamBuffer<T>::getNextLine( std::vector<T> &buffer ) {
|
||||
bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
|
||||
buffer.resize( m_cacheSize );
|
||||
if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
|
||||
if ( !readNextBlock() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool continuationFound( false ), endOfDataLine( false );
|
||||
size_t i = 0;
|
||||
while ( !IsLineEnd( m_cache[ m_cachePos ] ) ) {
|
||||
while ( !endOfDataLine ) {
|
||||
if ( continuationToken == m_cache[ m_cachePos ] ) {
|
||||
continuationFound = true;
|
||||
++m_cachePos;
|
||||
}
|
||||
if ( IsLineEnd( m_cache[ m_cachePos ] ) ) {
|
||||
if ( !continuationFound ) {
|
||||
// the end of the data line
|
||||
break;
|
||||
} else {
|
||||
// skip line end
|
||||
while ( m_cache[m_cachePos] != '\n') {
|
||||
++m_cachePos;
|
||||
}
|
||||
++m_cachePos;
|
||||
continuationFound = false;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[ i ] = m_cache[ m_cachePos ];
|
||||
m_cachePos++;
|
||||
i++;
|
||||
|
@ -245,10 +277,63 @@ bool IOStreamBuffer<T>::getNextLine( std::vector<T> &buffer ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer[ i ] = '\n';
|
||||
m_cachePos++;
|
||||
|
||||
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
|
||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "fast_atof.h"
|
||||
#include "GenericProperty.h"
|
||||
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "StandardShapes.h"
|
||||
#include "Importer.h"
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define AI_IRRLOADER_H_INCLUDED
|
||||
|
||||
#include "IRRShared.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "Importer.h"
|
||||
#include "StringUtils.h"
|
||||
#include <assimp/anim.h>
|
||||
|
|
|
@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
// internal headers
|
||||
#include "LWOFileData.h"
|
||||
#include <assimp/anim.h>
|
||||
|
||||
using namespace Assimp;
|
||||
using namespace Assimp::LWO;
|
||||
|
|
|
@ -48,11 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef AI_LWO_ANIMATION_INCLUDED
|
||||
#define AI_LWO_ANIMATION_INCLUDED
|
||||
|
||||
#include <assimp/anim.h>
|
||||
//
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
struct aiNodeAnim;
|
||||
struct aiVectorKey;
|
||||
|
||||
namespace Assimp {
|
||||
namespace LWO {
|
||||
|
@ -166,7 +167,6 @@ struct Envelope
|
|||
//! Keyframes for this envelope
|
||||
std::vector<Key> keys;
|
||||
|
||||
|
||||
// temporary data for AnimResolver
|
||||
size_t old_first,old_last;
|
||||
};
|
||||
|
@ -198,8 +198,7 @@ public:
|
|||
* @param Output tick rate, per second
|
||||
* @note The input envelopes are possibly modified.
|
||||
*/
|
||||
AnimResolver(std::list<Envelope>& envelopes,
|
||||
double tick);
|
||||
AnimResolver(std::list<Envelope>& envelopes, double tick);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "ParsingUtils.h"
|
||||
#include "fast_atof.h"
|
||||
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "GenericProperty.h"
|
||||
#include "SkeletonMeshBuilder.h"
|
||||
#include "ConvertToLHProcess.h"
|
||||
|
|
|
@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define AI_LWSLOADER_H_INCLUDED
|
||||
|
||||
#include "LWOFileData.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "BaseImporter.h"
|
||||
|
||||
struct aiImporterDesc;
|
||||
|
|
|
@ -142,14 +142,14 @@ struct Frame
|
|||
//! name of frame
|
||||
char name[ AI_MD3_MAXFRAME ];
|
||||
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** @brief Data structure for the tag header
|
||||
/**
|
||||
* @brief Data structure for the tag header
|
||||
*/
|
||||
struct Tag
|
||||
{
|
||||
struct Tag {
|
||||
//! name of the tag
|
||||
char NAME[ AI_MD3_MAXQPATH ];
|
||||
|
||||
|
@ -157,14 +157,13 @@ struct Tag
|
|||
aiVector3D origin;
|
||||
ai_real orientation[3][3];
|
||||
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** @brief Data structure for the surface header
|
||||
*/
|
||||
struct Surface
|
||||
{
|
||||
struct Surface {
|
||||
//! magic number
|
||||
int32_t IDENT;
|
||||
|
||||
|
@ -186,7 +185,6 @@ struct Surface
|
|||
//! number of triangles in the surface
|
||||
uint32_t NUM_TRIANGLES;
|
||||
|
||||
|
||||
//! offset to the triangle data
|
||||
uint32_t OFS_TRIANGLES;
|
||||
|
||||
|
@ -201,19 +199,18 @@ struct Surface
|
|||
|
||||
//! offset to the end of the Surface object
|
||||
int32_t OFS_END;
|
||||
} PACK_STRUCT;
|
||||
} /*PACK_STRUCT*/;
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** @brief Data structure for a shader defined in there
|
||||
*/
|
||||
struct Shader
|
||||
{
|
||||
struct Shader {
|
||||
//! filename of the shader
|
||||
char NAME[ AI_MD3_MAXQPATH ];
|
||||
|
||||
//! index of the shader
|
||||
uint32_t SHADER_INDEX;
|
||||
} PACK_STRUCT;
|
||||
} /*PACK_STRUCT*/;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
@ -223,7 +220,7 @@ struct Triangle
|
|||
{
|
||||
//! triangle indices
|
||||
uint32_t INDEXES[3];
|
||||
} PACK_STRUCT;
|
||||
} /*PACK_STRUCT*/;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
@ -233,7 +230,7 @@ struct TexCoord
|
|||
{
|
||||
//! UV coordinates
|
||||
ai_real U,V;
|
||||
} PACK_STRUCT;
|
||||
} /*PACK_STRUCT*/;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
@ -246,7 +243,7 @@ struct Vertex
|
|||
|
||||
//! encoded normal vector
|
||||
uint16_t NORMAL;
|
||||
} PACK_STRUCT;
|
||||
} /*PACK_STRUCT*/;
|
||||
|
||||
#include "./../include/assimp/Compiler/poppack1.h"
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
|
||||
|
||||
#include "MD3Loader.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "GenericProperty.h"
|
||||
#include "RemoveComments.h"
|
||||
#include "ParsingUtils.h"
|
||||
|
|
|
@ -157,7 +157,7 @@ struct Frame
|
|||
|
||||
//! Name of the frame
|
||||
char name [ 16 ] ;
|
||||
} PACK_STRUCT;
|
||||
} /*PACK_STRUCT*/;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \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
|
||||
#define AI_MDLFILEHELPER_H_INC
|
||||
|
||||
#include <assimp/anim.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/Compiler/pushpack1.h>
|
||||
#include "ByteSwapper.h"
|
||||
#include "./../include/assimp/anim.h"
|
||||
#include "./../include/assimp/mesh.h"
|
||||
#include "./../include/assimp/Compiler/pushpack1.h"
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
|
@ -90,7 +90,6 @@ namespace MDL {
|
|||
#define AI_MDL_MAGIC_NUMBER_BE_GS7 AI_MAKE_MAGIC("MDL7")
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_GS7 AI_MAKE_MAGIC("7LDM")
|
||||
|
||||
|
||||
// common limitations for Quake1 meshes. The loader does not check them,
|
||||
// (however it warns) but models should not exceed these limits.
|
||||
#if (!defined AI_MDL_VERSION)
|
||||
|
@ -119,8 +118,7 @@ namespace MDL {
|
|||
/** \struct Header
|
||||
* \brief Data structure for the MDL main header
|
||||
*/
|
||||
struct Header
|
||||
{
|
||||
struct Header {
|
||||
//! magic number: "IDPO"
|
||||
uint32_t ident;
|
||||
|
||||
|
@ -166,15 +164,14 @@ struct Header
|
|||
|
||||
//! Could be the total size of the file (and not a float)
|
||||
float size;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Header_MDL7
|
||||
* \brief Data structure for the MDL 7 main header
|
||||
*/
|
||||
struct Header_MDL7
|
||||
{
|
||||
struct Header_MDL7 {
|
||||
//! magic number: "MDL7"
|
||||
char ident[4];
|
||||
|
||||
|
@ -226,15 +223,14 @@ struct Header_MDL7
|
|||
|
||||
//! Size of the Frame_MDL7 data structure used in the file
|
||||
uint16_t frame_stc_size;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Bone_MDL7
|
||||
* \brief Data structure for a bone in a MDL7 file
|
||||
*/
|
||||
struct Bone_MDL7
|
||||
{
|
||||
struct Bone_MDL7 {
|
||||
//! Index of the parent bone of *this* bone. 0xffff means:
|
||||
//! "hey, I have no parent, I'm an orphan"
|
||||
uint16_t parent_index;
|
||||
|
@ -246,7 +242,7 @@ struct Bone_MDL7
|
|||
|
||||
//! Optional name of the bone
|
||||
char name[1 /* DUMMY SIZE */];
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
|
||||
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
|
||||
|
@ -268,8 +264,7 @@ struct Bone_MDL7
|
|||
/** \struct Group_MDL7
|
||||
* \brief Group in a MDL7 file
|
||||
*/
|
||||
struct Group_MDL7
|
||||
{
|
||||
struct Group_MDL7 {
|
||||
//! = '1' -> triangle based Mesh
|
||||
unsigned char typ;
|
||||
|
||||
|
@ -295,7 +290,7 @@ struct Group_MDL7
|
|||
|
||||
//! Number of frames
|
||||
int32_t numframes;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
|
||||
#define AI_MDL7_SKINTYPE_MATERIAL 0x10
|
||||
|
@ -310,41 +305,36 @@ struct Group_MDL7
|
|||
/** \struct Deformer_MDL7
|
||||
* \brief Deformer in a MDL7 file
|
||||
*/
|
||||
struct Deformer_MDL7
|
||||
{
|
||||
struct Deformer_MDL7 {
|
||||
int8_t deformer_version; // 0
|
||||
int8_t deformer_typ; // 0 - bones
|
||||
int8_t _unused_[2];
|
||||
int32_t group_index;
|
||||
int32_t elements;
|
||||
int32_t deformerdata_size;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct DeformerElement_MDL7
|
||||
* \brief Deformer element in a MDL7 file
|
||||
*/
|
||||
struct DeformerElement_MDL7
|
||||
{
|
||||
struct DeformerElement_MDL7 {
|
||||
//! bei deformer_typ==0 (==bones) element_index == bone index
|
||||
int32_t element_index;
|
||||
char element_name[AI_MDL7_MAX_BONENAMESIZE];
|
||||
int32_t weights;
|
||||
} PACK_STRUCT;
|
||||
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct DeformerWeight_MDL7
|
||||
* \brief Deformer weight in a MDL7 file
|
||||
*/
|
||||
struct DeformerWeight_MDL7
|
||||
{
|
||||
struct DeformerWeight_MDL7 {
|
||||
//! for deformer_typ==0 (==bones) index == vertex index
|
||||
int32_t index;
|
||||
float weight;
|
||||
} PACK_STRUCT;
|
||||
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// don't know why this was in the original headers ...
|
||||
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||
|
@ -353,17 +343,15 @@ typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
|||
/** \struct ColorValue_MDL7
|
||||
* \brief Data structure for a color value in a MDL7 file
|
||||
*/
|
||||
struct ColorValue_MDL7
|
||||
{
|
||||
struct ColorValue_MDL7 {
|
||||
float r,g,b,a;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Material_MDL7
|
||||
* \brief Data structure for a Material in a MDL7 file
|
||||
*/
|
||||
struct Material_MDL7
|
||||
{
|
||||
struct Material_MDL7 {
|
||||
//! Diffuse base color of the material
|
||||
ColorValue_MDL7 Diffuse;
|
||||
|
||||
|
@ -378,15 +366,13 @@ struct Material_MDL7
|
|||
|
||||
//! Phong power
|
||||
float Power;
|
||||
} PACK_STRUCT;
|
||||
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Skin
|
||||
* \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
|
||||
*/
|
||||
struct Skin
|
||||
{
|
||||
struct Skin {
|
||||
//! 0 = single (Skin), 1 = group (GroupSkin)
|
||||
//! For MDL3-5: Defines the type of the skin and there
|
||||
//! fore the size of the data to skip:
|
||||
|
@ -402,7 +388,7 @@ struct Skin
|
|||
|
||||
//! Texture data
|
||||
uint8_t *data;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -410,11 +396,10 @@ struct Skin
|
|||
* \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
|
||||
* \see Skin
|
||||
*/
|
||||
struct Skin_MDL5
|
||||
{
|
||||
struct Skin_MDL5 {
|
||||
int32_t size, width, height;
|
||||
uint8_t *data;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// maximum length of texture file name
|
||||
#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
|
||||
|
@ -425,44 +410,40 @@ struct Skin_MDL5
|
|||
/** \struct Skin_MDL7
|
||||
* \brief Skin data structure #3 - used by MDL7 and HMP7
|
||||
*/
|
||||
struct Skin_MDL7
|
||||
{
|
||||
struct Skin_MDL7 {
|
||||
uint8_t typ;
|
||||
int8_t _unused_[3];
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct RGB565
|
||||
* \brief Data structure for a RGB565 pixel in a texture
|
||||
*/
|
||||
struct RGB565
|
||||
{
|
||||
struct RGB565 {
|
||||
uint16_t r : 5;
|
||||
uint16_t g : 6;
|
||||
uint16_t b : 5;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct ARGB4
|
||||
* \brief Data structure for a ARGB4444 pixel in a texture
|
||||
*/
|
||||
struct ARGB4
|
||||
{
|
||||
struct ARGB4 {
|
||||
uint16_t a : 4;
|
||||
uint16_t r : 4;
|
||||
uint16_t g : 4;
|
||||
uint16_t b : 4;
|
||||
} PACK_STRUCT;
|
||||
} /*PACK_STRUCT*/;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct GroupSkin
|
||||
* \brief Skin data structure #2 (group of pictures)
|
||||
*/
|
||||
struct GroupSkin
|
||||
{
|
||||
struct GroupSkin {
|
||||
//! 0 = single (Skin), 1 = group (GroupSkin)
|
||||
int32_t group;
|
||||
|
||||
|
@ -474,14 +455,13 @@ struct GroupSkin
|
|||
|
||||
//! Data of each image
|
||||
uint8_t **data;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct TexCoord
|
||||
* \brief Texture coordinate data structure used by the Quake1 MDL format
|
||||
*/
|
||||
struct TexCoord
|
||||
{
|
||||
struct TexCoord {
|
||||
//! Is the vertex on the noundary between front and back piece?
|
||||
int32_t onseam;
|
||||
|
||||
|
@ -490,33 +470,31 @@ struct TexCoord
|
|||
|
||||
//! Texture coordinate in the ty direction
|
||||
int32_t t;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct TexCoord_MDL3
|
||||
* \brief Data structure for an UV coordinate in the 3DGS MDL3 format
|
||||
*/
|
||||
struct TexCoord_MDL3
|
||||
{
|
||||
struct TexCoord_MDL3 {
|
||||
//! position, horizontally in range 0..skinwidth-1
|
||||
int16_t u;
|
||||
|
||||
//! position, vertically in range 0..skinheight-1
|
||||
int16_t v;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct TexCoord_MDL7
|
||||
* \brief Data structure for an UV coordinate in the 3DGS MDL7 format
|
||||
*/
|
||||
struct TexCoord_MDL7
|
||||
{
|
||||
struct TexCoord_MDL7 {
|
||||
//! position, horizontally in range 0..1
|
||||
float u;
|
||||
|
||||
//! position, vertically in range 0..1
|
||||
float v;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct SkinSet_MDL7
|
||||
|
@ -532,7 +510,7 @@ struct SkinSet_MDL7
|
|||
|
||||
//! Material index
|
||||
int32_t material; // size 4
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Triangle
|
||||
|
@ -545,7 +523,7 @@ struct Triangle
|
|||
|
||||
//! Vertex indices
|
||||
int32_t vertex[3];
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Triangle_MDL3
|
||||
|
@ -558,7 +536,7 @@ struct Triangle_MDL3
|
|||
|
||||
//! Index of 3 skin vertices in range 0..numskinverts
|
||||
uint16_t index_uv[3];
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Triangle_MDL7
|
||||
|
@ -571,7 +549,7 @@ struct Triangle_MDL7
|
|||
|
||||
//! Two skinsets. The second will be used for multi-texturing
|
||||
SkinSet_MDL7 skinsets[2];
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
||||
# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
|
||||
|
@ -599,7 +577,7 @@ struct Vertex
|
|||
{
|
||||
uint8_t v[3];
|
||||
uint8_t normalIndex;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -625,8 +603,7 @@ struct Vertex_MDL7
|
|||
uint8_t norm162index;
|
||||
float norm[3];
|
||||
};
|
||||
} PACK_STRUCT;
|
||||
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct BoneTransform_MDL7
|
||||
|
@ -643,12 +620,11 @@ struct BoneTransform_MDL7
|
|||
//! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
|
||||
//! THIS STUPID FILE FORMAT!
|
||||
int8_t _unused_[2];
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
#define AI_MDL7_MAX_FRAMENAMESIZE 16
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Frame_MDL7
|
||||
* \brief Frame data structure used by MDL7 files
|
||||
|
@ -678,7 +654,7 @@ struct SimpleFrame
|
|||
|
||||
//! Vertex list of the frame
|
||||
Vertex *verts;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Frame
|
||||
|
@ -691,7 +667,7 @@ struct Frame
|
|||
|
||||
//! Frame data
|
||||
SimpleFrame frame;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -708,7 +684,7 @@ struct SimpleFrame_MDLn_SP
|
|||
|
||||
//! Vertex list of the frame
|
||||
Vertex_MDL4 *verts;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct GroupFrame
|
||||
|
@ -730,7 +706,7 @@ struct GroupFrame
|
|||
|
||||
//! List of single frames
|
||||
SimpleFrame *frames;
|
||||
} PACK_STRUCT;
|
||||
} /* PACK_STRUCT */;
|
||||
|
||||
#include "./../include/assimp/Compiler/poppack1.h"
|
||||
|
||||
|
@ -738,8 +714,7 @@ struct GroupFrame
|
|||
/** \struct IntFace_MDL7
|
||||
* \brief Internal data structure to temporarily represent a face
|
||||
*/
|
||||
struct IntFace_MDL7
|
||||
{
|
||||
struct IntFace_MDL7 {
|
||||
// provide a constructor for our own convenience
|
||||
IntFace_MDL7()
|
||||
{
|
||||
|
|
|
@ -1,3 +1,43 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2017, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef MMD_CPP14_H
|
||||
|
|
|
@ -1,3 +1,43 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2017, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <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 "MMDPmxParser.h"
|
||||
#include "../contrib/utf8cpp/source/utf8.h"
|
||||
#include "Exceptional.h"
|
||||
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
||||
|
||||
namespace pmx
|
||||
{
|
||||
|
@ -60,15 +100,7 @@ namespace pmx
|
|||
const unsigned int targetSize = size * 3; // enough to encode
|
||||
char* targetStart = new char[targetSize]();
|
||||
const char* targetReserved = targetStart;
|
||||
ConversionFlags flags = ConversionFlags::lenientConversion;
|
||||
|
||||
ConversionResult conversionResult;
|
||||
if( ( conversionResult = ConvertUTF16toUTF8(
|
||||
(const UTF16**)&sourceStart, (const UTF16*)(sourceStart + size),
|
||||
(UTF8**)&targetStart, (UTF8*)(targetStart + targetSize),
|
||||
flags) ) != ConversionResult::conversionOK) {
|
||||
throw DeadlyImportError( "Convert " + std::string(sourceStart) + " to UTF8 is not valid." );
|
||||
}
|
||||
utf8::utf16to8( sourceStart, sourceStart + size, targetStart );
|
||||
|
||||
result.assign(targetReserved, targetStart - targetReserved);
|
||||
delete[] targetReserved;
|
||||
|
|
|
@ -1,3 +1,43 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2017, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <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
|
||||
|
||||
#include <vector>
|
||||
|
|
|
@ -64,7 +64,7 @@ ObjFileParser::ObjFileParser()
|
|||
, m_uiLine( 0 )
|
||||
, m_pIO( nullptr )
|
||||
, m_progress( nullptr )
|
||||
, m_originalObjFileName( "" ) {
|
||||
, m_originalObjFileName() {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -109,28 +109,6 @@ ObjFile::Model *ObjFileParser::GetModel() const {
|
|||
return m_pModel;
|
||||
}
|
||||
|
||||
void ignoreNewLines(IOStreamBuffer<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 ) {
|
||||
// only update every 100KB or it'll be too slow
|
||||
//const unsigned int updateProgressEveryBytes = 100 * 1024;
|
||||
|
@ -142,7 +120,7 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
|||
size_t lastFilePos( 0 );
|
||||
|
||||
std::vector<char> buffer;
|
||||
while ( streamBuffer.getNextLine( buffer ) ) {
|
||||
while ( streamBuffer.getNextDataLine( buffer, '\\' ) ) {
|
||||
m_DataIt = buffer.begin();
|
||||
m_DataItEnd = buffer.end();
|
||||
|
||||
|
@ -154,14 +132,14 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
|||
progressCounter++;
|
||||
m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
|
||||
}
|
||||
//ignoreNewLines(streamBuffer, buffer);
|
||||
|
||||
// parse line
|
||||
switch (*m_DataIt) {
|
||||
case 'v': // Parse a vertex texture coordinate
|
||||
{
|
||||
++m_DataIt;
|
||||
if (*m_DataIt == ' ' || *m_DataIt == '\t') {
|
||||
size_t numComponents = getNumComponentsInLine();
|
||||
size_t numComponents = getNumComponentsInDataDefinition();
|
||||
if (numComponents == 3) {
|
||||
// read in vertex definition
|
||||
getVector3(m_pModel->m_Vertices);
|
||||
|
@ -245,7 +223,6 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
|||
default:
|
||||
{
|
||||
pf_skip_line:
|
||||
|
||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||
}
|
||||
break;
|
||||
|
@ -274,21 +251,44 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
|
|||
pBuffer[index] = '\0';
|
||||
}
|
||||
|
||||
size_t ObjFileParser::getNumComponentsInLine() {
|
||||
static bool isDataDefinitionEnd( const char *tmp ) {
|
||||
if ( *tmp == '\\' ) {
|
||||
tmp++;
|
||||
if ( IsLineEnd( *tmp ) ) {
|
||||
tmp++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t ObjFileParser::getNumComponentsInDataDefinition() {
|
||||
size_t numComponents( 0 );
|
||||
const char* tmp( &m_DataIt[0] );
|
||||
while( !IsLineEnd( *tmp ) ) {
|
||||
bool end_of_definition = false;
|
||||
while ( !end_of_definition ) {
|
||||
if ( isDataDefinitionEnd( tmp ) ) {
|
||||
tmp += 2;
|
||||
} else if ( IsLineEnd( *tmp ) ) {
|
||||
end_of_definition = true;
|
||||
}
|
||||
if ( !SkipSpaces( &tmp ) ) {
|
||||
break;
|
||||
}
|
||||
const bool isNum( IsNumeric( *tmp ) );
|
||||
SkipToken( tmp );
|
||||
++numComponents;
|
||||
if ( isNum ) {
|
||||
++numComponents;
|
||||
}
|
||||
if ( !SkipSpaces( &tmp ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
||||
size_t numComponents = getNumComponentsInLine();
|
||||
size_t numComponents = getNumComponentsInDataDefinition();
|
||||
ai_real x, y, z;
|
||||
if( 2 == numComponents ) {
|
||||
copyNextWord( m_buffer, Buffersize );
|
||||
|
@ -397,10 +397,6 @@ static const std::string DefaultObjName = "defaultobject";
|
|||
// -------------------------------------------------------------------
|
||||
// Get values for a new face instance
|
||||
void ObjFileParser::getFace( aiPrimitiveType type ) {
|
||||
//copyNextLine(m_buffer, Buffersize);
|
||||
//char *pPtr = m_DataIt;
|
||||
//char *pPtr = m_buffer;
|
||||
//char *pEnd = &pPtr[Buffersize];
|
||||
m_DataIt = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
|
||||
if ( m_DataIt == m_DataItEnd || *m_DataIt == '\0' ) {
|
||||
return;
|
||||
|
@ -571,14 +567,7 @@ void ObjFileParser::getMaterialDesc() {
|
|||
// -------------------------------------------------------------------
|
||||
// Get a comment, values will be skipped
|
||||
void ObjFileParser::getComment() {
|
||||
while (m_DataIt != m_DataItEnd) {
|
||||
if ( '\n' == (*m_DataIt)) {
|
||||
++m_DataIt;
|
||||
break;
|
||||
} else {
|
||||
++m_DataIt;
|
||||
}
|
||||
}
|
||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
|
@ -91,6 +91,8 @@ protected:
|
|||
void copyNextWord(char *pBuffer, size_t length);
|
||||
/// Method to copy the new line.
|
||||
// void copyNextLine(char *pBuffer, size_t length);
|
||||
/// Get the number of components in a line.
|
||||
size_t getNumComponentsInDataDefinition();
|
||||
/// Stores the vector
|
||||
void getVector( std::vector<aiVector3D> &point3d_array );
|
||||
/// Stores the following 3d vector.
|
||||
|
@ -129,8 +131,6 @@ protected:
|
|||
bool needsNewMesh( const std::string &rMaterialName );
|
||||
/// Error report in token
|
||||
void reportErrorTokenInFace();
|
||||
/// Get the number of components in a line.
|
||||
size_t getNumComponentsInLine();
|
||||
|
||||
private:
|
||||
// Copy and assignment constructor should be private
|
||||
|
@ -154,9 +154,8 @@ private:
|
|||
IOSystem *m_pIO;
|
||||
//! Pointer to progress handler
|
||||
ProgressHandler* m_progress;
|
||||
/// Path to the current model
|
||||
// name of the obj file where the buffer comes from
|
||||
const std::string& m_originalObjFileName;
|
||||
/// Path to the current model, name of the obj file where the buffer comes from
|
||||
const std::string m_originalObjFileName;
|
||||
};
|
||||
|
||||
} // Namespace Assimp
|
||||
|
|
|
@ -116,14 +116,16 @@ inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
|
|||
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
|
||||
++it;
|
||||
}
|
||||
if ( it != end )
|
||||
{
|
||||
|
||||
if ( it != end ) {
|
||||
++it;
|
||||
++uiLine;
|
||||
}
|
||||
// fix .. from time to time there are spaces at the beginning of a material line
|
||||
while ( it != end && (*it == '\t' || *it == ' ') )
|
||||
while ( it != end && ( *it == '\t' || *it == ' ' ) ) {
|
||||
++it;
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "OptimizeGraph.h"
|
||||
#include "ProcessHelper.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "Exceptional.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "OptimizeMeshes.h"
|
||||
#include "ProcessHelper.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "Exceptional.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
|
|
@ -51,14 +51,12 @@ struct aiScene;
|
|||
struct aiNode;
|
||||
struct aiMesh;
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Helper class to export a given scene to a Stanford Ply file. */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class PlyExporter
|
||||
{
|
||||
class PlyExporter {
|
||||
public:
|
||||
/// The class constructor for a specific scene to export
|
||||
PlyExporter(const char* filename, const aiScene* pScene, bool binary = false);
|
||||
|
|
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();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -78,6 +77,16 @@ public:
|
|||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||
bool checkSig) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Extract a vertex from the DOM
|
||||
*/
|
||||
void LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Extract a face from the DOM
|
||||
*/
|
||||
void LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos);
|
||||
|
||||
protected:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -94,53 +103,10 @@ protected:
|
|||
IOSystem* pIOHandler);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Extract vertices from the DOM
|
||||
*/
|
||||
void LoadVertices(std::vector<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
|
||||
*/
|
||||
void LoadMaterial(std::vector<aiMaterial*>* pvOut);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** 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);
|
||||
|
||||
void LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Static helper to parse a color from four single channels in
|
||||
|
@ -151,7 +117,6 @@ protected:
|
|||
PLY::EDataType aiTypes[4],
|
||||
aiColor4D* clrOut);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Static helper to parse a color channel value. The input value
|
||||
* is normalized to 0-1.
|
||||
|
@ -160,12 +125,14 @@ protected:
|
|||
PLY::PropertyInstance::ValueUnion val,
|
||||
PLY::EDataType eType);
|
||||
|
||||
|
||||
/** Buffer to hold the loaded file */
|
||||
unsigned char* mBuffer;
|
||||
|
||||
/** Document object model representation extracted from the file */
|
||||
PLY::DOM* pcDOM;
|
||||
|
||||
/** Mesh generated by loader */
|
||||
aiMesh* mGeneratedMesh;
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
|
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
|
||||
|
||||
All rights reserved.
|
||||
|
||||
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 "IOStreamBuffer.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
//pre-declaration
|
||||
class PLYImporter;
|
||||
|
||||
// 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://www.okino.com/conv/exp_ply.htm
|
||||
namespace PLY
|
||||
{
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
/*
|
||||
name type number of bytes
|
||||
|
@ -197,6 +198,9 @@ enum EElementSemantic
|
|||
//! The element is a material description
|
||||
EEST_Material,
|
||||
|
||||
//! texture path
|
||||
EEST_TextureFile,
|
||||
|
||||
//! Marks invalid entries
|
||||
EEST_INVALID
|
||||
};
|
||||
|
@ -238,16 +242,15 @@ public:
|
|||
//! string is either '\n', '\r' or '\0'. Return value is false
|
||||
//! if the input string is NOT a valid property (E.g. does
|
||||
//! not start with the "property" keyword)
|
||||
static bool ParseProperty (const char* pCur, const char** pCurOut,
|
||||
Property* pOut);
|
||||
static bool ParseProperty(std::vector<char> &buffer, Property* pOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! 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
|
||||
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.
|
||||
//! The function will parse all properties contained in the
|
||||
//! element, too.
|
||||
static bool ParseElement (const char* pCur, const char** pCurOut,
|
||||
Element* pOut);
|
||||
static bool ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, Element* pOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a semantic from a string
|
||||
static EElementSemantic ParseSemantic(const char* pCur,
|
||||
const char** pCurOut);
|
||||
static EElementSemantic ParseSemantic(std::vector<char> &buffer);
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
@ -331,13 +332,13 @@ public:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
//! 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);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a property instance in binary format
|
||||
static bool ParseInstanceBinary (const char* pCur,const char** pCurOut,
|
||||
const Property* prop, PropertyInstance* p_pcOut,bool p_bBE);
|
||||
static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||
const char* &pCur, unsigned int &bufferSize, const Property* prop, PropertyInstance* p_pcOut, bool p_bBE);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Get the default value for a given data type
|
||||
|
@ -345,13 +346,12 @@ public:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a value
|
||||
static bool ParseValue(const char* pCur,const char** pCurOut,
|
||||
EDataType eType,ValueUnion* out);
|
||||
static bool ParseValue(const char* &pCur, EDataType eType, ValueUnion* out);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a binary value
|
||||
static bool ParseValueBinary(const char* pCur,const char** pCurOut,
|
||||
EDataType eType,ValueUnion* out,bool p_bBE);
|
||||
static bool ParseValueBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||
const char* &pCur, unsigned int &bufferSize, EDataType eType, ValueUnion* out, bool p_bBE);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Convert a property value to a given type TYPE
|
||||
|
@ -375,13 +375,13 @@ public:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
//! 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);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a binary element instance
|
||||
static bool ParseInstanceBinary (const char* pCur,const char** pCurOut,
|
||||
const Element* pcElement, ElementInstance* p_pcOut,bool p_bBE);
|
||||
static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||
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
|
||||
static bool ParseInstanceList (const char* pCur,const char** pCurOut,
|
||||
const Element* pcElement, ElementInstanceList* p_pcOut);
|
||||
static bool ParseInstanceList(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||
const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a binary element instance list
|
||||
static bool ParseInstanceListBinary (const char* pCur,const char** pCurOut,
|
||||
const Element* pcElement, ElementInstanceList* p_pcOut,bool p_bBE);
|
||||
static bool ParseInstanceListBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
|
||||
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
|
||||
|
@ -428,50 +428,33 @@ public:
|
|||
|
||||
//! Parse the DOM for a PLY file. The input string is assumed
|
||||
//! to be terminated with zero
|
||||
static bool ParseInstance (const char* pCur,DOM* p_pcOut);
|
||||
static bool ParseInstanceBinary (const char* pCur,
|
||||
DOM* p_pcOut,bool p_bBE);
|
||||
static bool ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader);
|
||||
static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader, bool p_bBE);
|
||||
|
||||
//! 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:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//! 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
|
||||
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
|
||||
bool ParseElementInstanceListsBinary (const char* pCur,
|
||||
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;
|
||||
bool ParseElementInstanceListsBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, const char* &pCur, unsigned int &bufferSize, PLYImporter* loader, bool p_bBE);
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
|
|
@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "PretransformVertices.h"
|
||||
#include "ProcessHelper.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "Exceptional.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
|
|
@ -58,7 +58,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "ByteSwapper.h"
|
||||
#include "StreamReader.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/DefaultLogger.hpp>
|
||||
#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.
|
||||
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)
|
||||
UTF16* temp = new UTF16[numWChars];
|
||||
UTF8* str = new UTF8[numWChars * 4 + 1];
|
||||
//UTF16* temp = new UTF16[numWChars];
|
||||
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++)
|
||||
temp[n] = stream->GetU2();
|
||||
|
||||
// Convert it and NUL-terminate.
|
||||
const UTF16 *start = temp, *end = temp + numWChars;
|
||||
UTF8 *dest = str, *limit = str + numWChars*4;
|
||||
ConvertUTF16toUTF8(&start, end, &dest, limit, lenientConversion);
|
||||
*dest = '\0';
|
||||
//const UTF16 *start = temp, *end = temp + numWChars;
|
||||
|
||||
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.
|
||||
aiString result = aiString((const char *)str);
|
||||
delete[] str;
|
||||
aiString result = aiString((const char *)&str[0]);
|
||||
//delete[] str;
|
||||
delete[] temp;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -40,18 +40,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
/** @file STEPFileEncoding.cpp
|
||||
* @brief STEP character handling, string unescaping
|
||||
* @brief STEP character handling, string un-escaping
|
||||
*/
|
||||
#include "STEPFileEncoding.h"
|
||||
#include "fast_atof.h"
|
||||
#include <contrib/utf8cpp/source/utf8.h>
|
||||
|
||||
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
||||
#include <memory>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
// roman1 to utf16 table
|
||||
static const UTF16 mac_codetable[] = {
|
||||
static const uint16_t mac_codetable[] = {
|
||||
// 0x20 unassig./nonprint. slots
|
||||
0x0020 ,
|
||||
0x0021 ,
|
||||
|
@ -309,14 +309,12 @@ bool STEP::StringToUTF8(std::string& s)
|
|||
|
||||
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;
|
||||
ai_assert(sizeof(UTF8) == 1);
|
||||
unsigned char temp[5], *tempp = temp;
|
||||
ai_assert(sizeof( unsigned char ) == 1);
|
||||
|
||||
if(ConvertUTF32toUTF8(&univalp, univalp+1, &tempp, tempp+sizeof(temp), lenientConversion) != conversionOK) {
|
||||
return false;
|
||||
}
|
||||
utf8::utf32to8( univalp, univalp + 1, tempp );
|
||||
|
||||
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;
|
||||
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;
|
||||
for (size_t k = 0; k < count; ++k, cur += 4) {
|
||||
src[k] = (static_cast<UTF16>(HexOctetToDecimal(cur)) << 8u) |
|
||||
static_cast<UTF16>(HexOctetToDecimal(cur+2));
|
||||
src[k] = (static_cast<uint16_t>(HexOctetToDecimal(cur)) << 8u) |
|
||||
static_cast<uint16_t>(HexOctetToDecimal(cur+2));
|
||||
}
|
||||
|
||||
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();
|
||||
UTF8* destt = dest.get();
|
||||
if(ConvertUTF16toUTF8(&srct, srct+count, &destt, destt+dcount, lenientConversion) != conversionOK) {
|
||||
return false;
|
||||
}
|
||||
const uint16_t* srct = src.get();
|
||||
unsigned char* destt = dest.get();
|
||||
utf8::utf16to8( srct, srct + count, destt );
|
||||
|
||||
const size_t outcount = static_cast<size_t>(destt-dest.get());
|
||||
|
||||
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);
|
||||
|
||||
i += outcount;
|
||||
|
@ -388,37 +384,34 @@ bool STEP::StringToUTF8(std::string& s)
|
|||
}
|
||||
|
||||
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;
|
||||
for (size_t k = 0; k < count; ++k, cur += 8) {
|
||||
src[k] = (static_cast<UTF32>(HexOctetToDecimal(cur )) << 24u) |
|
||||
(static_cast<UTF32>(HexOctetToDecimal(cur+2)) << 16u) |
|
||||
(static_cast<UTF32>(HexOctetToDecimal(cur+4)) << 8u) |
|
||||
(static_cast<UTF32>(HexOctetToDecimal(cur+6)));
|
||||
src[k] = (static_cast<uint32_t>(HexOctetToDecimal(cur )) << 24u) |
|
||||
(static_cast<uint32_t>(HexOctetToDecimal(cur+2)) << 16u) |
|
||||
(static_cast<uint32_t>(HexOctetToDecimal(cur+4)) << 8u) |
|
||||
(static_cast<uint32_t>(HexOctetToDecimal(cur+6)));
|
||||
}
|
||||
|
||||
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();
|
||||
UTF8* destt = dest.get();
|
||||
if(ConvertUTF32toUTF8(&srct, srct+count, &destt, destt+dcount, lenientConversion) != conversionOK) {
|
||||
return false;
|
||||
}
|
||||
const uint32_t* srct = src.get();
|
||||
unsigned char* destt = dest.get();
|
||||
utf8::utf32to8( srct, srct + count, destt );
|
||||
|
||||
const size_t outcount = static_cast<size_t>(destt-dest.get());
|
||||
|
||||
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);
|
||||
|
||||
i += outcount;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// 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++)
|
||||
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).
|
||||
aiMaterial* pcMat = new aiMaterial();
|
||||
aiString s;
|
||||
s.Set(AI_DEFAULT_MATERIAL_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) {
|
||||
clrDiffuse = clrColorDefault;
|
||||
}
|
||||
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||
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);
|
||||
|
||||
pScene->mNumMaterials = 1;
|
||||
|
|
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
* OptimizeGraph step.
|
||||
*/
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "StringUtils.h"
|
||||
#include "fast_atof.h"
|
||||
#include "Hash.h"
|
||||
|
|
|
@ -126,9 +126,8 @@ void SpatialSort::FindPositions( const aiVector3D& pPosition,
|
|||
const ai_real dist = pPosition * mPlaneNormal;
|
||||
const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
|
||||
|
||||
// clear the array in this strange fashion because a simple clear() would also deallocate
|
||||
// the array which we want to avoid
|
||||
poResults.erase( poResults.begin(), poResults.end());
|
||||
// clear the array
|
||||
poResults.clear();
|
||||
|
||||
// quick check for positions outside the range
|
||||
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_STEP_EXPORTER
|
||||
|
||||
#include "StepExporter.h"
|
||||
#include "ConvertToLHProcess.h"
|
||||
#include "Bitmap.h"
|
||||
#include "BaseImporter.h"
|
||||
#include "fast_atof.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
|
|
|
@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
#include "Subdivision.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include "SpatialSort.h"
|
||||
#include "ProcessHelper.h"
|
||||
#include "Vertex.h"
|
||||
|
|
|
@ -43,12 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
|
||||
|
||||
#include "XFileExporter.h"
|
||||
#include "ConvertToLHProcess.h"
|
||||
#include "Bitmap.h"
|
||||
#include "BaseImporter.h"
|
||||
#include "fast_atof.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include <assimp/DefaultIOSystem.h>
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// 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
|
||||
|
@ -22,6 +24,7 @@
|
|||
#include <assimp/defs.h>
|
||||
|
||||
#include "StringComparison.h"
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
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;
|
||||
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' );
|
||||
|
||||
if (new_value < value) /* numeric overflow, we rely on you */
|
||||
throw std::overflow_error(std::string("Converting the string \"") + in + "\" into a value resulted in overflow.");
|
||||
// numeric overflow, we rely on you
|
||||
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;
|
||||
|
||||
|
|
|
@ -48,8 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "ByteSwapper.h"
|
||||
|
||||
#include "SplitLargeMeshes.h"
|
||||
#include "SceneCombiner.h"
|
||||
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include <assimp/version.h>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/Exporter.hpp>
|
||||
|
@ -185,8 +185,11 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
|
|||
unsigned int bytesPerComp = ComponentTypeSize(compType);
|
||||
|
||||
size_t offset = buffer->byteLength;
|
||||
// make sure offset is correctly byte-aligned, as required by spec
|
||||
size_t padding = offset % bytesPerComp;
|
||||
offset += padding;
|
||||
size_t length = count * numCompsOut * bytesPerComp;
|
||||
buffer->Grow(length);
|
||||
buffer->Grow(length + padding);
|
||||
|
||||
// bufferView
|
||||
Ref<BufferView> bv = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));
|
||||
|
|
|
@ -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_MINOR 1 )
|
||||
SET ( OPENDDL_PARSER_VERSION_PATCH 0 )
|
||||
SET ( OPENDDL_PARSER_VERSION ${CPPCORE_VERSION_MAJOR}.${CPPCORE_VERSION_MINOR}.${CPPCORE_VERSION_PATCH} )
|
||||
SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} )
|
||||
SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
|
||||
|
||||
option( DDL_USE_CPP11 "Set to ON to use C++11 features ( always on on windows )." ON )
|
||||
option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF )
|
||||
option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON )
|
||||
option( COVERALLS "Generate coveralls data" OFF )
|
||||
|
||||
if ( DDL_USE_CPP11 )
|
||||
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||
set( OPENDDL_CXXFLAGS -std=c++0x )
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set( OPENDDL_CXXFLAGS --std=c++11 )
|
||||
endif()
|
||||
else( DDL_USE_CPP11 )
|
||||
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||
endif( DDL_USE_CPP11)
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||
find_package(Threads)
|
||||
else()
|
||||
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
|
||||
endif()
|
||||
|
||||
if ( DDL_STATIC_LIBRARY )
|
||||
add_definitions( -DOPENDDL_STATIC_LIBARY )
|
||||
endif()
|
||||
|
||||
add_definitions( -DOPENDDLPARSER_BUILD )
|
||||
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||
add_definitions( -D_VARIADIC_MAX=10 )
|
||||
add_definitions( -DGTEST_HAS_PTHREAD=0 )
|
||||
if ( DDL_DEBUG_OUTPUT )
|
||||
add_definitions( -DDDL_DEBUG_HEADER_NAME)
|
||||
endif()
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
./
|
||||
|
@ -24,9 +46,10 @@ INCLUDE_DIRECTORIES(
|
|||
)
|
||||
|
||||
link_directories(
|
||||
./
|
||||
${CMAKE_HOME_DIRECTORY}/lib
|
||||
)
|
||||
|
||||
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake )
|
||||
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
||||
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
|
||||
|
@ -40,18 +63,38 @@ if( WIN32 AND NOT CYGWIN )
|
|||
endif()
|
||||
elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||
# Update if necessary
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS}")
|
||||
elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS} -Wwrite-strings")
|
||||
endif()
|
||||
|
||||
if (COVERALLS)
|
||||
include(Coveralls)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||
endif()
|
||||
|
||||
# Include the doc component.
|
||||
FIND_PACKAGE( doxygen )
|
||||
IF ( DOXYGEN_FOUND )
|
||||
CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY )
|
||||
ADD_CUSTOM_TARGET( doc ALL ${DOXYGEN_EXECUTABLE} doc/doxygenfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen" VERBATIM )
|
||||
ENDIF ( DOXYGEN_FOUND )
|
||||
|
||||
SET ( openddl_parser_src
|
||||
code/OpenDDLCommon.cpp
|
||||
code/OpenDDLExport.cpp
|
||||
code/OpenDDLParser.cpp
|
||||
code/OpenDDLStream.cpp
|
||||
code/DDLNode.cpp
|
||||
code/Value.cpp
|
||||
include/openddlparser/OpenDDLCommon.h
|
||||
include/openddlparser/OpenDDLExport.h
|
||||
include/openddlparser/OpenDDLParser.h
|
||||
include/openddlparser/OpenDDLParserUtils.h
|
||||
include/openddlparser/OpenDDLCommon.h
|
||||
include/openddlparser/OpenDDLStream.h
|
||||
include/openddlparser/DDLNode.h
|
||||
include/openddlparser/Value.h
|
||||
README.md
|
||||
|
@ -59,6 +102,69 @@ SET ( openddl_parser_src
|
|||
|
||||
SOURCE_GROUP( code FILES ${openddl_parser_src} )
|
||||
|
||||
ADD_LIBRARY( openddl_parser SHARED
|
||||
${openddl_parser_src}
|
||||
if ( DDL_STATIC_LIBRARY )
|
||||
ADD_LIBRARY( openddl_parser STATIC
|
||||
${openddl_parser_src}
|
||||
)
|
||||
else()
|
||||
ADD_LIBRARY( openddl_parser SHARED
|
||||
${openddl_parser_src}
|
||||
)
|
||||
endif()
|
||||
|
||||
SET ( GTEST_PATH contrib/gtest-1.7.0 )
|
||||
|
||||
SET ( gtest_src
|
||||
${GTEST_PATH}/src/gtest-death-test.cc
|
||||
${GTEST_PATH}/src/gtest-filepath.cc
|
||||
${GTEST_PATH}/src/gtest-internal-inl.h
|
||||
${GTEST_PATH}/src/gtest-port.cc
|
||||
${GTEST_PATH}/src/gtest-printers.cc
|
||||
${GTEST_PATH}/src/gtest-test-part.cc
|
||||
${GTEST_PATH}/src/gtest-typed-test.cc
|
||||
${GTEST_PATH}/src/gtest.cc
|
||||
${GTEST_PATH}/src/gtest_main.cc
|
||||
)
|
||||
|
||||
SET( openddl_parser_unittest_src
|
||||
test/UnitTestCommon.h
|
||||
test/DDLNodeTest.cpp
|
||||
test/OpenDDLCommonTest.cpp
|
||||
test/OpenDDLExportTest.cpp
|
||||
test/OpenDDLParserTest.cpp
|
||||
test/OpenDDLParserUtilsTest.cpp
|
||||
test/OpenDDLStreamTest.cpp
|
||||
test/OpenDDLIntegrationTest.cpp
|
||||
test/ValueTest.cpp
|
||||
test/OpenDDLDefectsTest.cpp
|
||||
)
|
||||
|
||||
SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} )
|
||||
SOURCE_GROUP( gtest FILES ${gtest_src} )
|
||||
|
||||
ADD_EXECUTABLE( openddl_parser_unittest
|
||||
${gtest_src}
|
||||
${openddl_parser_unittest_src}
|
||||
)
|
||||
|
||||
target_link_libraries( openddl_parser_unittest openddl_parser ${CMAKE_THREAD_LIBS_INIT} )
|
||||
|
||||
SET( openddl_parser_demo_src
|
||||
demo/main.cpp
|
||||
)
|
||||
|
||||
if (COVERALLS)
|
||||
set(COVERAGE_SRCS ${gtest_src} ${openddl_parser_unittest_src} )
|
||||
|
||||
# Create the coveralls target.
|
||||
coveralls_setup(
|
||||
"${COVERAGE_SRCS}" # The source files.
|
||||
ON # If we should upload.
|
||||
"${PROJECT_SOURCE_DIR}/cmake/") # (Optional) Alternate project cmake module path.
|
||||
endif()
|
||||
|
||||
ADD_EXECUTABLE( openddl_parser_demo
|
||||
${openddl_parser_demo_src}
|
||||
)
|
||||
|
||||
target_link_libraries( openddl_parser_demo openddl_parser )
|
||||
|
|
|
@ -12,5 +12,8 @@ Improvements value interface, serveral bugfixes.
|
|||
- Henry Read ( henrya2 ):
|
||||
Static build option, Interface improvements
|
||||
|
||||
- (wise86-android)
|
||||
fix several mem-leaks
|
||||
|
||||
- Paul Holland ( pkholland ):
|
||||
Bugfixes.
|
||||
|
|
|
@ -11,7 +11,7 @@ Current coverity check status:
|
|||
<img alt="Coverity Scan Build Status"
|
||||
src="https://scan.coverity.com/projects/5606/badge.svg"/>
|
||||
</a>
|
||||
|
||||
Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls)
|
||||
Get the source code
|
||||
===================
|
||||
You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
|
||||
|
@ -25,7 +25,7 @@ After installing it you can open a console and enter:
|
|||
|
||||
> cmake CMakeLists.txt
|
||||
|
||||
This command will generate a build environment for your installed build enrironment ( for Visual-Studio-users the project files will be generated, for gcc-users the makefiles will be generated ).
|
||||
This command will generate a build environment for your preferred build tool ( for Visual-Studio-users the project files will be generated, for gcc-users the makefiles will be generated ).
|
||||
When using an IDE open the IDE and run the build. When using GNU-make type in your console:
|
||||
|
||||
> make
|
||||
|
|
|
@ -68,8 +68,8 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx,
|
|||
}
|
||||
|
||||
DDLNode::~DDLNode() {
|
||||
releaseDataType<Property>( m_properties );
|
||||
releaseDataType<Value>( m_value );
|
||||
delete m_properties;
|
||||
delete m_value;
|
||||
releaseReferencedNames( m_references );
|
||||
|
||||
delete m_dtArrayList;
|
||||
|
@ -77,6 +77,9 @@ DDLNode::~DDLNode() {
|
|||
if( s_allocatedNodes[ m_idx ] == this ) {
|
||||
s_allocatedNodes[ m_idx ] = ddl_nullptr;
|
||||
}
|
||||
for ( size_t i = 0; i<m_children.size(); i++ ){
|
||||
delete m_children[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
void DDLNode::attachParent( DDLNode *parent ) {
|
||||
|
@ -91,9 +94,8 @@ void DDLNode::attachParent( DDLNode *parent ) {
|
|||
}
|
||||
|
||||
void DDLNode::detachParent() {
|
||||
if( m_parent ) {
|
||||
std::vector<DDLNode*>::iterator it;
|
||||
it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this );
|
||||
if( ddl_nullptr != m_parent ) {
|
||||
DDLNodeIt it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this );
|
||||
if( m_parent->m_children.end() != it ) {
|
||||
m_parent->m_children.erase( it );
|
||||
}
|
||||
|
@ -126,6 +128,8 @@ const std::string &DDLNode::getName() const {
|
|||
}
|
||||
|
||||
void DDLNode::setProperties( Property *prop ) {
|
||||
if(m_properties!=ddl_nullptr)
|
||||
delete m_properties;
|
||||
m_properties = prop;
|
||||
}
|
||||
|
||||
|
@ -187,6 +191,10 @@ Reference *DDLNode::getReferences() const {
|
|||
return m_references;
|
||||
}
|
||||
|
||||
void DDLNode::dump(IOStreamBase &stream) {
|
||||
// Todo!
|
||||
}
|
||||
|
||||
DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) {
|
||||
const size_t idx( s_allocatedNodes.size() );
|
||||
DDLNode *node = new DDLNode( type, name, idx, parent );
|
||||
|
@ -197,7 +205,7 @@ DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLN
|
|||
|
||||
void DDLNode::releaseNodes() {
|
||||
if( s_allocatedNodes.size() > 0 ) {
|
||||
for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
|
||||
for( DDLNodeIt it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
|
||||
if( *it ) {
|
||||
delete *it;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
-----------------------------------------------------------------------------------------------*/
|
||||
#include <openddlparser/OpenDDLCommon.h>
|
||||
#include <openddlparser/DDLNode.h>
|
||||
#include <openddlparser/Value.h>
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
|
@ -84,7 +85,14 @@ Name::~Name() {
|
|||
m_id = ddl_nullptr;
|
||||
}
|
||||
|
||||
Reference::Reference()
|
||||
Name::Name( const Name &name ){
|
||||
m_type=name.m_type;
|
||||
m_id=new Text(name.m_id->m_buffer,name.m_id->m_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference::Reference()
|
||||
: m_numRefs( 0 )
|
||||
, m_referencedName( ddl_nullptr ) {
|
||||
// empty
|
||||
|
@ -96,8 +104,16 @@ Reference::Reference( size_t numrefs, Name **names )
|
|||
if ( numrefs > 0 ) {
|
||||
m_referencedName = new Name *[ numrefs ];
|
||||
for ( size_t i = 0; i < numrefs; i++ ) {
|
||||
Name *name = new Name( names[ i ]->m_type, names[ i ]->m_id );
|
||||
m_referencedName[ i ] = name;
|
||||
m_referencedName[ i ] = names[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference::Reference(const Reference &ref) {
|
||||
m_numRefs=ref.m_numRefs;
|
||||
if(m_numRefs!=0){
|
||||
m_referencedName = new Name*[m_numRefs];
|
||||
for ( size_t i = 0; i < m_numRefs; i++ ) {
|
||||
m_referencedName[i] = new Name(*ref.m_referencedName[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +123,7 @@ Reference::~Reference() {
|
|||
delete m_referencedName[ i ];
|
||||
}
|
||||
m_numRefs = 0;
|
||||
delete [] m_referencedName;
|
||||
m_referencedName = ddl_nullptr;
|
||||
}
|
||||
|
||||
|
@ -135,21 +152,30 @@ Property::Property( Text *id )
|
|||
}
|
||||
|
||||
Property::~Property() {
|
||||
m_key = ddl_nullptr;
|
||||
m_value = ddl_nullptr;
|
||||
m_ref = ddl_nullptr;;
|
||||
m_next = ddl_nullptr;;
|
||||
delete m_key;
|
||||
if(m_value!=ddl_nullptr)
|
||||
delete m_value;
|
||||
if(m_ref!=ddl_nullptr)
|
||||
delete(m_ref);
|
||||
if(m_next!=ddl_nullptr)
|
||||
delete m_next;
|
||||
}
|
||||
|
||||
DataArrayList::DataArrayList()
|
||||
: m_numItems( 0 )
|
||||
, m_dataList( ddl_nullptr )
|
||||
, m_next( ddl_nullptr ) {
|
||||
, m_next( ddl_nullptr )
|
||||
, m_refs(ddl_nullptr)
|
||||
, m_numRefs(0){
|
||||
// empty
|
||||
}
|
||||
|
||||
DataArrayList::~DataArrayList() {
|
||||
// empty
|
||||
delete m_dataList;
|
||||
if(m_next!=ddl_nullptr)
|
||||
delete m_next;
|
||||
if(m_refs!=ddl_nullptr)
|
||||
delete m_refs;
|
||||
}
|
||||
|
||||
size_t DataArrayList::size() {
|
||||
|
|
|
@ -29,60 +29,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
StreamFormatterBase::StreamFormatterBase() {
|
||||
|
||||
}
|
||||
|
||||
StreamFormatterBase::~StreamFormatterBase() {
|
||||
|
||||
}
|
||||
|
||||
std::string StreamFormatterBase::format( const std::string &statement ) {
|
||||
std::string tmp( statement );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
IOStreamBase::IOStreamBase( StreamFormatterBase *formatter )
|
||||
: m_formatter( formatter )
|
||||
, m_file( ddl_nullptr ) {
|
||||
if (ddl_nullptr == m_formatter) {
|
||||
m_formatter = new StreamFormatterBase;
|
||||
}
|
||||
}
|
||||
|
||||
IOStreamBase::~IOStreamBase() {
|
||||
delete m_formatter;
|
||||
m_formatter = ddl_nullptr;
|
||||
}
|
||||
|
||||
bool IOStreamBase::open( const std::string &name ) {
|
||||
m_file = ::fopen( name.c_str(), "a" );
|
||||
if (m_file == ddl_nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IOStreamBase::close() {
|
||||
if (ddl_nullptr == m_file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::fclose( m_file );
|
||||
m_file = ddl_nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t IOStreamBase::write( const std::string &statement ) {
|
||||
if (ddl_nullptr == m_file) {
|
||||
return 0;
|
||||
}
|
||||
std::string formatStatement = m_formatter->format( statement );
|
||||
return ::fwrite( formatStatement.c_str(), sizeof( char ), formatStatement.size(), m_file );
|
||||
}
|
||||
|
||||
struct DDLNodeIterator {
|
||||
const DDLNode::DllNodeList &m_childs;
|
||||
size_t m_idx;
|
||||
|
@ -280,7 +226,7 @@ bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std:
|
|||
statement += "[";
|
||||
char buffer[ 256 ];
|
||||
::memset( buffer, '\0', 256 * sizeof( char ) );
|
||||
sprintf( buffer, "%d", int(numItems) );
|
||||
sprintf( buffer, "%d", static_cast<int>( numItems ) );
|
||||
statement += buffer;
|
||||
statement += "]";
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
static const char *Version = "0.3.0";
|
||||
static const char *Version = "0.4.0";
|
||||
|
||||
namespace Grammar {
|
||||
static const char *OpenBracketToken = "{";
|
||||
|
@ -49,7 +49,7 @@ namespace Grammar {
|
|||
static const char *BoolFalse = "false";
|
||||
static const char *CommaSeparator = ",";
|
||||
|
||||
static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
|
||||
static const char *PrimitiveTypeToken[ Value::ddl_types_max ] = {
|
||||
"bool",
|
||||
"int8",
|
||||
"int16",
|
||||
|
@ -74,8 +74,8 @@ const char *getTypeToken( Value::ValueType type ) {
|
|||
static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
|
||||
std::stringstream stream;
|
||||
stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl;
|
||||
std::string full(in);
|
||||
std::string part(full.substr(0,50));
|
||||
std::string full( in );
|
||||
std::string part( full.substr( 0, 50 ) );
|
||||
stream << part;
|
||||
callback( ddl_error_msg, stream.str() );
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ static bool isIntegerType( Value::ValueType integerType ) {
|
|||
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -105,7 +106,7 @@ static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
|
|||
const std::string type( id->m_buffer );
|
||||
DDLNode *parent( parser->top() );
|
||||
DDLNode *node = DDLNode::create( type, "", parent );
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -193,10 +194,11 @@ size_t OpenDDLParser::getBufferSize() const {
|
|||
void OpenDDLParser::clear() {
|
||||
m_buffer.resize( 0 );
|
||||
if( ddl_nullptr != m_context ) {
|
||||
m_context->m_root = ddl_nullptr;
|
||||
delete m_context;
|
||||
m_context=ddl_nullptr;
|
||||
}
|
||||
|
||||
DDLNode::releaseNodes();
|
||||
// DDLNode::releaseNodes();
|
||||
}
|
||||
|
||||
bool OpenDDLParser::parse() {
|
||||
|
@ -212,11 +214,11 @@ bool OpenDDLParser::parse() {
|
|||
|
||||
// do the main parsing
|
||||
char *current( &m_buffer[ 0 ] );
|
||||
char *end( &m_buffer[ m_buffer.size() - 1 ] + 1 );
|
||||
char *end( &m_buffer[m_buffer.size() - 1 ] + 1 );
|
||||
size_t pos( current - &m_buffer[ 0 ] );
|
||||
while( pos < m_buffer.size() ) {
|
||||
current = parseNextNode( current, end );
|
||||
if(current==ddl_nullptr) {
|
||||
if ( current == ddl_nullptr ) {
|
||||
return false;
|
||||
}
|
||||
pos = current - &m_buffer[ 0 ];
|
||||
|
@ -245,7 +247,7 @@ static void dumpId( Identifier *id ) {
|
|||
if( ddl_nullptr != id ) {
|
||||
if ( ddl_nullptr != id->m_text.m_buffer ) {
|
||||
std::cout << id->m_text.m_buffer << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -271,14 +273,17 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
|||
} else {
|
||||
std::cerr << "nullptr returned by creating DDLNode." << std::endl;
|
||||
}
|
||||
delete id;
|
||||
|
||||
Name *name(ddl_nullptr);
|
||||
in = OpenDDLParser::parseName(in, end, &name);
|
||||
if( ddl_nullptr != name && ddl_nullptr != node ) {
|
||||
const std::string nodeName( name->m_id->m_buffer );
|
||||
node->setName( nodeName );
|
||||
delete name;
|
||||
}
|
||||
|
||||
|
||||
Property *first(ddl_nullptr);
|
||||
in = lookForNextToken(in, end);
|
||||
if (*in == Grammar::OpenPropertyToken[0]) {
|
||||
|
@ -303,7 +308,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
|||
prev = prop;
|
||||
}
|
||||
}
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
// set the properties
|
||||
|
@ -322,17 +327,17 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
|
|||
|
||||
bool error( false );
|
||||
in = lookForNextToken( in, end );
|
||||
if( *in == '{' ) {
|
||||
if( *in == *Grammar::OpenBracketToken) {
|
||||
// loop over all children ( data and nodes )
|
||||
do {
|
||||
in = parseStructureBody( in, end, error );
|
||||
if(in == ddl_nullptr){
|
||||
return ddl_nullptr;
|
||||
}
|
||||
} while ( *in != '}' );
|
||||
in++;
|
||||
} while ( *in != *Grammar::CloseBracketToken);
|
||||
++in;
|
||||
} else {
|
||||
in++;
|
||||
++in;
|
||||
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
|
||||
error = true;
|
||||
return ddl_nullptr;
|
||||
|
@ -373,7 +378,7 @@ static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayLi
|
|||
|
||||
char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
|
||||
if( !isNumeric( *in ) && !isCharacter( *in ) ) {
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
in = lookForNextToken( in, end );
|
||||
|
@ -431,7 +436,6 @@ DDLNode *OpenDDLParser::popNode() {
|
|||
|
||||
DDLNode *topNode( top() );
|
||||
m_stack.pop_back();
|
||||
|
||||
return topNode;
|
||||
}
|
||||
|
||||
|
@ -467,7 +471,14 @@ void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
|
|||
for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
|
||||
char *c( &buffer[readIdx] );
|
||||
// check for a comment
|
||||
if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
|
||||
if (isCommentOpenTag(c, end)) {
|
||||
++readIdx;
|
||||
while (!isCommentCloseTag(&buffer[readIdx], end)) {
|
||||
++readIdx;
|
||||
}
|
||||
++readIdx;
|
||||
++readIdx;
|
||||
} else if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
|
||||
newBuffer.push_back( buffer[ readIdx ] );
|
||||
} else {
|
||||
if( isComment<char>( c, end ) ) {
|
||||
|
@ -529,14 +540,17 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Text **id ) {
|
|||
// get size of id
|
||||
size_t idLen( 0 );
|
||||
char *start( in );
|
||||
while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != Grammar::OpenPropertyToken[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] && *in != '$' ) {
|
||||
while( !isSeparator( *in ) &&
|
||||
!isNewLine( *in ) && ( in != end ) &&
|
||||
*in != Grammar::OpenPropertyToken[ 0 ] &&
|
||||
*in != Grammar::ClosePropertyToken[ 0 ] &&
|
||||
*in != '$' ) {
|
||||
++in;
|
||||
++idLen;
|
||||
}
|
||||
|
||||
const size_t len( idLen );
|
||||
Text *newId = new Text( start, len );
|
||||
*id = newId;
|
||||
*id = new Text( start, len );
|
||||
|
||||
return in;
|
||||
}
|
||||
|
@ -552,7 +566,7 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
|
|||
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
|
||||
prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
|
||||
if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
|
||||
type = ( Value::ValueType ) i;
|
||||
type = static_cast<Value::ValueType>( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -567,14 +581,14 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
|
|||
bool ok( true );
|
||||
if( *in == Grammar::OpenArrayToken[ 0 ] ) {
|
||||
ok = false;
|
||||
in++;
|
||||
++in;
|
||||
char *start( in );
|
||||
while ( in != end ) {
|
||||
in++;
|
||||
++in;
|
||||
if( *in == Grammar::CloseArrayToken[ 0 ] ) {
|
||||
len = ::atoi( start );
|
||||
ok = true;
|
||||
in++;
|
||||
++in;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -623,10 +637,10 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean )
|
|||
char *start( in );
|
||||
size_t len( 0 );
|
||||
while( !isSeparator( *in ) && in != end ) {
|
||||
in++;
|
||||
len++;
|
||||
++in;
|
||||
++len;
|
||||
}
|
||||
len++;
|
||||
++len;
|
||||
int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
|
||||
if( 0 != res ) {
|
||||
res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
|
||||
|
@ -657,7 +671,7 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
|
|||
in = lookForNextToken( in, end );
|
||||
char *start( in );
|
||||
while( !isSeparator( *in ) && in != end ) {
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
if( isNumeric( *start ) ) {
|
||||
|
@ -671,29 +685,29 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
|
|||
*integer = ValueAllocator::allocPrimData( integerType );
|
||||
switch( integerType ) {
|
||||
case Value::ddl_int8:
|
||||
( *integer )->setInt8( (int8) value );
|
||||
break;
|
||||
( *integer )->setInt8( (int8) value );
|
||||
break;
|
||||
case Value::ddl_int16:
|
||||
( *integer )->setInt16( ( int16 ) value );
|
||||
break;
|
||||
( *integer )->setInt16( ( int16 ) value );
|
||||
break;
|
||||
case Value::ddl_int32:
|
||||
( *integer )->setInt32( ( int32 ) value );
|
||||
break;
|
||||
( *integer )->setInt32( ( int32 ) value );
|
||||
break;
|
||||
case Value::ddl_int64:
|
||||
( *integer )->setInt64( ( int64 ) value );
|
||||
break;
|
||||
( *integer )->setInt64( ( int64 ) value );
|
||||
break;
|
||||
case Value::ddl_unsigned_int8:
|
||||
( *integer )->setUnsignedInt8( (uint8) uvalue );
|
||||
break;
|
||||
( *integer )->setUnsignedInt8( (uint8) uvalue );
|
||||
break;
|
||||
case Value::ddl_unsigned_int16:
|
||||
( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
|
||||
break;
|
||||
( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
|
||||
break;
|
||||
case Value::ddl_unsigned_int32:
|
||||
( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
|
||||
break;
|
||||
( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
|
||||
break;
|
||||
case Value::ddl_unsigned_int64:
|
||||
( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
|
||||
break;
|
||||
( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -711,7 +725,7 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
|
|||
in = lookForNextToken( in, end );
|
||||
char *start( in );
|
||||
while( !isSeparator( *in ) && in != end ) {
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
// parse the float value
|
||||
|
@ -732,8 +746,7 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
|
|||
}
|
||||
|
||||
if( ok ) {
|
||||
if(floatType == Value::ddl_double)
|
||||
{
|
||||
if ( floatType == Value::ddl_double ) {
|
||||
const double value( atof( start ) );
|
||||
*floating = ValueAllocator::allocPrimData( Value::ddl_double );
|
||||
( *floating )->setDouble( value );
|
||||
|
@ -757,17 +770,17 @@ char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData
|
|||
size_t len( 0 );
|
||||
char *start( in );
|
||||
if( *start == '\"' ) {
|
||||
start++;
|
||||
in++;
|
||||
++start;
|
||||
++in;
|
||||
while( *in != '\"' && in != end ) {
|
||||
in++;
|
||||
len++;
|
||||
++in;
|
||||
++len;
|
||||
}
|
||||
|
||||
*stringData = ValueAllocator::allocPrimData( Value::ddl_string, len );
|
||||
::strncpy( ( char* ) ( *stringData )->m_data, start, len );
|
||||
( *stringData )->m_data[len] = '\0';
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
return in;
|
||||
|
@ -791,12 +804,12 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
|
|||
return in;
|
||||
}
|
||||
|
||||
in++;
|
||||
++in;
|
||||
if( *in != 'x' && *in != 'X' ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in++;
|
||||
++in;
|
||||
bool ok( true );
|
||||
char *start( in );
|
||||
int pos( 0 );
|
||||
|
@ -805,8 +818,8 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
|
|||
ok = false;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
in++;
|
||||
++pos;
|
||||
++in;
|
||||
}
|
||||
|
||||
if( !ok ) {
|
||||
|
@ -816,9 +829,9 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
|
|||
int value( 0 );
|
||||
while( pos > 0 ) {
|
||||
int v = hex2Decimal( *start );
|
||||
pos--;
|
||||
--pos;
|
||||
value = ( value << 4 ) | v;
|
||||
start++;
|
||||
++start;
|
||||
}
|
||||
|
||||
*data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 );
|
||||
|
@ -841,7 +854,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
|
|||
if( ddl_nullptr != id ) {
|
||||
in = lookForNextToken( in, end );
|
||||
if( *in == '=' ) {
|
||||
in++;
|
||||
++in;
|
||||
in = getNextToken( in, end );
|
||||
Value *primData( ddl_nullptr );
|
||||
if( isInteger( in, end ) ) {
|
||||
|
@ -862,6 +875,8 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
|
|||
( *prop )->m_ref = ref;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delete id;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -878,7 +893,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
|
|||
|
||||
in = lookForNextToken( in, end );
|
||||
if( *in == '{' ) {
|
||||
in++;
|
||||
++in;
|
||||
Value *current( ddl_nullptr ), *prev( ddl_nullptr );
|
||||
while( '}' != *in ) {
|
||||
current = ddl_nullptr;
|
||||
|
@ -934,7 +949,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
|
|||
prev->setNext( current );
|
||||
prev = current;
|
||||
}
|
||||
numValues++;
|
||||
++numValues;
|
||||
}
|
||||
|
||||
in = getNextSeparator( in, end );
|
||||
|
@ -942,7 +957,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
|
|||
break;
|
||||
}
|
||||
}
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
return in;
|
||||
|
@ -972,7 +987,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType ty
|
|||
|
||||
in = lookForNextToken( in, end );
|
||||
if( *in == Grammar::OpenBracketToken[ 0 ] ) {
|
||||
in++;
|
||||
++in;
|
||||
Value *currentValue( ddl_nullptr );
|
||||
Reference *refs( ddl_nullptr );
|
||||
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
|
||||
|
@ -995,7 +1010,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType ty
|
|||
}
|
||||
} while( Grammar::CommaSeparator[ 0 ] == *in && in != end );
|
||||
in = lookForNextToken( in, end );
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
return in;
|
||||
|
|
|
@ -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() {
|
||||
// empty
|
||||
if(m_data!=ddl_nullptr) {
|
||||
if (m_type == ddl_ref ) {
|
||||
Reference *tmp = (Reference *) m_data;
|
||||
if (tmp != ddl_nullptr)
|
||||
delete tmp;
|
||||
}else
|
||||
delete[] m_data;
|
||||
|
||||
}
|
||||
if(m_next!=ddl_nullptr)
|
||||
delete m_next;
|
||||
}
|
||||
|
||||
void Value::setBool( bool value ) {
|
||||
|
@ -273,13 +283,7 @@ void Value::setRef( Reference *ref ) {
|
|||
delete [] m_data;
|
||||
}
|
||||
|
||||
m_data = new unsigned char[ sizeof( Reference ) ];
|
||||
Reference *myRef = ( Reference * ) m_data;
|
||||
myRef->m_numRefs = ref->m_numRefs;
|
||||
myRef->m_referencedName = new Name *[ myRef->m_numRefs ];
|
||||
for ( size_t i = 0; i < myRef->m_numRefs; i++ ) {
|
||||
myRef->m_referencedName[ i ] = new Name( ref->m_referencedName[ i ]->m_type, ref->m_referencedName[ i ]->m_id );
|
||||
}
|
||||
m_data = (unsigned char*) new Reference(*ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +294,7 @@ Reference *Value::getRef() const {
|
|||
return (Reference*) m_data;
|
||||
}
|
||||
|
||||
void Value::dump() {
|
||||
void Value::dump( IOStreamBase &stream ) {
|
||||
switch( m_type ) {
|
||||
case ddl_none:
|
||||
std::cout << "None" << std::endl;
|
||||
|
@ -350,7 +354,7 @@ Value *Value::getNext() const {
|
|||
return m_next;
|
||||
}
|
||||
|
||||
size_t Value::size(){
|
||||
size_t Value::size() const{
|
||||
size_t result=1;
|
||||
Value *n=m_next;
|
||||
while( n!=ddl_nullptr) {
|
||||
|
@ -366,7 +370,6 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
|
|||
}
|
||||
|
||||
Value *data = new Value( type );
|
||||
data->m_type = type;
|
||||
switch( type ) {
|
||||
case Value::ddl_bool:
|
||||
data->m_size = sizeof( bool );
|
||||
|
@ -405,10 +408,10 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
|
|||
data->m_size = sizeof( double );
|
||||
break;
|
||||
case Value::ddl_string:
|
||||
data->m_size = sizeof( char );
|
||||
data->m_size = sizeof( char )*(len+1);
|
||||
break;
|
||||
case Value::ddl_ref:
|
||||
data->m_size = sizeof( char );
|
||||
data->m_size = 0;
|
||||
break;
|
||||
case Value::ddl_none:
|
||||
case Value::ddl_types_max:
|
||||
|
@ -417,12 +420,8 @@ Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
|
|||
}
|
||||
|
||||
if( data->m_size ) {
|
||||
size_t len1( len );
|
||||
if( Value::ddl_string == type ) {
|
||||
len1++;
|
||||
}
|
||||
data->m_size *= len1;
|
||||
data->m_data = new unsigned char[ data->m_size ];
|
||||
::memset(data->m_data,0,data->m_size);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
|
|
@ -29,6 +29,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
// Forward declarations
|
||||
class IOStreamBase;
|
||||
class Value;
|
||||
class OpenDDLParser;
|
||||
|
||||
|
@ -53,6 +55,9 @@ public:
|
|||
/// @brief The child-node-list type.
|
||||
typedef std::vector<DDLNode*> DllNodeList;
|
||||
|
||||
/// @brief The child-node-list iterator.
|
||||
typedef std::vector<DDLNode*>::iterator DDLNodeIt;
|
||||
|
||||
public:
|
||||
/// @brief The class destructor.
|
||||
~DDLNode();
|
||||
|
@ -81,7 +86,7 @@ public:
|
|||
const std::string &getType() const;
|
||||
|
||||
/// Set the name of the DDLNode instance.
|
||||
/// @param type [in] The name.
|
||||
/// @param name [in] The name.
|
||||
void setName( const std::string &name );
|
||||
|
||||
/// @brief Returns the name of the DDLNode instance.
|
||||
|
@ -89,7 +94,7 @@ public:
|
|||
const std::string &getName() const;
|
||||
|
||||
/// @brief Set a new property set.
|
||||
/// @param prop [in] The first element of the property set.
|
||||
/// @param prop [in] The first element of the property set.
|
||||
void setProperties( Property *prop );
|
||||
|
||||
/// @brief Returns the first element of the assigned property set.
|
||||
|
@ -97,7 +102,7 @@ public:
|
|||
Property *getProperties() const;
|
||||
|
||||
/// @brief Looks for a given property.
|
||||
/// @param name [in] The name for the property to look for.
|
||||
/// @param name [in] The name for the property to look for.
|
||||
/// @return true, if a corresponding property is assigned to the node, false if not.
|
||||
bool hasProperty( const std::string &name );
|
||||
|
||||
|
@ -106,12 +111,12 @@ public:
|
|||
bool hasProperties() const;
|
||||
|
||||
/// @brief Search for a given property and returns it. Will return ddl_nullptr if no property was found.
|
||||
/// @param name [in] The name for the property to look for.
|
||||
/// @param name [in] The name for the property to look for.
|
||||
/// @return The property or ddl_nullptr if no property was found.
|
||||
Property *findPropertyByName( const std::string &name );
|
||||
|
||||
/// @brief Set a new value set.
|
||||
/// @param val [in] The first value instance of the value set.
|
||||
/// @param val [in] The first value instance of the value set.
|
||||
void setValue( Value *val );
|
||||
|
||||
/// @brief Returns the first element of the assigned value set.
|
||||
|
@ -119,7 +124,7 @@ public:
|
|||
Value *getValue() const;
|
||||
|
||||
/// @brief Set a new DataArrayList.
|
||||
/// @param val [in] The DataArrayList instance.
|
||||
/// @param dtArrayList [in] The DataArrayList instance.
|
||||
void setDataArrayList( DataArrayList *dtArrayList );
|
||||
|
||||
/// @brief Returns the DataArrayList.
|
||||
|
@ -127,17 +132,21 @@ public:
|
|||
DataArrayList *getDataArrayList() const;
|
||||
|
||||
/// @brief Set a new Reference set.
|
||||
/// @param val [in] The first value instance of the Reference set.
|
||||
/// @param refs [in] The first value instance of the Reference set.
|
||||
void setReferences( Reference *refs );
|
||||
|
||||
/// @brief Returns the first element of the assigned Reference set.
|
||||
/// @return The first property of the assigned Reference set.
|
||||
Reference *getReferences() const;
|
||||
|
||||
/// @brief Will dump the node into the stream.
|
||||
/// @param stream [in] The stream to write to.
|
||||
void dump(IOStreamBase &stream);
|
||||
|
||||
/// @brief The creation method.
|
||||
/// @param type [in] The DDLNode type.
|
||||
/// @param name [in] The name for the new DDLNode instance.
|
||||
/// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there.
|
||||
/// @param type [in] The DDLNode type.
|
||||
/// @param name [in] The name for the new DDLNode instance.
|
||||
/// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there.
|
||||
/// @return The new created node instance.
|
||||
static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr );
|
||||
|
||||
|
|
|
@ -148,12 +148,12 @@ struct DLL_ODDLPARSER_EXPORT Name {
|
|||
/// @param type [in] The name type.
|
||||
/// @param id [in] The id.
|
||||
Name( NameType type, Text *id );
|
||||
|
||||
Name( const Name &name );
|
||||
/// @brief The destructor.
|
||||
~Name();
|
||||
|
||||
private:
|
||||
Name( const Name & ) ddl_no_copy;
|
||||
|
||||
Name &operator = ( const Name& ) ddl_no_copy;
|
||||
};
|
||||
|
||||
|
@ -164,7 +164,7 @@ struct DLL_ODDLPARSER_EXPORT Reference {
|
|||
|
||||
/// @brief The default constructor.
|
||||
Reference();
|
||||
|
||||
Reference( const Reference &ref );
|
||||
/// @brief The constructor with an array of ref names.
|
||||
/// @param numrefs [in] The number of ref names.
|
||||
/// @param names [in] The ref names.
|
||||
|
@ -178,7 +178,6 @@ struct DLL_ODDLPARSER_EXPORT Reference {
|
|||
size_t sizeInBytes();
|
||||
|
||||
private:
|
||||
Reference( const Reference & ) ddl_no_copy;
|
||||
Reference &operator = ( const Reference & ) ddl_no_copy;
|
||||
};
|
||||
|
||||
|
|
|
@ -23,37 +23,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#pragma once
|
||||
|
||||
#include <openddlparser/OpenDDLCommon.h>
|
||||
#include <openddlparser/OpenDDLStream.h>
|
||||
#include <openddlparser/Value.h>
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/// @ingroup IOStreamBase
|
||||
/// @brief This class represents the stream to write out.
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DLL_ODDLPARSER_EXPORT StreamFormatterBase {
|
||||
public:
|
||||
StreamFormatterBase();
|
||||
virtual ~StreamFormatterBase();
|
||||
virtual std::string format( const std::string &statement );
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/// @ingroup IOStreamBase
|
||||
/// @brief This class represents the stream to write out.
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DLL_ODDLPARSER_EXPORT IOStreamBase {
|
||||
public:
|
||||
IOStreamBase( StreamFormatterBase *formatter = ddl_nullptr );
|
||||
virtual ~IOStreamBase();
|
||||
virtual bool open( const std::string &anme );
|
||||
virtual bool close();
|
||||
virtual size_t write( const std::string &statement );
|
||||
|
||||
private:
|
||||
StreamFormatterBase *m_formatter;
|
||||
FILE *m_file;
|
||||
};
|
||||
// Forward declarations
|
||||
class IOStreamBase;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
///
|
||||
|
|
|
@ -39,6 +39,16 @@ struct Identifier;
|
|||
struct Reference;
|
||||
struct Property;
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isEmbeddedCommentOpenTag( T *in, T *end ) {
|
||||
if ( in == '/' && in+1 == '*' ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @brief Utility function to search for the next token or the end of the buffer.
|
||||
/// @param in [in] The start position in the buffer.
|
||||
/// @param end [in] The end position in the buffer.
|
||||
|
@ -47,7 +57,7 @@ struct Property;
|
|||
template<class T>
|
||||
inline
|
||||
T *lookForNextToken( T *in, T *end ) {
|
||||
while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
|
||||
while( ( in != end ) && ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) ) {
|
||||
in++;
|
||||
}
|
||||
return in;
|
||||
|
|
|
@ -84,7 +84,7 @@ static const unsigned char chartype_table[ 256 ] = {
|
|||
template<class T>
|
||||
inline
|
||||
bool isNumeric( const T in ) {
|
||||
return ( chartype_table[ static_cast<int>( in ) ] == 1 );
|
||||
return ( chartype_table[ static_cast<size_t>( in ) ] == 1 );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
@ -98,7 +98,7 @@ inline
|
|||
bool isInteger( T *in, T *end ) {
|
||||
if( in != end ) {
|
||||
if( *in == '-' ) {
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ bool isInteger( T *in, T *end ) {
|
|||
if( !result ) {
|
||||
break;
|
||||
}
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -119,7 +119,7 @@ inline
|
|||
bool isFloat( T *in, T *end ) {
|
||||
if( in != end ) {
|
||||
if( *in == '-' ) {
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,12 +134,12 @@ bool isFloat( T *in, T *end ) {
|
|||
if( !result ) {
|
||||
return false;
|
||||
}
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
// check for 1<.>0f
|
||||
if( *in == '.' ) {
|
||||
in++;
|
||||
++in;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ bool isFloat( T *in, T *end ) {
|
|||
if( !result ) {
|
||||
return false;
|
||||
}
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -208,7 +208,7 @@ template<class T>
|
|||
inline
|
||||
static T *getNextSeparator( T *in, T *end ) {
|
||||
while( !isSeparator( *in ) || in == end ) {
|
||||
in++;
|
||||
++in;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
@ -250,5 +250,33 @@ bool isComment( T *in, T *end ) {
|
|||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isCommentOpenTag(T *in, T *end ) {
|
||||
if (*in == '/') {
|
||||
if (in + 1 != end) {
|
||||
if (*(in + 1) == '*') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isCommentCloseTag(T *in, T *end) {
|
||||
if (*in == '*') {
|
||||
if (in + 1 != end) {
|
||||
if (*(in + 1) == '/') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
END_ODDLPARSER_NS
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
// Forward declarations
|
||||
struct ValueAllocator;
|
||||
|
||||
class IOStreamBase;
|
||||
|
||||
///------------------------------------------------------------------------------------------------
|
||||
/// @brief This class implements a value.
|
||||
///
|
||||
|
@ -213,7 +216,7 @@ public:
|
|||
double getDouble() const;
|
||||
|
||||
/// @brief Assigns a std::string to the value.
|
||||
/// @param value [in] The value.
|
||||
/// @param str [in] The value.
|
||||
void setString( const std::string &str );
|
||||
|
||||
/// @brief Returns the std::string value.
|
||||
|
@ -229,7 +232,8 @@ public:
|
|||
Reference *getRef() const;
|
||||
|
||||
/// @brief Dumps the value.
|
||||
void dump();
|
||||
/// @param stream [in] The stream to write in.
|
||||
void dump( IOStreamBase &stream );
|
||||
|
||||
/// @brief Assigns the next value.
|
||||
/// @param next [n] The next value.
|
||||
|
@ -241,7 +245,7 @@ public:
|
|||
|
||||
/// @brief Gets the length of the array.
|
||||
/// @return The number of items in the array.
|
||||
size_t size();
|
||||
size_t size() const;
|
||||
|
||||
ValueType m_type;
|
||||
size_t m_size;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
@ -88,7 +88,7 @@ void Triangle::Clear()
|
|||
points_[0]=points_[1]=points_[2] = NULL;
|
||||
}
|
||||
|
||||
void Triangle::ClearNeighbor(Triangle *triangle )
|
||||
void Triangle::ClearNeighbor(const Triangle *triangle )
|
||||
{
|
||||
if( neighbors_[0] == triangle )
|
||||
{
|
||||
|
@ -96,14 +96,14 @@ void Triangle::ClearNeighbor(Triangle *triangle )
|
|||
}
|
||||
else if( neighbors_[1] == triangle )
|
||||
{
|
||||
neighbors_[1] = NULL;
|
||||
neighbors_[1] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
neighbors_[2] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Triangle::ClearNeighbors()
|
||||
{
|
||||
neighbors_[0] = NULL;
|
||||
|
@ -116,13 +116,9 @@ void Triangle::ClearDelunayEdges()
|
|||
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);
|
||||
//double x = cw->x;
|
||||
//double y = cw->y;
|
||||
//x = p.x;
|
||||
//y = p.y;
|
||||
return PointCW(*cw);
|
||||
}
|
||||
|
||||
|
@ -164,8 +160,7 @@ int Triangle::Index(const Point* p)
|
|||
return 2;
|
||||
}
|
||||
assert(0);
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
||||
|
@ -192,7 +187,7 @@ int Triangle::EdgeIndex(const Point* p1, const Point* p2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void Triangle::MarkConstrainedEdge(const int index)
|
||||
void Triangle::MarkConstrainedEdge(int index)
|
||||
{
|
||||
constrained_edge[index] = true;
|
||||
}
|
||||
|
@ -215,7 +210,7 @@ void Triangle::MarkConstrainedEdge(Point* p, Point* q)
|
|||
}
|
||||
|
||||
// The point counter-clockwise to given point
|
||||
Point* Triangle::PointCW(Point& point)
|
||||
Point* Triangle::PointCW(const Point& point)
|
||||
{
|
||||
if (&point == points_[0]) {
|
||||
return points_[2];
|
||||
|
@ -225,12 +220,11 @@ Point* Triangle::PointCW(Point& point)
|
|||
return points_[1];
|
||||
}
|
||||
assert(0);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// The point counter-clockwise to given point
|
||||
Point* Triangle::PointCCW(Point& point)
|
||||
Point* Triangle::PointCCW(const Point& point)
|
||||
{
|
||||
if (&point == points_[0]) {
|
||||
return points_[1];
|
||||
|
@ -240,12 +234,11 @@ Point* Triangle::PointCCW(Point& point)
|
|||
return points_[0];
|
||||
}
|
||||
assert(0);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// The neighbor clockwise to given point
|
||||
Triangle* Triangle::NeighborCW(Point& point)
|
||||
Triangle* Triangle::NeighborCW(const Point& point)
|
||||
{
|
||||
if (&point == points_[0]) {
|
||||
return neighbors_[1];
|
||||
|
@ -256,7 +249,7 @@ Triangle* Triangle::NeighborCW(Point& point)
|
|||
}
|
||||
|
||||
// The neighbor counter-clockwise to given point
|
||||
Triangle* Triangle::NeighborCCW(Point& point)
|
||||
Triangle* Triangle::NeighborCCW(const Point& point)
|
||||
{
|
||||
if (&point == points_[0]) {
|
||||
return neighbors_[2];
|
||||
|
@ -266,7 +259,7 @@ Triangle* Triangle::NeighborCCW(Point& point)
|
|||
return neighbors_[1];
|
||||
}
|
||||
|
||||
bool Triangle::GetConstrainedEdgeCCW(Point& p)
|
||||
bool Triangle::GetConstrainedEdgeCCW(const Point& p)
|
||||
{
|
||||
if (&p == points_[0]) {
|
||||
return constrained_edge[2];
|
||||
|
@ -276,7 +269,7 @@ bool Triangle::GetConstrainedEdgeCCW(Point& p)
|
|||
return constrained_edge[1];
|
||||
}
|
||||
|
||||
bool Triangle::GetConstrainedEdgeCW(Point& p)
|
||||
bool Triangle::GetConstrainedEdgeCW(const Point& p)
|
||||
{
|
||||
if (&p == points_[0]) {
|
||||
return constrained_edge[1];
|
||||
|
@ -286,7 +279,7 @@ bool Triangle::GetConstrainedEdgeCW(Point& p)
|
|||
return constrained_edge[0];
|
||||
}
|
||||
|
||||
void Triangle::SetConstrainedEdgeCCW(Point& p, bool ce)
|
||||
void Triangle::SetConstrainedEdgeCCW(const Point& p, bool ce)
|
||||
{
|
||||
if (&p == points_[0]) {
|
||||
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]) {
|
||||
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]) {
|
||||
return delaunay_edge[2];
|
||||
|
@ -318,7 +311,7 @@ bool Triangle::GetDelunayEdgeCCW(Point& p)
|
|||
return delaunay_edge[1];
|
||||
}
|
||||
|
||||
bool Triangle::GetDelunayEdgeCW(Point& p)
|
||||
bool Triangle::GetDelunayEdgeCW(const Point& p)
|
||||
{
|
||||
if (&p == points_[0]) {
|
||||
return delaunay_edge[1];
|
||||
|
@ -328,7 +321,7 @@ bool Triangle::GetDelunayEdgeCW(Point& p)
|
|||
return delaunay_edge[0];
|
||||
}
|
||||
|
||||
void Triangle::SetDelunayEdgeCCW(Point& p, bool e)
|
||||
void Triangle::SetDelunayEdgeCCW(const Point& p, bool e)
|
||||
{
|
||||
if (&p == points_[0]) {
|
||||
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]) {
|
||||
delaunay_edge[1] = e;
|
||||
|
@ -351,7 +344,7 @@ void Triangle::SetDelunayEdgeCW(Point& p, bool e)
|
|||
}
|
||||
|
||||
// The neighbor across to given point
|
||||
Triangle& Triangle::NeighborAcross(Point& opoint)
|
||||
Triangle& Triangle::NeighborAcross(const Point& opoint)
|
||||
{
|
||||
if (&opoint == points_[0]) {
|
||||
return *neighbors_[0];
|
||||
|
@ -369,5 +362,4 @@ void Triangle::DebugPrint()
|
|||
cout << points_[2]->x << "," << points_[2]->y << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -113,7 +113,7 @@ struct Point {
|
|||
/// Convert this point into a unit point. Returns the Length.
|
||||
double Normalize()
|
||||
{
|
||||
double len = Length();
|
||||
const double len = Length();
|
||||
x /= len;
|
||||
y /= len;
|
||||
return len;
|
||||
|
@ -162,50 +162,50 @@ bool constrained_edge[3];
|
|||
/// Flags to determine if an edge is a Delauney edge
|
||||
bool delaunay_edge[3];
|
||||
|
||||
Point* GetPoint(const int& index);
|
||||
Point* PointCW(Point& point);
|
||||
Point* PointCCW(Point& point);
|
||||
Point* OppositePoint(Triangle& t, Point& p);
|
||||
Point* GetPoint(int index);
|
||||
Point* PointCW(const Point& point);
|
||||
Point* PointCCW(const Point& point);
|
||||
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(Triangle& t);
|
||||
|
||||
void MarkConstrainedEdge(const int index);
|
||||
void MarkConstrainedEdge(int index);
|
||||
void MarkConstrainedEdge(Edge& edge);
|
||||
void MarkConstrainedEdge(Point* p, Point* q);
|
||||
|
||||
int Index(const Point* p);
|
||||
int EdgeIndex(const Point* p1, const Point* p2);
|
||||
|
||||
Triangle* NeighborCW(Point& point);
|
||||
Triangle* NeighborCCW(Point& point);
|
||||
bool GetConstrainedEdgeCCW(Point& p);
|
||||
bool GetConstrainedEdgeCW(Point& p);
|
||||
void SetConstrainedEdgeCCW(Point& p, bool ce);
|
||||
void SetConstrainedEdgeCW(Point& p, bool ce);
|
||||
bool GetDelunayEdgeCCW(Point& p);
|
||||
bool GetDelunayEdgeCW(Point& p);
|
||||
void SetDelunayEdgeCCW(Point& p, bool e);
|
||||
void SetDelunayEdgeCW(Point& p, bool e);
|
||||
Triangle* NeighborCW(const Point& point);
|
||||
Triangle* NeighborCCW(const Point& point);
|
||||
bool GetConstrainedEdgeCCW(const Point& p);
|
||||
bool GetConstrainedEdgeCW(const Point& p);
|
||||
void SetConstrainedEdgeCCW(const Point& p, bool ce);
|
||||
void SetConstrainedEdgeCW(const Point& p, bool ce);
|
||||
bool GetDelunayEdgeCCW(const Point& p);
|
||||
bool GetDelunayEdgeCW(const Point& p);
|
||||
void SetDelunayEdgeCCW(const 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(Point* p, Point* q);
|
||||
bool Contains(const Point* p, const Point* q);
|
||||
void Legalize(Point& point);
|
||||
void Legalize(Point& opoint, Point& npoint);
|
||||
/**
|
||||
* Clears all references to all other triangles and points
|
||||
*/
|
||||
void Clear();
|
||||
void ClearNeighbor(Triangle *triangle );
|
||||
void ClearNeighbor(const Triangle *triangle);
|
||||
void ClearNeighbors();
|
||||
void ClearDelunayEdges();
|
||||
|
||||
inline bool IsInterior();
|
||||
inline void IsInterior(bool b);
|
||||
|
||||
Triangle& NeighborAcross(Point& opoint);
|
||||
Triangle& NeighborAcross(const Point& opoint);
|
||||
|
||||
void DebugPrint();
|
||||
|
||||
|
@ -258,7 +258,7 @@ 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.
|
||||
|
@ -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
|
||||
/// 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);
|
||||
}
|
||||
|
||||
inline Point* Triangle::GetPoint(const int& index)
|
||||
inline Point* Triangle::GetPoint(int index)
|
||||
{
|
||||
return points_[index];
|
||||
}
|
||||
|
||||
inline Triangle* Triangle::GetNeighbor(const int& index)
|
||||
inline Triangle* Triangle::GetNeighbor(int 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];
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ inline bool Triangle::Contains(const Edge& e)
|
|||
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);
|
||||
}
|
||||
|
@ -324,6 +324,4 @@ inline void Triangle::IsInterior(bool b)
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
@ -28,18 +28,26 @@
|
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
// Otherwise #defines like M_PI are undeclared under Visual Studio
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include <exception>
|
||||
#include <math.h>
|
||||
|
||||
// C99 removes M_PI from math.h
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327
|
||||
#endif
|
||||
|
||||
namespace p2t {
|
||||
|
||||
const double PI = 3.1415926535897932384626433832795029;
|
||||
const double PI_2 = 2 * PI;
|
||||
const double PI_3div4 = 3 * PI / 4;
|
||||
const double EPSILON = 1e-15;
|
||||
const double PI_3div4 = 3 * M_PI / 4;
|
||||
const double PI_div2 = 1.57079632679489661923;
|
||||
const double EPSILON = 1e-12;
|
||||
|
||||
enum Orientation { CW, CCW, COLLINEAR };
|
||||
|
||||
|
@ -53,7 +61,7 @@ enum Orientation { CW, CCW, COLLINEAR };
|
|||
* = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
|
||||
* </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 detright = (pa.y - pc.y) * (pb.x - pc.x);
|
||||
|
@ -66,6 +74,7 @@ Orientation Orient2d(Point& pa, Point& pb, Point& pc)
|
|||
return CW;
|
||||
}
|
||||
|
||||
/*
|
||||
bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
|
||||
{
|
||||
double pdx = pd.x;
|
||||
|
@ -97,7 +106,22 @@ bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
|
|||
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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
@ -35,5 +35,4 @@
|
|||
#include "common/shapes.h"
|
||||
#include "sweep/cdt.h"
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -39,7 +39,7 @@ AdvancingFront::AdvancingFront(Node& head, Node& tail)
|
|||
search_node_ = &head;
|
||||
}
|
||||
|
||||
Node* AdvancingFront::LocateNode(const double& x)
|
||||
Node* AdvancingFront::LocateNode(double x)
|
||||
{
|
||||
Node* node = search_node_;
|
||||
|
||||
|
@ -61,7 +61,7 @@ Node* AdvancingFront::LocateNode(const double& x)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Node* AdvancingFront::FindSearchNode(const double& x)
|
||||
Node* AdvancingFront::FindSearchNode(double x)
|
||||
{
|
||||
(void)x; // suppress compiler warnings "unused parameter 'x'"
|
||||
// TODO: implement BST index
|
||||
|
@ -105,5 +105,4 @@ AdvancingFront::~AdvancingFront()
|
|||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -74,7 +74,7 @@ Node* search();
|
|||
void set_search(Node* node);
|
||||
|
||||
/// Locate insertion point along advancing front
|
||||
Node* LocateNode(const double& x);
|
||||
Node* LocateNode(double x);
|
||||
|
||||
Node* LocatePoint(const Point* point);
|
||||
|
||||
|
@ -82,7 +82,7 @@ private:
|
|||
|
||||
Node* head_, *tail_, *search_node_;
|
||||
|
||||
Node* FindSearchNode(const double& x);
|
||||
Node* FindSearchNode(double x);
|
||||
};
|
||||
|
||||
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
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
@ -32,13 +32,13 @@
|
|||
|
||||
namespace p2t {
|
||||
|
||||
CDT::CDT(std::vector<Point*> polyline)
|
||||
CDT::CDT(const std::vector<Point*>& polyline)
|
||||
{
|
||||
sweep_context_ = new SweepContext(polyline);
|
||||
sweep_ = new Sweep;
|
||||
}
|
||||
|
||||
void CDT::AddHole(std::vector<Point*> polyline)
|
||||
void CDT::AddHole(const std::vector<Point*>& polyline)
|
||||
{
|
||||
sweep_context_->AddHole(polyline);
|
||||
}
|
||||
|
@ -68,5 +68,4 @@ CDT::~CDT()
|
|||
delete sweep_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
@ -28,7 +28,7 @@
|
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CDT_H
|
||||
#define CDT_H
|
||||
|
||||
|
@ -37,11 +37,11 @@
|
|||
#include "sweep.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Mason Green <mason.green@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace p2t {
|
||||
|
||||
class CDT
|
||||
|
@ -50,40 +50,40 @@ public:
|
|||
|
||||
/**
|
||||
* Constructor - add polyline with non repeating points
|
||||
*
|
||||
*
|
||||
* @param polyline
|
||||
*/
|
||||
CDT(std::vector<Point*> polyline);
|
||||
|
||||
CDT(const std::vector<Point*>& polyline);
|
||||
|
||||
/**
|
||||
* Destructor - clean up memory
|
||||
*/
|
||||
~CDT();
|
||||
|
||||
|
||||
/**
|
||||
* Add a hole
|
||||
*
|
||||
*
|
||||
* @param polyline
|
||||
*/
|
||||
void AddHole(std::vector<Point*> polyline);
|
||||
|
||||
void AddHole(const std::vector<Point*>& polyline);
|
||||
|
||||
/**
|
||||
* Add a steiner point
|
||||
*
|
||||
*
|
||||
* @param point
|
||||
*/
|
||||
void AddPoint(Point* point);
|
||||
|
||||
|
||||
/**
|
||||
* Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
|
||||
*/
|
||||
void Triangulate();
|
||||
|
||||
|
||||
/**
|
||||
* Get CDT triangles
|
||||
*/
|
||||
std::vector<Triangle*> GetTriangles();
|
||||
|
||||
|
||||
/**
|
||||
* Get triangle map
|
||||
*/
|
||||
|
@ -94,7 +94,7 @@ public:
|
|||
/**
|
||||
* Internals
|
||||
*/
|
||||
|
||||
|
||||
SweepContext* sweep_context_;
|
||||
Sweep* sweep_;
|
||||
|
||||
|
@ -102,4 +102,4 @@ public:
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -49,7 +49,7 @@ void Sweep::Triangulate(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);
|
||||
Node* node = &PointEvent(tcx, point);
|
||||
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");
|
||||
if( triangle->Contains(&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
|
||||
tcx.edge_event.constrained_edge->q = p1;
|
||||
triangle = &triangle->NeighborAcross(point);
|
||||
|
@ -137,7 +137,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
|
|||
|
||||
if( triangle->Contains(&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
|
||||
tcx.edge_event.constrained_edge->q = p2;
|
||||
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)
|
||||
{
|
||||
int index = triangle.EdgeIndex(&ep, &eq);
|
||||
const int index = triangle.EdgeIndex(&ep, &eq);
|
||||
|
||||
if (index != -1) {
|
||||
triangle.MarkConstrainedEdge(index);
|
||||
|
@ -230,8 +230,8 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
|
|||
Node* node = n.next;
|
||||
|
||||
while (node->next) {
|
||||
double angle = HoleAngle(*node);
|
||||
if (angle > PI_2 || angle < -PI_2) break;
|
||||
// if HoleAngle exceeds 90 degrees then break.
|
||||
if (LargeHole_DontFill(node)) break;
|
||||
Fill(tcx, *node);
|
||||
node = node->next;
|
||||
}
|
||||
|
@ -240,29 +240,81 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
|
|||
node = n.prev;
|
||||
|
||||
while (node->prev) {
|
||||
double angle = HoleAngle(*node);
|
||||
if (angle > PI_2 || angle < -PI_2) break;
|
||||
// if HoleAngle exceeds 90 degrees then break.
|
||||
if (LargeHole_DontFill(node)) break;
|
||||
Fill(tcx, *node);
|
||||
node = node->prev;
|
||||
}
|
||||
|
||||
// Fill right basins
|
||||
if (n.next && n.next->next) {
|
||||
double angle = BasinAngle(n);
|
||||
const double angle = BasinAngle(n);
|
||||
if (angle < PI_3div4) {
|
||||
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;
|
||||
double ay = node.point->y - node.next->next->point->y;
|
||||
const double ax = node.point->x - node.next->next->point->x;
|
||||
const double ay = node.point->y - node.next->next->point->y;
|
||||
return atan2(ay, ax);
|
||||
}
|
||||
|
||||
double Sweep::HoleAngle(Node& node)
|
||||
double Sweep::HoleAngle(const Node& node) const
|
||||
{
|
||||
/* Complex plane
|
||||
* ab = cosA +i*sinA
|
||||
|
@ -272,10 +324,10 @@ double Sweep::HoleAngle(Node& node)
|
|||
* Where x = ax*bx + ay*by
|
||||
* y = ax*by - ay*bx
|
||||
*/
|
||||
double ax = node.next->point->x - node.point->x;
|
||||
double ay = node.next->point->y - node.point->y;
|
||||
double bx = node.prev->point->x - node.point->x;
|
||||
double by = node.prev->point->y - node.point->y;
|
||||
const double ax = node.next->point->x - node.point->x;
|
||||
const double ay = node.next->point->y - node.point->y;
|
||||
const double bx = node.prev->point->x - node.point->x;
|
||||
const double by = node.prev->point->y - node.point->y;
|
||||
return atan2(ax * by - ay * bx, ax * bx + ay * by);
|
||||
}
|
||||
|
||||
|
@ -340,43 +392,43 @@ bool Sweep::Legalize(SweepContext& tcx, Triangle& t)
|
|||
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;
|
||||
double ady = pa.y - pd.y;
|
||||
double bdx = pb.x - pd.x;
|
||||
double bdy = pb.y - pd.y;
|
||||
const double adx = pa.x - pd.x;
|
||||
const double ady = pa.y - pd.y;
|
||||
const double bdx = pb.x - pd.x;
|
||||
const double bdy = pb.y - pd.y;
|
||||
|
||||
double adxbdy = adx * bdy;
|
||||
double bdxady = bdx * ady;
|
||||
double oabd = adxbdy - bdxady;
|
||||
const double adxbdy = adx * bdy;
|
||||
const double bdxady = bdx * ady;
|
||||
const double oabd = adxbdy - bdxady;
|
||||
|
||||
if (oabd <= 0)
|
||||
return false;
|
||||
|
||||
double cdx = pc.x - pd.x;
|
||||
double cdy = pc.y - pd.y;
|
||||
const double cdx = pc.x - pd.x;
|
||||
const double cdy = pc.y - pd.y;
|
||||
|
||||
double cdxady = cdx * ady;
|
||||
double adxcdy = adx * cdy;
|
||||
double ocad = cdxady - adxcdy;
|
||||
const double cdxady = cdx * ady;
|
||||
const double adxcdy = adx * cdy;
|
||||
const double ocad = cdxady - adxcdy;
|
||||
|
||||
if (ocad <= 0)
|
||||
return false;
|
||||
|
||||
double bdxcdy = bdx * cdy;
|
||||
double cdxbdy = cdx * bdy;
|
||||
const double bdxcdy = bdx * cdy;
|
||||
const double cdxbdy = cdx * bdy;
|
||||
|
||||
double alift = adx * adx + ady * ady;
|
||||
double blift = bdx * bdx + bdy * bdy;
|
||||
double clift = cdx * cdx + cdy * cdy;
|
||||
const double alift = adx * adx + ady * ady;
|
||||
const double blift = bdx * bdx + bdy * bdy;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
n1 = t.NeighborCCW(p);
|
||||
|
@ -708,11 +760,8 @@ Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op)
|
|||
} else if (o2d == CCW) {
|
||||
// Left
|
||||
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,
|
||||
|
@ -740,7 +789,7 @@ void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle&
|
|||
Sweep::~Sweep() {
|
||||
|
||||
// Clean up memory
|
||||
for(unsigned int i = 0; i < nodes_.size(); i++) {
|
||||
for(size_t i = 0; i < nodes_.size(); i++) {
|
||||
delete nodes_[i];
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation',
|
||||
* 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
|
||||
|
@ -49,17 +49,17 @@ struct Point;
|
|||
struct Edge;
|
||||
class Triangle;
|
||||
|
||||
class Sweep
|
||||
class Sweep
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Triangulate
|
||||
*
|
||||
*
|
||||
* @param tcx
|
||||
*/
|
||||
void Triangulate(SweepContext& tcx);
|
||||
|
||||
|
||||
/**
|
||||
* Destructor - clean up memory
|
||||
*/
|
||||
|
@ -69,7 +69,7 @@ private:
|
|||
|
||||
/**
|
||||
* Start sweeping the Y-sorted point set from bottom to top
|
||||
*
|
||||
*
|
||||
* @param tcx
|
||||
*/
|
||||
void SweepPoints(SweepContext& tcx);
|
||||
|
@ -86,8 +86,8 @@ private:
|
|||
Node& PointEvent(SweepContext& tcx, Point& point);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param tcx
|
||||
* @param edge
|
||||
* @param node
|
||||
|
@ -98,7 +98,7 @@ private:
|
|||
|
||||
/**
|
||||
* Creates a new front triangle and legalize it
|
||||
*
|
||||
*
|
||||
* @param tcx
|
||||
* @param point
|
||||
* @param node
|
||||
|
@ -142,7 +142,7 @@ private:
|
|||
* @param d - point opposite a
|
||||
* @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
|
||||
|
@ -158,7 +158,7 @@ private:
|
|||
* n4 n4
|
||||
* </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
|
||||
|
@ -169,17 +169,24 @@ private:
|
|||
*/
|
||||
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
|
||||
* @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]
|
||||
*/
|
||||
double BasinAngle(Node& node);
|
||||
double BasinAngle(const Node& node) const;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* intersecting the edge. So decide which to contiune with and legalize the other
|
||||
*
|
||||
*
|
||||
* @param tcx
|
||||
* @param o - should be the result of an orient2d( eq, op, ep )
|
||||
* @param t - triangle 1
|
||||
* @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
|
||||
* @return returns the triangle still intersecting the edge
|
||||
*/
|
||||
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
|
||||
* triangle.
|
||||
*
|
||||
* triangle.
|
||||
*
|
||||
* @param ep
|
||||
* @param eq
|
||||
* @param ot
|
||||
|
@ -254,10 +261,10 @@ private:
|
|||
|
||||
/**
|
||||
* Scan part of the FlipScan algorithm<br>
|
||||
* When a triangle pair isn't flippable we will scan for the next
|
||||
* point that is inside the flip triangle scan area. When found
|
||||
* When a triangle pair isn't flippable we will scan for the next
|
||||
* point that is inside the flip triangle scan area. When found
|
||||
* we generate a new flipEdgeEvent
|
||||
*
|
||||
*
|
||||
* @param tcx
|
||||
* @param ep - last 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 {
|
||||
|
||||
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_);
|
||||
}
|
||||
|
||||
void SweepContext::AddHole(std::vector<Point*> polyline)
|
||||
void SweepContext::AddHole(const std::vector<Point*>& polyline)
|
||||
{
|
||||
InitEdges(polyline);
|
||||
for(unsigned int i = 0; i < polyline.size(); i++) {
|
||||
|
@ -56,12 +57,12 @@ void SweepContext::AddPoint(Point* point) {
|
|||
points_.push_back(point);
|
||||
}
|
||||
|
||||
std::vector<Triangle*> SweepContext::GetTriangles()
|
||||
std::vector<Triangle*> &SweepContext::GetTriangles()
|
||||
{
|
||||
return triangles_;
|
||||
}
|
||||
|
||||
std::list<Triangle*> SweepContext::GetMap()
|
||||
std::list<Triangle*> &SweepContext::GetMap()
|
||||
{
|
||||
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());
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
int j = i < num_points - 1 ? i + 1 : 0;
|
||||
size_t num_points = polyline.size();
|
||||
for (size_t i = 0; i < num_points; i++) {
|
||||
size_t j = i < num_points - 1 ? i + 1 : 0;
|
||||
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];
|
||||
}
|
||||
|
@ -113,13 +114,13 @@ void SweepContext::AddToMap(Triangle* triangle)
|
|||
map_.push_back(triangle);
|
||||
}
|
||||
|
||||
Node& SweepContext::LocateNode(Point& point)
|
||||
Node& SweepContext::LocateNode(const Point& point)
|
||||
{
|
||||
// TODO implement search tree
|
||||
return *front_->LocateNode(point.x);
|
||||
}
|
||||
|
||||
void SweepContext::CreateAdvancingFront(std::vector<Node*> nodes)
|
||||
void SweepContext::CreateAdvancingFront(const std::vector<Node*>& nodes)
|
||||
{
|
||||
|
||||
(void) nodes;
|
||||
|
@ -164,12 +165,20 @@ void SweepContext::RemoveFromMap(Triangle* triangle)
|
|||
|
||||
void SweepContext::MeshClean(Triangle& triangle)
|
||||
{
|
||||
if (!triangle.IsInterior()) {
|
||||
triangle.IsInterior(true);
|
||||
triangles_.push_back(&triangle);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (!triangle.constrained_edge[i])
|
||||
MeshClean(*triangle.GetNeighbor(i));
|
||||
std::vector<Triangle *> triangles;
|
||||
triangles.push_back(&triangle);
|
||||
|
||||
while(!triangles.empty()){
|
||||
Triangle *t = triangles.back();
|
||||
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:
|
||||
|
||||
/// Constructor
|
||||
SweepContext(std::vector<Point*> polyline);
|
||||
SweepContext(const std::vector<Point*>& polyline);
|
||||
/// Destructor
|
||||
~SweepContext();
|
||||
|
||||
void set_head(Point* p1);
|
||||
|
||||
Point* head();
|
||||
Point* head() const;
|
||||
|
||||
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 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
|
||||
void MapTriangleToNodes(Triangle& t);
|
||||
|
||||
void AddToMap(Triangle* triangle);
|
||||
|
||||
Point* GetPoint(const int& index);
|
||||
Point* GetPoint(size_t index);
|
||||
|
||||
Point* GetPoints();
|
||||
|
||||
void RemoveFromMap(Triangle* triangle);
|
||||
|
||||
void AddHole(std::vector<Point*> polyline);
|
||||
void AddHole(const std::vector<Point*>& polyline);
|
||||
|
||||
void AddPoint(Point* point);
|
||||
|
||||
AdvancingFront* front();
|
||||
AdvancingFront* front() const;
|
||||
|
||||
void MeshClean(Triangle& triangle);
|
||||
|
||||
std::vector<Triangle*> GetTriangles();
|
||||
std::list<Triangle*> GetMap();
|
||||
std::vector<Triangle*> &GetTriangles();
|
||||
std::list<Triangle*> &GetMap();
|
||||
|
||||
std::vector<Edge*> edge_list;
|
||||
|
||||
|
@ -147,18 +147,18 @@ Point* tail_;
|
|||
Node *af_head_, *af_middle_, *af_tail_;
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -166,7 +166,7 @@ inline void SweepContext::set_head(Point* p1)
|
|||
head_ = p1;
|
||||
}
|
||||
|
||||
inline Point* SweepContext::head()
|
||||
inline Point* SweepContext::head() const
|
||||
{
|
||||
return head_;
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ inline void SweepContext::set_tail(Point* p1)
|
|||
tail_ = p1;
|
||||
}
|
||||
|
||||
inline Point* SweepContext::tail()
|
||||
inline Point* SweepContext::tail() const
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
typedef std::pair<aiBone*,unsigned int> BoneSrcIndex;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -153,7 +152,6 @@ struct BoneWithHash : public std::pair<uint32_t,aiString*> {
|
|||
std::vector<BoneSrcIndex> pSrcBones;
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief Utility for SceneCombiner
|
||||
*/
|
|
@ -77,7 +77,6 @@ AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f)
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename TReal>
|
||||
AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
|
||||
//return *(&r + i);
|
||||
switch ( i ) {
|
||||
case 0:
|
||||
return r;
|
||||
|
@ -93,7 +92,6 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename TReal>
|
||||
AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
|
||||
// return *(&r + i);
|
||||
switch ( i ) {
|
||||
case 0:
|
||||
return r;
|
||||
|
|
|
@ -48,6 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef AI_MATERIAL_INL_INC
|
||||
#define AI_MATERIAL_INL_INC
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
inline aiPropertyTypeInfo ai_real_to_property_type_info(float)
|
||||
{
|
||||
return aiPTI_Float;
|
||||
}
|
||||
|
||||
inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
|
||||
{
|
||||
return aiPTI_Double;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
//! @cond never
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -223,7 +235,7 @@ inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
|
|||
{
|
||||
return AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(aiUVTransform),
|
||||
pKey,type,index,aiPTI_Float); //TODO could be Double ...
|
||||
pKey,type,index,ai_real_to_property_type_info(pInput->mRotation));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -235,7 +247,7 @@ inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
|
|||
{
|
||||
return AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(aiColor4D),
|
||||
pKey,type,index,aiPTI_Float); //TODO could be Double ...
|
||||
pKey,type,index,ai_real_to_property_type_info(pInput->a));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -247,7 +259,7 @@ inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
|
|||
{
|
||||
return AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(aiColor3D),
|
||||
pKey,type,index,aiPTI_Float); //TODO could be Double ...
|
||||
pKey,type,index,ai_real_to_property_type_info(pInput->b));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -259,7 +271,7 @@ inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
|
|||
{
|
||||
return AddBinaryProperty((const void*)pInput,
|
||||
pNumValues * sizeof(aiVector3D),
|
||||
pKey,type,index,aiPTI_Float); //TODO could be Double ...
|
||||
pKey,type,index,ai_real_to_property_type_info(pInput->x));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -224,7 +224,7 @@ public:
|
|||
* @return Reference to the output matrix
|
||||
*/
|
||||
static aiMatrix4x4t& Rotation(TReal a, const aiVector3t<TReal>& axis,
|
||||
aiMatrix4x4t& out);
|
||||
aiMatrix4x4t& out);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns a translation matrix
|
||||
|
@ -232,7 +232,8 @@ public:
|
|||
* @param out Receives 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
|
||||
|
@ -252,7 +253,7 @@ public:
|
|||
* Journal of Graphics Tools, 4(4):1-4, 1999
|
||||
*/
|
||||
static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from,
|
||||
const aiVector3t<TReal>& to, aiMatrix4x4t& out);
|
||||
const aiVector3t<TReal>& to, aiMatrix4x4t& out);
|
||||
|
||||
public:
|
||||
TReal a1, a2, a3, a4;
|
||||
|
|
|
@ -8,7 +8,6 @@ import os
|
|||
import ctypes
|
||||
from ctypes import POINTER
|
||||
import operator
|
||||
import sys
|
||||
|
||||
try: import numpy
|
||||
except: numpy = None
|
||||
|
@ -40,9 +39,7 @@ elif os.name=='nt':
|
|||
for dir_candidate in path_dirs:
|
||||
if 'assimp' in dir_candidate.lower():
|
||||
additional_dirs.append(dir_candidate)
|
||||
|
||||
additional_dirs += sys.path
|
||||
|
||||
|
||||
#print(additional_dirs)
|
||||
def vec2tuple(x):
|
||||
""" Converts a VECTOR3D to a Tuple """
|
||||
|
|
|
@ -9,7 +9,5 @@ setup(name='pyassimp',
|
|||
url='https://github.com/assimp/assimp',
|
||||
packages=['pyassimp'],
|
||||
data_files=[('share/pyassimp', ['README.md']),
|
||||
('share/examples/pyassimp', ['scripts/' + f for f in os.listdir('scripts/')]),
|
||||
('lib/', [f for f in os.listdir('../../lib') if os.path.isfile(f)])],
|
||||
requires=['numpy']
|
||||
('share/examples/pyassimp', ['scripts/' + f for f in os.listdir('scripts/')])], 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