Merge branch 'master' into patch-8

pull/5379/head
Kim Kulling 2024-02-05 15:11:05 +01:00 committed by GitHub
commit 6d095594b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
141 changed files with 2467 additions and 1242 deletions

View File

@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter, windows-msvc-hunter]
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++]
# For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
include:
- name: windows-latest-cl.exe
@ -35,15 +35,6 @@ jobs:
os: ubuntu-latest
cxx: g++
cc: gcc
- name: ubuntu-gcc-hunter
os: ubuntu-latest
toolchain: ninja-gcc-cxx17-fpic
- name: macos-clang-hunter
os: macos-latest
toolchain: ninja-clang-cxx17-fpic
- name: windows-msvc-hunter
os: windows-latest
toolchain: ninja-vs-win64-cxx17
steps:
- uses: actions/checkout@v4
@ -55,29 +46,15 @@ jobs:
- uses: ilammy/msvc-dev-cmd@v1
- name: Set Compiler Environment
if: "!endsWith(matrix.name, 'hunter')"
uses: lukka/set-shell-env@v1
with:
CXX: ${{ matrix.cxx }}
CC: ${{ matrix.cc }}
- name: Set Compiler Environment for Hunter on Windows
if: startsWith(matrix.name, 'windows') && endsWith(matrix.name, 'hunter')
uses: lukka/set-shell-env@v1
with:
VS160COMNTOOLS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools
- name: Checkout Hunter toolchains
if: endsWith(matrix.name, 'hunter')
uses: actions/checkout@v4
with:
repository: cpp-pm/polly
path: cmake/polly
- name: Cache DX SDK
id: dxcache
if: contains(matrix.name, 'windows')
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: '${{ github.workspace }}/DX_SDK'
key: ${{ runner.os }}-DX_SDK
@ -121,7 +98,7 @@ jobs:
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
shell: bash
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
if: matrix.name == 'windows-msvc'
with:
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'

View File

@ -19,7 +19,7 @@ jobs:
dry-run: false
language: c++
- name: Upload Crash
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts

View File

@ -137,7 +137,7 @@ IF (WIN32)
ELSE()
OPTION( ASSIMP_BUILD_ZLIB
"Build your own zlib"
ON
OFF
)
ENDIF()
@ -311,9 +311,9 @@ ELSEIF( MINGW )
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF()
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
ELSE()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
ENDIF()
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
ENDIF()

View File

@ -6,6 +6,7 @@ RUN apt-get update && apt-get install -y ninja-build \
RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update
WORKDIR /opt
RUN apt install zlib1g-dev
# Build Assimp
RUN git clone https://github.com/assimp/assimp.git /opt/assimp

View File

@ -16,26 +16,27 @@ APIs are provided for C and C++. There are various bindings to other languages (
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.
### Documentation ###
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
Read [our latest documentation](https://assimp-docs.readthedocs.io/en/latest/).
### Pre-built binaries ###
Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
Download binaries from [our Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
### Test data ###
Clone [our model database](https://github.com/assimp/assimp-mdb).
### Communities ###
- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
And we also have a Gitter-channel:Gitter [![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>
#### Supported file formats ####
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md).
### Building ###
Take a look [here](https://github.com/assimp/assimp/blob/master/Build.md) to get started. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
Start by reading [our build instructions](https://github.com/assimp/assimp/blob/master/Build.md). We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
### Ports ###
* [Android](port/AndroidJNI/README.md)

View File

@ -57,6 +57,7 @@ enum class ResourceType {
RT_BaseMaterials,
RT_EmbeddedTexture2D,
RT_Texture2DGroup,
RT_ColorGroup,
RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
@ -117,6 +118,21 @@ public:
}
};
class ColorGroup : public Resource {
public:
std::vector<aiColor4D> mColors;
ColorGroup(int id) :
Resource(id){
// empty
}
~ColorGroup() override = default;
ResourceType getType() const override {
return ResourceType::RT_ColorGroup;
}
};
class BaseMaterials : public Resource {
public:
std::vector<unsigned int> mMaterialIndex;

View File

@ -98,6 +98,11 @@ namespace XmlTag {
const char *const texture_cuurd_u = "u";
const char *const texture_cuurd_v = "v";
// vertex color definitions
const char *const colorgroup = "m:colorgroup";
const char *const color_item = "m:color";
const char *const color_vaule = "color";
// Meta info tags
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";

View File

@ -81,12 +81,17 @@ static constexpr aiImporterDesc desc = {
"3mf"
};
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool ) const {
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
return false;
}
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
return opcPackage.validate();
static const char *const ModelRef = "3D/3dmodel.model";
ZipArchiveIOSystem archive(pIOHandler, filename);
if (!archive.Exists(ModelRef)) {
return false;
}
return true;
}
void D3MFImporter::SetupProperties(const Importer*) {

View File

@ -119,9 +119,9 @@ public:
static bool IsEmbeddedTexture( const std::string &filename ) {
const std::string extension = BaseImporter::GetExtension(filename);
if (extension == "jpg" || extension == "png") {
if (extension == "jpg" || extension == "png" || extension == "jpeg") {
std::string::size_type pos = filename.find("thumbnail");
if (pos == std::string::npos) {
if (pos != std::string::npos) {
return false;
}
return true;

View File

@ -75,7 +75,7 @@ aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
texId0 = texId1 = texId2 = -1;
texId0 = texId1 = texId2 = IdNotSet;
XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
@ -236,6 +236,8 @@ void XmlSerializer::ImportXml(aiScene *scene) {
ReadBaseMaterials(currentNode);
} else if (currentNodeName == XmlTag::meta) {
ReadMetadata(currentNode);
} else if (currentNodeName == XmlTag::colorgroup) {
ReadColorGroup(currentNode);
}
}
StoreMaterialsInScene(scene);
@ -331,9 +333,49 @@ void XmlSerializer::ReadObject(XmlNode &node) {
if (hasPid) {
auto it = mResourcesDictionnary.find(pid);
if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
if (hasPindex && it != mResourcesDictionnary.end()) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
if (mesh->mTextureCoords[0] == nullptr) {
mesh->mNumUVComponents[0] = 2;
for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
mesh->mNumUVComponents[i] = 0;
}
const std::string name = ai_to_string(group->mTexId);
for (size_t i = 0; i < mMaterials.size(); ++i) {
if (name == mMaterials[i]->GetName().C_Str()) {
mesh->mMaterialIndex = static_cast<unsigned int>(i);
}
}
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
mesh->mTextureCoords[0][vertex_idx] =
aiVector3D(group->mTex2dCoords[pindex].x, group->mTex2dCoords[pindex].y, 0.0f);
}
} else {
for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
if (mesh->mTextureCoords[0][vertex_idx].z < 0) {
// use default
mesh->mTextureCoords[0][vertex_idx] =
aiVector3D(group->mTex2dCoords[pindex].x, group->mTex2dCoords[pindex].y, 0.0f);
}
}
}
}else if (it->second->getType() == ResourceType::RT_ColorGroup) {
if (mesh->mColors[0] == nullptr) {
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
ColorGroup *group = static_cast<ColorGroup *>(it->second);
for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
mesh->mColors[0][vertex_idx] = group->mColors[pindex];
}
}
}
}
}
@ -415,27 +457,36 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::triangle) {
int pid = IdNotSet, p1 = IdNotSet;
int pid = IdNotSet;
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
int texId[3];
Texture2DGroup *group = nullptr;
aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]);
if (hasPid && hasP1) {
int pindex[3];
aiFace face = ReadTriangle(currentNode, pindex[0], pindex[1], pindex[2]);
if (hasPid && (pindex[0] != IdNotSet || pindex[1] != IdNotSet || pindex[2] != IdNotSet)) {
auto it = mResourcesDictionnary.find(pid);
if (it != mResourcesDictionnary.end()) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
auto update_material = [&](int idx) {
if (pindex[idx] != IdNotSet) {
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[pindex[idx]];
}
};
update_material(0);
update_material(1);
update_material(2);
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
// Load texture coordinates into mesh, when any
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second); // fix bug
if (mesh->mTextureCoords[0] == nullptr) {
mesh->mNumUVComponents[0] = 2;
for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
mesh->mNumUVComponents[i] = 0;
}
group = static_cast<Texture2DGroup *>(it->second);
const std::string name = ai_to_string(group->mTexId);
for (size_t i = 0; i < mMaterials.size(); ++i) {
if (name == mMaterials[i]->GetName().C_Str()) {
@ -443,21 +494,44 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
}
}
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
for (unsigned int vertex_index = 0; vertex_index < mesh->mNumVertices; vertex_index++) {
mesh->mTextureCoords[0][vertex_index].z = IdNotSet;//mark not set
}
}
auto update_texture = [&](int idx) {
if (pindex[idx] != IdNotSet) {
size_t vertex_index = face.mIndices[idx];
mesh->mTextureCoords[0][vertex_index] =
aiVector3D(group->mTex2dCoords[pindex[idx]].x, group->mTex2dCoords[pindex[idx]].y, 0.0f);
}
};
update_texture(0);
update_texture(1);
update_texture(2);
} else if (it->second->getType() == ResourceType::RT_ColorGroup) {
// Load vertex color into mesh, when any
ColorGroup *group = static_cast<ColorGroup *>(it->second);
if (mesh->mColors[0] == nullptr) {
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
}
auto update_color = [&](int idx) {
if (pindex[idx] != IdNotSet) {
size_t vertex_index = face.mIndices[idx];
mesh->mColors[0][vertex_index] = group->mColors[pindex[idx]];
}
};
update_color(0);
update_color(1);
update_color(2);
}
}
}
// Load texture coordinates into mesh, when any
if (group != nullptr) {
size_t i0 = face.mIndices[0];
size_t i1 = face.mIndices[1];
size_t i2 = face.mIndices[2];
mesh->mTextureCoords[0][i0] = aiVector3D(group->mTex2dCoords[texId[0]].x, group->mTex2dCoords[texId[0]].y, 0.0f);
mesh->mTextureCoords[0][i1] = aiVector3D(group->mTex2dCoords[texId[1]].x, group->mTex2dCoords[texId[1]].y, 0.0f);
mesh->mTextureCoords[0][i2] = aiVector3D(group->mTex2dCoords[texId[2]].x, group->mTex2dCoords[texId[2]].y, 0.0f);
}
faces.push_back(face);
}
}
@ -598,6 +672,38 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
return material;
}
void XmlSerializer::ReadColor(XmlNode &node, ColorGroup *colorGroup) {
if (node.empty() || nullptr == colorGroup) {
return;
}
for (XmlNode currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::color_item) {
const char *color = currentNode.attribute(XmlTag::color_vaule).as_string();
aiColor4D color_value;
if (parseColor(color, color_value)) {
colorGroup->mColors.push_back(color_value);
}
}
}
}
void XmlSerializer::ReadColorGroup(XmlNode &node) {
if (node.empty()) {
return;
}
int id = IdNotSet;
if (!XmlParser::getIntAttribute(node, XmlTag::id, id)) {
return;
}
ColorGroup *group = new ColorGroup(id);
ReadColor(node, group);
mResourcesDictionnary.insert(std::make_pair(id, group));
}
void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
if (nullptr == scene) {
return;

View File

@ -57,6 +57,7 @@ class D3MFOpcPackage;
class Object;
class Texture2DGroup;
class EmbeddedTexture;
class ColorGroup;
class XmlSerializer {
public:
@ -78,6 +79,8 @@ private:
void ReadTextureGroup(XmlNode &node);
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
void StoreMaterialsInScene(aiScene *scene);
void ReadColorGroup(XmlNode &node);
void ReadColor(XmlNode &node, ColorGroup *colorGroup);
private:
struct MetaEntry {

View File

@ -77,8 +77,8 @@ static constexpr aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// skip to the next token
inline const char *AcSkipToNextToken(const char *buffer) {
if (!SkipSpaces(&buffer)) {
inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
if (!SkipSpaces(&buffer, end)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
}
return buffer;
@ -86,13 +86,13 @@ inline const char *AcSkipToNextToken(const char *buffer) {
// ------------------------------------------------------------------------------------------------
// read a string (may be enclosed in double quotation marks). buffer must point to "
inline const char *AcGetString(const char *buffer, std::string &out) {
inline const char *AcGetString(const char *buffer, const char *end, std::string &out) {
if (*buffer == '\0') {
throw DeadlyImportError("AC3D: Unexpected EOF in string");
}
++buffer;
const char *sz = buffer;
while ('\"' != *buffer) {
while ('\"' != *buffer && buffer != end) {
if (IsLineEnd(*buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
out = "ERROR";
@ -112,8 +112,8 @@ inline const char *AcGetString(const char *buffer, std::string &out) {
// ------------------------------------------------------------------------------------------------
// read 1 to n floats prefixed with an optional predefined identifier
template <class T>
inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) {
buffer = AcSkipToNextToken(buffer);
inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end, const char *name, size_t name_length, size_t num, T *out) {
buffer = AcSkipToNextToken(buffer, end);
if (0 != name_length) {
if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected.");
@ -122,7 +122,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
buffer += name_length + 1;
}
for (unsigned int _i = 0; _i < num; ++_i) {
buffer = AcSkipToNextToken(buffer);
buffer = AcSkipToNextToken(buffer, end);
buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
}
@ -132,7 +132,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
AC3DImporter::AC3DImporter() :
buffer(),
mBuffer(),
configSplitBFCull(),
configEvalSubdivision(),
mNumMeshes(),
@ -164,17 +164,17 @@ const aiImporterDesc *AC3DImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
// Get a pointer to the next line from the file
bool AC3DImporter::GetNextLine() {
SkipLine(&buffer);
return SkipSpaces(&buffer);
SkipLine(&mBuffer.data, mBuffer.end);
return SkipSpaces(&mBuffer.data, mBuffer.end);
}
// ------------------------------------------------------------------------------------------------
// Parse an object section in an AC file
void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (!TokenMatch(buffer, "OBJECT", 6))
return;
bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (!TokenMatch(mBuffer.data, "OBJECT", 6))
return false;
SkipSpaces(&buffer);
SkipSpaces(&mBuffer.data, mBuffer.end);
++mNumMeshes;
@ -182,7 +182,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
Object &obj = objects.back();
aiLight *light = nullptr;
if (!ASSIMP_strincmp(buffer, "light", 5)) {
if (!ASSIMP_strincmp(mBuffer.data, "light", 5)) {
// This is a light source. Add it to the list
mLights->push_back(light = new aiLight());
@ -198,62 +198,66 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered");
obj.type = Object::Light;
} else if (!ASSIMP_strincmp(buffer, "group", 5)) {
} else if (!ASSIMP_strincmp(mBuffer.data, "group", 5)) {
obj.type = Object::Group;
} else if (!ASSIMP_strincmp(buffer, "world", 5)) {
} else if (!ASSIMP_strincmp(mBuffer.data, "world", 5)) {
obj.type = Object::World;
} else
obj.type = Object::Poly;
while (GetNextLine()) {
if (TokenMatch(buffer, "kids", 4)) {
SkipSpaces(&buffer);
unsigned int num = strtoul10(buffer, &buffer);
if (TokenMatch(mBuffer.data, "kids", 4)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
unsigned int num = strtoul10(mBuffer.data, &mBuffer.data);
GetNextLine();
if (num) {
// load the children of this object recursively
obj.children.reserve(num);
for (unsigned int i = 0; i < num; ++i)
LoadObjectSection(obj.children);
for (unsigned int i = 0; i < num; ++i) {
if (!LoadObjectSection(obj.children)) {
ASSIMP_LOG_WARN("AC3D: wrong number of kids");
break;
}
}
}
return;
} else if (TokenMatch(buffer, "name", 4)) {
SkipSpaces(&buffer);
buffer = AcGetString(buffer, obj.name);
return true;
} else if (TokenMatch(mBuffer.data, "name", 4)) {
SkipSpaces(&mBuffer.data, mBuffer.data);
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, obj.name);
// If this is a light source, we'll also need to store
// the name of the node in it.
if (light) {
light->mName.Set(obj.name);
}
} else if (TokenMatch(buffer, "texture", 7)) {
SkipSpaces(&buffer);
} else if (TokenMatch(mBuffer.data, "texture", 7)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
std::string texture;
buffer = AcGetString(buffer, texture);
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, texture);
obj.textures.push_back(texture);
} else if (TokenMatch(buffer, "texrep", 6)) {
SkipSpaces(&buffer);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
} else if (TokenMatch(mBuffer.data, "texrep", 6)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &obj.texRepeat);
if (!obj.texRepeat.x || !obj.texRepeat.y)
obj.texRepeat = aiVector2D(1.f, 1.f);
} else if (TokenMatch(buffer, "texoff", 6)) {
SkipSpaces(&buffer);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texOffset);
} else if (TokenMatch(buffer, "rot", 3)) {
SkipSpaces(&buffer);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 9, &obj.rotation);
} else if (TokenMatch(buffer, "loc", 3)) {
SkipSpaces(&buffer);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &obj.translation);
} else if (TokenMatch(buffer, "subdiv", 6)) {
SkipSpaces(&buffer);
obj.subDiv = strtoul10(buffer, &buffer);
} else if (TokenMatch(buffer, "crease", 6)) {
SkipSpaces(&buffer);
obj.crease = fast_atof(buffer);
} else if (TokenMatch(buffer, "numvert", 7)) {
SkipSpaces(&buffer);
} else if (TokenMatch(mBuffer.data, "texoff", 6)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &obj.texOffset);
} else if (TokenMatch(mBuffer.data, "rot", 3)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 9, &obj.rotation);
} else if (TokenMatch(mBuffer.data, "loc", 3)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 3, &obj.translation);
} else if (TokenMatch(mBuffer.data, "subdiv", 6)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
obj.subDiv = strtoul10(mBuffer.data, &mBuffer.data);
} else if (TokenMatch(mBuffer.data, "crease", 6)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
obj.crease = fast_atof(mBuffer.data);
} else if (TokenMatch(mBuffer.data, "numvert", 7)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
unsigned int t = strtoul10(buffer, &buffer);
unsigned int t = strtoul10(mBuffer.data, &mBuffer.data);
if (t >= AI_MAX_ALLOC(aiVector3D)) {
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
}
@ -262,59 +266,59 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (!GetNextLine()) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet");
break;
} else if (!IsNumeric(*buffer)) {
} else if (!IsNumeric(*mBuffer.data)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet");
--buffer; // make sure the line is processed a second time
--mBuffer.data; // make sure the line is processed a second time
break;
}
obj.vertices.emplace_back();
aiVector3D &v = obj.vertices.back();
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 3, &v.x);
}
} else if (TokenMatch(buffer, "numsurf", 7)) {
SkipSpaces(&buffer);
} else if (TokenMatch(mBuffer.data, "numsurf", 7)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
bool Q3DWorkAround = false;
const unsigned int t = strtoul10(buffer, &buffer);
const unsigned int t = strtoul10(mBuffer.data, &mBuffer.data);
obj.surfaces.reserve(t);
for (unsigned int i = 0; i < t; ++i) {
GetNextLine();
if (!TokenMatch(buffer, "SURF", 4)) {
if (!TokenMatch(mBuffer.data, "SURF", 4)) {
// FIX: this can occur for some files - Quick 3D for
// example writes no surf chunks
if (!Q3DWorkAround) {
ASSIMP_LOG_WARN("AC3D: SURF token was expected");
ASSIMP_LOG_VERBOSE_DEBUG("Continuing with Quick3D Workaround enabled");
}
--buffer; // make sure the line is processed a second time
--mBuffer.data; // make sure the line is processed a second time
// break; --- see fix notes above
Q3DWorkAround = true;
}
SkipSpaces(&buffer);
SkipSpaces(&mBuffer.data, mBuffer.end);
obj.surfaces.emplace_back();
Surface &surf = obj.surfaces.back();
surf.flags = strtoul_cppstyle(buffer);
surf.flags = strtoul_cppstyle(mBuffer.data);
while (true) {
if (!GetNextLine()) {
throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
}
if (TokenMatch(buffer, "mat", 3)) {
SkipSpaces(&buffer);
surf.mat = strtoul10(buffer);
} else if (TokenMatch(buffer, "refs", 4)) {
if (TokenMatch(mBuffer.data, "mat", 3)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
surf.mat = strtoul10(mBuffer.data);
} else if (TokenMatch(mBuffer.data, "refs", 4)) {
// --- see fix notes above
if (Q3DWorkAround) {
if (!surf.entries.empty()) {
buffer -= 6;
mBuffer.data -= 6;
break;
}
}
SkipSpaces(&buffer);
const unsigned int m = strtoul10(buffer);
SkipSpaces(&mBuffer.data, mBuffer.end);
const unsigned int m = strtoul10(mBuffer.data);
surf.entries.reserve(m);
obj.numRefs += m;
@ -327,12 +331,12 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
surf.entries.emplace_back();
Surface::SurfaceEntry &entry = surf.entries.back();
entry.first = strtoul10(buffer, &buffer);
SkipSpaces(&buffer);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &entry.second);
entry.first = strtoul10(mBuffer.data, &mBuffer.data);
SkipSpaces(&mBuffer.data, mBuffer.end);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &entry.second);
}
} else {
--buffer; // make sure the line is processed a second time
--mBuffer.data; // make sure the line is processed a second time
break;
}
}
@ -340,6 +344,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
}
}
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected");
return false;
}
// ------------------------------------------------------------------------------------------------
@ -445,7 +450,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
idx = 0;
}
if ((*it).entries.empty()) {
ASSIMP_LOG_WARN("AC3D: surface her zero vertex references");
ASSIMP_LOG_WARN("AC3D: surface has zero vertex references");
}
// validate all vertex indices to make sure we won't crash here
@ -463,16 +468,15 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
}
switch ((*it).GetType()) {
// closed line
case Surface::ClosedLine:
needMat[idx].first += (unsigned int)(*it).entries.size();
needMat[idx].second += (unsigned int)(*it).entries.size() << 1u;
case Surface::ClosedLine: // closed line
needMat[idx].first += static_cast<unsigned int>((*it).entries.size());
needMat[idx].second += static_cast<unsigned int>((*it).entries.size() << 1u);
break;
// unclosed line
case Surface::OpenLine:
needMat[idx].first += (unsigned int)(*it).entries.size() - 1;
needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u;
needMat[idx].first += static_cast<unsigned int>((*it).entries.size() - 1);
needMat[idx].second += static_cast<unsigned int>(((*it).entries.size() - 1) << 1u);
break;
// triangle strip
@ -574,15 +578,6 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
const Surface::SurfaceEntry &entry2 = src.entries[i + 1];
const Surface::SurfaceEntry &entry3 = src.entries[i + 2];
// skip degenerate triangles
if (object.vertices[entry1.first] == object.vertices[entry2.first] ||
object.vertices[entry1.first] == object.vertices[entry3.first] ||
object.vertices[entry2.first] == object.vertices[entry3.first]) {
mesh->mNumFaces--;
mesh->mNumVertices -= 3;
continue;
}
aiFace &face = *faces++;
face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices];
@ -760,17 +755,18 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(), mBuffer2);
buffer = &mBuffer2[0];
mBuffer.data = &mBuffer2[0];
mBuffer.end = &mBuffer2[0] + mBuffer2.size();
mNumMeshes = 0;
mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0;
if (::strncmp(buffer, "AC3D", 4)) {
if (::strncmp(mBuffer.data, "AC3D", 4)) {
throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
}
// print the file format version to the console
unsigned int version = HexDigitToDecimal(buffer[4]);
unsigned int version = HexDigitToDecimal(mBuffer.data[4]);
char msg[3];
ASSIMP_itoa10(msg, 3, version);
ASSIMP_LOG_INFO("AC3D file format version: ", msg);
@ -785,30 +781,31 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
mLights = &lights;
while (GetNextLine()) {
if (TokenMatch(buffer, "MATERIAL", 8)) {
if (TokenMatch(mBuffer.data, "MATERIAL", 8)) {
materials.emplace_back();
Material &mat = materials.back();
// manually parse the material ... sscanf would use the buldin atof ...
// Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f
buffer = AcSkipToNextToken(buffer);
if ('\"' == *buffer) {
buffer = AcGetString(buffer, mat.name);
buffer = AcSkipToNextToken(buffer);
mBuffer.data = AcSkipToNextToken(mBuffer.data, mBuffer.end);
if ('\"' == *mBuffer.data) {
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, mat.name);
mBuffer.data = AcSkipToNextToken(mBuffer.data, mBuffer.end);
}
buffer = TAcCheckedLoadFloatArray(buffer, "rgb", 3, 3, &mat.rgb);
buffer = TAcCheckedLoadFloatArray(buffer, "amb", 3, 3, &mat.amb);
buffer = TAcCheckedLoadFloatArray(buffer, "emis", 4, 3, &mat.emis);
buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec);
buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin);
buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "rgb", 3, 3, &mat.rgb);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "amb", 3, 3, &mat.amb);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "emis", 4, 3, &mat.emis);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "spec", 4, 3, &mat.spec);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "shi", 3, 1, &mat.shin);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "trans", 5, 1, &mat.trans);
} else {
LoadObjectSection(rootObjects);
}
LoadObjectSection(rootObjects);
}
if (rootObjects.empty() || !mNumMeshes) {
if (rootObjects.empty() || mNumMeshes == 0u) {
throw DeadlyImportError("AC3D: No meshes have been loaded");
}
if (materials.empty()) {
@ -824,7 +821,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
materials.reserve(mNumMeshes);
// generate a dummy root if there are multiple objects on the top layer
Object *root;
Object *root = nullptr;
if (1 == rootObjects.size())
root = &rootObjects[0];
else {
@ -837,7 +834,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
delete root;
}
if (!::strncmp(pScene->mRootNode->mName.data, "Node", 4)) {
if (::strncmp(pScene->mRootNode->mName.data, "Node", 4) == 0) {
pScene->mRootNode->mName.Set("<AC3DWorld>");
}
@ -856,7 +853,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
// copy lights
pScene->mNumLights = (unsigned int)lights.size();
if (lights.size()) {
if (!lights.empty()) {
pScene->mLights = new aiLight *[lights.size()];
::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *));
}

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -216,7 +216,7 @@ private:
* load subobjects, the method returns after a 'kids 0' was
* encountered.
* @objects List of output objects*/
void LoadObjectSection(std::vector<Object> &objects);
bool LoadObjectSection(std::vector<Object> &objects);
// -------------------------------------------------------------------
/** Convert all objects into meshes and nodes.
@ -242,7 +242,7 @@ private:
private:
// points to the next data line
const char *buffer;
aiBuffer mBuffer;
// Configuration option: if enabled, up to two meshes
// are generated per material: those faces who have

View File

@ -110,10 +110,12 @@ using namespace Assimp::ASE;
++filePtr;
// ------------------------------------------------------------------------------------------------
Parser::Parser(const char *szFile, unsigned int fileFormatDefault) {
Parser::Parser(const char *szFile, unsigned int fileFormatDefault) :
filePtr(nullptr), mEnd (nullptr) {
ai_assert(nullptr != szFile);
filePtr = szFile;
mEnd = filePtr + std::strlen(filePtr);
iFileFormat = fileFormatDefault;
// make sure that the color values are invalid
@ -179,14 +181,22 @@ bool Parser::SkipToNextToken() {
while (true) {
char me = *filePtr;
if (filePtr == mEnd) {
return false;
}
// increase the line number counter if necessary
if (IsLineEnd(me) && !bLastWasEndLine) {
++iLineNumber;
bLastWasEndLine = true;
} else
bLastWasEndLine = false;
if ('*' == me || '}' == me || '{' == me) return true;
if ('\0' == me) return false;
if ('*' == me || '}' == me || '{' == me) {
return true;
}
if ('\0' == me) {
return false;
}
++filePtr;
}
@ -344,8 +354,9 @@ void Parser::ParseLV1SoftSkinBlock() {
unsigned int numVerts = 0;
const char *sz = filePtr;
while (!IsSpaceOrNewLine(*filePtr))
while (!IsSpaceOrNewLine(*filePtr)) {
++filePtr;
}
const unsigned int diff = (unsigned int)(filePtr - sz);
if (diff) {
@ -363,24 +374,24 @@ void Parser::ParseLV1SoftSkinBlock() {
// Skip the mesh data - until we find a new mesh
// or the end of the *MESH_SOFTSKINVERTS section
while (true) {
SkipSpacesAndLineEnd(&filePtr);
SkipSpacesAndLineEnd(&filePtr, mEnd);
if (*filePtr == '}') {
++filePtr;
return;
} else if (!IsNumeric(*filePtr))
break;
SkipLine(&filePtr);
SkipLine(&filePtr, mEnd);
}
} else {
SkipSpacesAndLineEnd(&filePtr);
SkipSpacesAndLineEnd(&filePtr, mEnd);
ParseLV4MeshLong(numVerts);
// Reserve enough storage
curMesh->mBoneVertices.reserve(numVerts);
for (unsigned int i = 0; i < numVerts; ++i) {
SkipSpacesAndLineEnd(&filePtr);
SkipSpacesAndLineEnd(&filePtr, mEnd);
unsigned int numWeights;
ParseLV4MeshLong(numWeights);
@ -422,7 +433,7 @@ void Parser::ParseLV1SoftSkinBlock() {
if (*filePtr == '\0')
return;
++filePtr;
SkipSpacesAndLineEnd(&filePtr);
SkipSpacesAndLineEnd(&filePtr, mEnd);
}
}
@ -743,7 +754,7 @@ void Parser::ParseLV3MapBlock(Texture &map) {
// ------------------------------------------------------------------------------------------------
bool Parser::ParseString(std::string &out, const char *szName) {
char szBuffer[1024];
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Unexpected EOL", szName);
LogWarning(szBuffer);
@ -1355,7 +1366,7 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
// Mesh bone with name ...
if (TokenMatch(filePtr, "MESH_BONE_NAME", 14)) {
// parse an index ...
if (SkipSpaces(&filePtr)) {
if (SkipSpaces(&filePtr, mEnd)) {
unsigned int iIndex = strtoul10(filePtr, &filePtr);
if (iIndex >= iNumBones) {
LogWarning("Bone index is out of bounds");
@ -1395,11 +1406,11 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
std::pair<int, float> pairOut;
while (true) {
// first parse the bone index ...
if (!SkipSpaces(&filePtr)) break;
if (!SkipSpaces(&filePtr, mEnd)) break;
pairOut.first = strtoul10(filePtr, &filePtr);
// then parse the vertex weight
if (!SkipSpaces(&filePtr)) break;
if (!SkipSpaces(&filePtr, mEnd)) break;
filePtr = fast_atoreal_move<float>(filePtr, pairOut.second);
// -1 marks unused entries
@ -1675,7 +1686,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFace(ASE::Face &out) {
// skip spaces and tabs
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL [#1]");
SkipToNextToken();
return;
@ -1685,7 +1696,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
out.iFace = strtoul10(filePtr, &filePtr);
// next character should be ':'
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
// FIX: there are some ASE files which haven't got : here ....
LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. \':\' expected [#2]");
SkipToNextToken();
@ -1697,7 +1708,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
// Parse all mesh indices
for (unsigned int i = 0; i < 3; ++i) {
unsigned int iIndex = 0;
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL");
SkipToNextToken();
return;
@ -1723,7 +1734,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
++filePtr;
// next character should be ':'
if (!SkipSpaces(&filePtr) || ':' != *filePtr) {
if (!SkipSpaces(&filePtr, mEnd) || ':' != *filePtr) {
LogWarning("Unable to parse *MESH_FACE Element: "
"Unexpected EOL. \':\' expected [#2]");
SkipToNextToken();
@ -1731,9 +1742,9 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
}
++filePtr;
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
"Vertex index ecpected [#4]");
"Vertex index expected [#4]");
SkipToNextToken();
return;
}
@ -1752,7 +1763,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
// parse the smoothing group of the face
if (TokenMatch(filePtr, "*MESH_SMOOTHING", 15)) {
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
LogWarning("Unable to parse *MESH_SMOOTHING Element: "
"Unexpected EOL. Smoothing group(s) expected [#5]");
SkipToNextToken();
@ -1771,12 +1782,12 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
LogWarning(message.c_str());
}
}
SkipSpaces(&filePtr);
SkipSpaces(&filePtr, mEnd);
if (',' != *filePtr) {
break;
}
++filePtr;
SkipSpaces(&filePtr);
SkipSpaces(&filePtr, mEnd);
}
}
@ -1792,7 +1803,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
}
if (TokenMatch(filePtr, "*MESH_MTLID", 11)) {
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
LogWarning("Unable to parse *MESH_MTLID Element: Unexpected EOL. "
"Material index expected [#6]");
SkipToNextToken();
@ -1840,7 +1851,7 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFloat(ai_real &fOut) {
// skip spaces and tabs
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
// LOG
LogWarning("Unable to parse float: unexpected EOL [#1]");
fOut = 0.0;
@ -1853,7 +1864,7 @@ void Parser::ParseLV4MeshFloat(ai_real &fOut) {
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshLong(unsigned int &iOut) {
// Skip spaces and tabs
if (!SkipSpaces(&filePtr)) {
if (!SkipSpaces(&filePtr, mEnd)) {
// LOG
LogWarning("Unable to parse long: unexpected EOL [#1]");
iOut = 0;

View File

@ -620,6 +620,9 @@ public:
//! Pointer to current data
const char *filePtr;
/// The end pointer of the file data
const char *mEnd;
//! background color to be passed to the viewer
//! QNAN if none was found
aiColor3D m_clrBackground;

View File

@ -473,8 +473,9 @@ void COBImporter::ReadBasicNodeInfo_Ascii(Node &msh, LineSplitter &splitter, con
} else if (splitter.match_start("Transform")) {
for (unsigned int y = 0; y < 4 && ++splitter; ++y) {
const char *s = splitter->c_str();
const char *end = s + splitter->size();
for (unsigned int x = 0; x < 4; ++x) {
SkipSpaces(&s);
SkipSpaces(&s, end);
msh.transform[y][x] = fast_atof(&s);
}
}
@ -486,12 +487,12 @@ void COBImporter::ReadBasicNodeInfo_Ascii(Node &msh, LineSplitter &splitter, con
// ------------------------------------------------------------------------------------------------
template <typename T>
void COBImporter::ReadFloat3Tuple_Ascii(T &fill, const char **in) {
void COBImporter::ReadFloat3Tuple_Ascii(T &fill, const char **in, const char *end) {
const char *rgb = *in;
for (unsigned int i = 0; i < 3; ++i) {
SkipSpaces(&rgb);
SkipSpaces(&rgb, end);
if (*rgb == ',') ++rgb;
SkipSpaces(&rgb);
SkipSpaces(&rgb, end);
fill[i] = fast_atof(&rgb);
}
@ -538,7 +539,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
}
const char *rgb = splitter[1];
ReadFloat3Tuple_Ascii(mat.rgb, &rgb);
ReadFloat3Tuple_Ascii(mat.rgb, &rgb, splitter.getEnd());
++splitter;
if (!splitter.match_start("alpha ")) {
@ -617,20 +618,21 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk
}
const char *rgb = splitter[1];
ReadFloat3Tuple_Ascii(msh.color, &rgb);
const char *end = splitter.getEnd();
ReadFloat3Tuple_Ascii(msh.color, &rgb, end);
SkipSpaces(&rgb);
SkipSpaces(&rgb, end);
if (strncmp(rgb, "cone angle", 10) != 0) {
ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id);
}
SkipSpaces(rgb + 10, &rgb);
SkipSpaces(rgb + 10, &rgb, end);
msh.angle = fast_atof(&rgb);
SkipSpaces(&rgb);
SkipSpaces(&rgb, end);
if (strncmp(rgb, "inner angle", 11) != 0) {
ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
}
SkipSpaces(rgb + 11, &rgb);
SkipSpaces(rgb + 11, &rgb, end);
msh.inner_angle = fast_atof(&rgb);
// skip the rest for we can't handle this kind of physically-based lighting information.
@ -703,14 +705,14 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
const char *s = splitter->c_str();
const char *end = splitter.getEnd();
aiVector3D &v = msh.vertex_positions[cur];
SkipSpaces(&s);
SkipSpaces(&s, end);
v.x = fast_atof(&s);
SkipSpaces(&s);
SkipSpaces(&s, end);
v.y = fast_atof(&s);
SkipSpaces(&s);
SkipSpaces(&s, end);
v.z = fast_atof(&s);
}
} else if (splitter.match_start("Texture Vertices")) {
@ -719,12 +721,13 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
const char *s = splitter->c_str();
const char *end = splitter.getEnd();
aiVector2D &v = msh.texture_coords[cur];
SkipSpaces(&s);
SkipSpaces(&s, end);
v.x = fast_atof(&s);
SkipSpaces(&s);
SkipSpaces(&s, end);
v.y = fast_atof(&s);
}
} else if (splitter.match_start("Faces")) {
@ -749,8 +752,9 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
face.material = strtoul10(splitter[6]);
const char *s = (++splitter)->c_str();
const char *end = splitter.getEnd();
for (size_t i = 0; i < face.indices.size(); ++i) {
if (!SkipSpaces(&s)) {
if (!SkipSpaces(&s, end)) {
ThrowException("Expected EOL token in Face entry");
}
if ('<' != *s++) {

View File

@ -120,7 +120,7 @@ private:
void ReadChunkInfo_Ascii(COB::ChunkInfo &out, const LineSplitter &splitter);
void ReadBasicNodeInfo_Ascii(COB::Node &msh, LineSplitter &splitter, const COB::ChunkInfo &nfo);
template <typename T>
void ReadFloat3Tuple_Ascii(T &fill, const char **in);
void ReadFloat3Tuple_Ascii(T &fill, const char **in, const char *end);
void ReadPolH_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadBitM_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);

View File

@ -82,23 +82,20 @@ CSMImporter::CSMImporter() : noSkeletonMesh(){
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
{
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const {
static const char* tokens[] = {"$Filename"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------
// Build a string of all file extensions supported
const aiImporterDesc* CSMImporter::GetInfo () const
{
const aiImporterDesc* CSMImporter::GetInfo () const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
void CSMImporter::SetupProperties(const Importer* pImp)
{
void CSMImporter::SetupProperties(const Importer* pImp) {
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
}
@ -118,29 +115,29 @@ void CSMImporter::InternReadFile( const std::string& pFile,
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0];
const char *end = &mBuffer2[mBuffer2.size() - 1] + 1;
std::unique_ptr<aiAnimation> anim(new aiAnimation());
int first = 0, last = 0x00ffffff;
// now process the file and look out for '$' sections
while (true) {
SkipSpaces(&buffer);
SkipSpaces(&buffer, end);
if ('\0' == *buffer)
break;
if ('$' == *buffer) {
++buffer;
if (TokenMatchI(buffer,"firstframe",10)) {
SkipSpaces(&buffer);
SkipSpaces(&buffer, end);
first = strtol10(buffer,&buffer);
}
else if (TokenMatchI(buffer,"lastframe",9)) {
SkipSpaces(&buffer);
SkipSpaces(&buffer, end);
last = strtol10(buffer,&buffer);
}
else if (TokenMatchI(buffer,"rate",4)) {
SkipSpaces(&buffer);
float d;
SkipSpaces(&buffer, end);
float d = { 0.0f };
buffer = fast_atoreal_move<float>(buffer,d);
anim->mTicksPerSecond = d;
}
@ -148,8 +145,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
std::vector< aiNodeAnim* > anims_temp;
anims_temp.reserve(30);
while (true) {
SkipSpaces(&buffer);
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
SkipSpaces(&buffer, end);
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer, end) && *buffer == '$')
break; // next section
// Construct a new node animation channel and setup its name
@ -157,41 +154,43 @@ void CSMImporter::InternReadFile( const std::string& pFile,
aiNodeAnim* nda = anims_temp.back();
char* ot = nda->mNodeName.data;
while (!IsSpaceOrNewLine(*buffer))
while (!IsSpaceOrNewLine(*buffer)) {
*ot++ = *buffer++;
}
*ot = '\0';
nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data);
}
anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
if (!anim->mNumChannels)
if (!anim->mNumChannels) {
throw DeadlyImportError("CSM: Empty $order section");
}
// copy over to the output animation
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
}
else if (TokenMatchI(buffer,"points",6)) {
if (!anim->mNumChannels)
} else if (TokenMatchI(buffer,"points",6)) {
if (!anim->mNumChannels) {
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
}
// If we know how many frames we'll read, we can preallocate some storage
unsigned int alloc = 100;
if (last != 0x00ffffff)
{
if (last != 0x00ffffff) {
alloc = last-first;
alloc += alloc>>2u; // + 25%
for (unsigned int i = 0; i < anim->mNumChannels;++i)
for (unsigned int i = 0; i < anim->mNumChannels; ++i) {
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
}
}
unsigned int filled = 0;
// Now read all point data.
while (true) {
SkipSpaces(&buffer);
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
SkipSpaces(&buffer, end);
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer, end) || *buffer == '$')) {
break; // next section
}
@ -202,8 +201,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
aiNodeAnim* s = anim->mChannels[i];
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
if (s->mNumPositionKeys == alloc) {
// need to reallocate?
aiVectorKey* old = s->mPositionKeys;
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
@ -211,24 +210,26 @@ void CSMImporter::InternReadFile( const std::string& pFile,
}
// read x,y,z
if(!SkipSpacesAndLineEnd(&buffer))
if (!SkipSpacesAndLineEnd(&buffer, end)) {
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample x coord");
}
if (TokenMatchI(buffer, "DROPOUT", 7)) {
// seems this is invalid marker data; at least the doc says it's possible
ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)");
}
else {
} else {
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
sub->mTime = (double)frame;
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
if(!SkipSpacesAndLineEnd(&buffer))
if (!SkipSpacesAndLineEnd(&buffer, end)) {
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
}
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
if(!SkipSpacesAndLineEnd(&buffer))
if (!SkipSpacesAndLineEnd(&buffer, end)) {
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
}
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
++s->mNumPositionKeys;
@ -236,22 +237,22 @@ void CSMImporter::InternReadFile( const std::string& pFile,
}
// update allocation granularity
if (filled == alloc)
if (filled == alloc) {
alloc *= 2;
}
++filled;
}
// all channels must be complete in order to continue safely.
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
if (!anim->mChannels[i]->mNumPositionKeys)
if (!anim->mChannels[i]->mNumPositionKeys) {
throw DeadlyImportError("CSM: Invalid marker track");
}
}
}
}
else {
} else {
// advance to the next line
SkipLine(&buffer);
SkipLine(&buffer, end);
}
}
@ -265,7 +266,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
pScene->mRootNode->mNumChildren = anim->mNumChannels;
pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
aiNodeAnim* na = anim->mChannels[i];
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();

View File

@ -654,12 +654,13 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
std::string v;
XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str();
const char *end = content + v.size();
for (unsigned int a = 0; a < 16; a++) {
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
// read a number
content = fast_atoreal_move<ai_real>(content, controller.mBindShapeMatrix[a]);
// skip whitespace after it
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
}
} else if (currentName == "source") {
ReadSource(currentNode);
@ -740,7 +741,9 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
}
} else if (currentName == "vcount" && vertexCount > 0) {
const char *text = currentNode.text().as_string();
const std::string stdText = currentNode.text().as_string();
const char *text = stdText.c_str();
const char *end = text + stdText.size();
size_t numWeights = 0;
for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
if (*text == 0) {
@ -749,7 +752,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
*it = strtoul10(text, &text);
numWeights += *it;
SkipSpacesAndLineEnd(&text);
SkipSpacesAndLineEnd(&text, end);
}
// reserve weight count
pController.mWeights.resize(numWeights);
@ -758,18 +761,19 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
std::string stdText;
XmlParser::getValueAsString(currentNode, stdText);
const char *text = stdText.c_str();
const char *end = text + stdText.size();
for (std::vector<std::pair<size_t, size_t>>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
if (text == nullptr) {
throw DeadlyImportError("Out of data while reading <vertex_weights>");
}
SkipSpacesAndLineEnd(&text);
SkipSpacesAndLineEnd(&text, end);
it->first = strtoul10(text, &text);
SkipSpacesAndLineEnd(&text);
SkipSpacesAndLineEnd(&text, end);
if (*text == 0) {
throw DeadlyImportError("Out of data while reading <vertex_weights>");
}
it->second = strtoul10(text, &text);
SkipSpacesAndLineEnd(&text);
SkipSpacesAndLineEnd(&text, end);
}
}
}
@ -952,15 +956,16 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
std::string v;
XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str();
const char *end = content + v.size();
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
} else if (currentName == "constant_attenuation") {
XmlParser::getValueAsFloat(currentNode, pLight.mAttConstant);
} else if (currentName == "linear_attenuation") {
@ -1220,18 +1225,19 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
std::string v;
XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str();
const char *end = v.c_str() + v.size() + 1;
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
} else if (currentName == "texture") {
// get name of source texture/sampler
XmlParser::getStdStrAttribute(currentNode, "texture", pSampler.mName);
@ -1345,6 +1351,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
if (node.empty()) {
return;
}
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "mesh") {
@ -1415,6 +1422,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
XmlParser::getValueAsString(node, v);
v = ai_trim(v);
const char *content = v.c_str();
const char *end = content + v.size();
// read values and store inside an array in the data library
mDataLibrary[id] = Data();
@ -1433,11 +1441,13 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
}
s.clear();
while (!IsSpaceOrNewLine(*content))
s += *content++;
while (!IsSpaceOrNewLine(*content)) {
s += *content;
content++;
}
data.mStrings.push_back(s);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
}
} else {
data.mValues.reserve(count);
@ -1452,7 +1462,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
content = fast_atoreal_move<ai_real>(content, value);
data.mValues.push_back(value);
// skip whitespace after it
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
}
}
}
@ -1617,8 +1627,10 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
std::string v;
XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str();
const char *end = content + v.size();
vcount.reserve(numPrimitives);
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
for (unsigned int a = 0; a < numPrimitives; a++) {
if (*content == 0) {
throw DeadlyImportError("Expected more values while reading <vcount> contents.");
@ -1626,7 +1638,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
// read a number
vcount.push_back((size_t)strtoul10(content, &content));
// skip whitespace after it
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
}
}
}
@ -1735,14 +1747,16 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
std::string v;
XmlParser::getValueAsString(node, v);
const char *content = v.c_str();
SkipSpacesAndLineEnd(&content);
const char *end = content + v.size();
SkipSpacesAndLineEnd(&content, end);
while (*content != 0) {
// read a value.
// Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
int value = std::max(0, strtol10(content, &content));
indices.push_back(size_t(value));
// skip whitespace after it
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
}
}
@ -1801,8 +1815,10 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
size_t numPrimitives = pNumPrimitives;
if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon) {
numPrimitives = 1;
}
// For continued primitives, the given count is actually the number of <p>'s inside the parent tag
if (pPrimType == Prim_TriStrips) {
size_t numberOfVertices = indices.size() / numOffsets;
@ -2166,15 +2182,15 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
}
// how many parameters to read per transformation type
static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
static constexpr unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
std::string value;
XmlParser::getValueAsString(node, value);
const char *content = value.c_str();
const char *end = value.c_str() + value.size();
// read as many parameters and store in the transformation
for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
// skip whitespace before the number
SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
// read a number
content = fast_atoreal_move<ai_real>(content, tf.f[a]);
}

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the DXF importer class
*/
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
#include "AssetLib/DXF/DXFLoader.h"
@ -68,25 +67,267 @@ static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT;
// default vertex color that all uncolored vertices will receive
static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
// color indices for DXF - 16 are supported, the table is
// taken directly from the DXF spec.
static const aiColor4D g_aclrDxfIndexColors[] = {
aiColor4D(0.6f, 0.6f, 0.6f, 1.0f),
aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
aiColor4D (0.6f, 0.0f, 1.0f, 1.0f) // violet
// color indices for DXF - 256 are supported, the table is
// taken directly from the AutoCad Index (ACI) table
// https://gohtx.com/acadcolors.php
//STH 2024-0126
static const aiColor4D g_aclrDxfIndexColors[256] = {
aiColor4D (0.0f, 0.0f ,0.0f, 1.0f), //dxf color code 0
aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 1
aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 2
aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 3
aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 4
aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 5
aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 6
aiColor4D (1.0f, 1.0f ,1.0f, 1.0f), //dxf color code 7
aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 8
aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 9
aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 10
aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 11
aiColor4D (0.7f, 0.0f ,0.0f, 1.0f), //dxf color code 12
aiColor4D (0.7f, 0.5f ,0.5f, 1.0f), //dxf color code 13
aiColor4D (0.5f, 0.0f ,0.0f, 1.0f), //dxf color code 14
aiColor4D (0.5f, 0.3f ,0.3f, 1.0f), //dxf color code 15
aiColor4D (0.4f, 0.0f ,0.0f, 1.0f), //dxf color code 16
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 17
aiColor4D (0.3f, 0.0f ,0.0f, 1.0f), //dxf color code 18
aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 19
aiColor4D (1.0f, 0.2f ,0.0f, 1.0f), //dxf color code 20
aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 21
aiColor4D (0.7f, 0.2f ,0.0f, 1.0f), //dxf color code 22
aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 23
aiColor4D (0.5f, 0.1f ,0.0f, 1.0f), //dxf color code 24
aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 25
aiColor4D (0.4f, 0.1f ,0.0f, 1.0f), //dxf color code 26
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 27
aiColor4D (0.3f, 0.1f ,0.0f, 1.0f), //dxf color code 28
aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 29
aiColor4D (1.0f, 0.5f ,0.0f, 1.0f), //dxf color code 30
aiColor4D (1.0f, 0.8f ,0.7f, 1.0f), //dxf color code 31
aiColor4D (0.7f, 0.4f ,0.0f, 1.0f), //dxf color code 32
aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 33
aiColor4D (0.5f, 0.3f ,0.0f, 1.0f), //dxf color code 34
aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 35
aiColor4D (0.4f, 0.2f ,0.0f, 1.0f), //dxf color code 36
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 37
aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 38
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 39
aiColor4D (1.0f, 0.7f ,0.0f, 1.0f), //dxf color code 40
aiColor4D (1.0f, 0.9f ,0.7f, 1.0f), //dxf color code 41
aiColor4D (0.7f, 0.6f ,0.0f, 1.0f), //dxf color code 42
aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 43
aiColor4D (0.5f, 0.4f ,0.0f, 1.0f), //dxf color code 44
aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 45
aiColor4D (0.4f, 0.3f ,0.0f, 1.0f), //dxf color code 46
aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 47
aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 48
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 49
aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 50
aiColor4D (1.0f, 1.0f ,0.7f, 1.0f), //dxf color code 51
aiColor4D (0.7f, 0.7f ,0.0f, 1.0f), //dxf color code 52
aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 53
aiColor4D (0.5f, 0.5f ,0.0f, 1.0f), //dxf color code 54
aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 55
aiColor4D (0.4f, 0.4f ,0.0f, 1.0f), //dxf color code 56
aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 57
aiColor4D (0.3f, 0.3f ,0.0f, 1.0f), //dxf color code 58
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 59
aiColor4D (0.7f, 1.0f ,0.0f, 1.0f), //dxf color code 60
aiColor4D (0.9f, 1.0f ,0.7f, 1.0f), //dxf color code 61
aiColor4D (0.6f, 0.7f ,0.0f, 1.0f), //dxf color code 62
aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 63
aiColor4D (0.4f, 0.5f ,0.0f, 1.0f), //dxf color code 64
aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 65
aiColor4D (0.3f, 0.4f ,0.0f, 1.0f), //dxf color code 66
aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 67
aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 68
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 69
aiColor4D (0.5f, 1.0f ,0.0f, 1.0f), //dxf color code 70
aiColor4D (0.8f, 1.0f ,0.7f, 1.0f), //dxf color code 71
aiColor4D (0.4f, 0.7f ,0.0f, 1.0f), //dxf color code 72
aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 73
aiColor4D (0.3f, 0.5f ,0.0f, 1.0f), //dxf color code 74
aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 75
aiColor4D (0.2f, 0.4f ,0.0f, 1.0f), //dxf color code 76
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 77
aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 78
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 79
aiColor4D (0.2f, 1.0f ,0.0f, 1.0f), //dxf color code 80
aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 81
aiColor4D (0.2f, 0.7f ,0.0f, 1.0f), //dxf color code 82
aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 83
aiColor4D (0.1f, 0.5f ,0.0f, 1.0f), //dxf color code 84
aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 85
aiColor4D (0.1f, 0.4f ,0.0f, 1.0f), //dxf color code 86
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 87
aiColor4D (0.1f, 0.3f ,0.0f, 1.0f), //dxf color code 88
aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 89
aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 90
aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 91
aiColor4D (0.0f, 0.7f ,0.0f, 1.0f), //dxf color code 92
aiColor4D (0.5f, 0.7f ,0.5f, 1.0f), //dxf color code 93
aiColor4D (0.0f, 0.5f ,0.0f, 1.0f), //dxf color code 94
aiColor4D (0.3f, 0.5f ,0.3f, 1.0f), //dxf color code 95
aiColor4D (0.0f, 0.4f ,0.0f, 1.0f), //dxf color code 96
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 97
aiColor4D (0.0f, 0.3f ,0.0f, 1.0f), //dxf color code 98
aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 99
aiColor4D (0.0f, 1.0f ,0.2f, 1.0f), //dxf color code 100
aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 101
aiColor4D (0.0f, 0.7f ,0.2f, 1.0f), //dxf color code 102
aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 103
aiColor4D (0.0f, 0.5f ,0.1f, 1.0f), //dxf color code 104
aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 105
aiColor4D (0.0f, 0.4f ,0.1f, 1.0f), //dxf color code 106
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 107
aiColor4D (0.0f, 0.3f ,0.1f, 1.0f), //dxf color code 108
aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 109
aiColor4D (0.0f, 1.0f ,0.5f, 1.0f), //dxf color code 110
aiColor4D (0.7f, 1.0f ,0.8f, 1.0f), //dxf color code 111
aiColor4D (0.0f, 0.7f ,0.4f, 1.0f), //dxf color code 112
aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 113
aiColor4D (0.0f, 0.5f ,0.3f, 1.0f), //dxf color code 114
aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 115
aiColor4D (0.0f, 0.4f ,0.2f, 1.0f), //dxf color code 116
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 117
aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 118
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 119
aiColor4D (0.0f, 1.0f ,0.7f, 1.0f), //dxf color code 120
aiColor4D (0.7f, 1.0f ,0.9f, 1.0f), //dxf color code 121
aiColor4D (0.0f, 0.7f ,0.6f, 1.0f), //dxf color code 122
aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 123
aiColor4D (0.0f, 0.5f ,0.4f, 1.0f), //dxf color code 124
aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 125
aiColor4D (0.0f, 0.4f ,0.3f, 1.0f), //dxf color code 126
aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 127
aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 128
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 129
aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 130
aiColor4D (0.7f, 1.0f ,1.0f, 1.0f), //dxf color code 131
aiColor4D (0.0f, 0.7f ,0.7f, 1.0f), //dxf color code 132
aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 133
aiColor4D (0.0f, 0.5f ,0.5f, 1.0f), //dxf color code 134
aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 135
aiColor4D (0.0f, 0.4f ,0.4f, 1.0f), //dxf color code 136
aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 137
aiColor4D (0.0f, 0.3f ,0.3f, 1.0f), //dxf color code 138
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 139
aiColor4D (0.0f, 0.7f ,1.0f, 1.0f), //dxf color code 140
aiColor4D (0.7f, 0.9f ,1.0f, 1.0f), //dxf color code 141
aiColor4D (0.0f, 0.6f ,0.7f, 1.0f), //dxf color code 142
aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 143
aiColor4D (0.0f, 0.4f ,0.5f, 1.0f), //dxf color code 144
aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 145
aiColor4D (0.0f, 0.3f ,0.4f, 1.0f), //dxf color code 146
aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 147
aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 148
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 149
aiColor4D (0.0f, 0.5f ,1.0f, 1.0f), //dxf color code 150
aiColor4D (0.7f, 0.8f ,1.0f, 1.0f), //dxf color code 151
aiColor4D (0.0f, 0.4f ,0.7f, 1.0f), //dxf color code 152
aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 153
aiColor4D (0.0f, 0.3f ,0.5f, 1.0f), //dxf color code 154
aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 155
aiColor4D (0.0f, 0.2f ,0.4f, 1.0f), //dxf color code 156
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 157
aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 158
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 159
aiColor4D (0.0f, 0.2f ,1.0f, 1.0f), //dxf color code 160
aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 161
aiColor4D (0.0f, 0.2f ,0.7f, 1.0f), //dxf color code 162
aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 163
aiColor4D (0.0f, 0.1f ,0.5f, 1.0f), //dxf color code 164
aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 165
aiColor4D (0.0f, 0.1f ,0.4f, 1.0f), //dxf color code 166
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 167
aiColor4D (0.0f, 0.1f ,0.3f, 1.0f), //dxf color code 168
aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 169
aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 170
aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 171
aiColor4D (0.0f, 0.0f ,0.7f, 1.0f), //dxf color code 172
aiColor4D (0.5f, 0.5f ,0.7f, 1.0f), //dxf color code 173
aiColor4D (0.0f, 0.0f ,0.5f, 1.0f), //dxf color code 174
aiColor4D (0.3f, 0.3f ,0.5f, 1.0f), //dxf color code 175
aiColor4D (0.0f, 0.0f ,0.4f, 1.0f), //dxf color code 176
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 177
aiColor4D (0.0f, 0.0f ,0.3f, 1.0f), //dxf color code 178
aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 179
aiColor4D (0.2f, 0.0f ,1.0f, 1.0f), //dxf color code 180
aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 181
aiColor4D (0.2f, 0.0f ,0.7f, 1.0f), //dxf color code 182
aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 183
aiColor4D (0.1f, 0.0f ,0.5f, 1.0f), //dxf color code 184
aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 185
aiColor4D (0.1f, 0.0f ,0.4f, 1.0f), //dxf color code 186
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 187
aiColor4D (0.1f, 0.0f ,0.3f, 1.0f), //dxf color code 188
aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 189
aiColor4D (0.5f, 0.0f ,1.0f, 1.0f), //dxf color code 190
aiColor4D (0.8f, 0.7f ,1.0f, 1.0f), //dxf color code 191
aiColor4D (0.4f, 0.0f ,0.7f, 1.0f), //dxf color code 192
aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 193
aiColor4D (0.3f, 0.0f ,0.5f, 1.0f), //dxf color code 194
aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 195
aiColor4D (0.2f, 0.0f ,0.4f, 1.0f), //dxf color code 196
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 197
aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 198
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 199
aiColor4D (0.7f, 0.0f ,1.0f, 1.0f), //dxf color code 200
aiColor4D (0.9f, 0.7f ,1.0f, 1.0f), //dxf color code 201
aiColor4D (0.6f, 0.0f ,0.7f, 1.0f), //dxf color code 202
aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 203
aiColor4D (0.4f, 0.0f ,0.5f, 1.0f), //dxf color code 204
aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 205
aiColor4D (0.3f, 0.0f ,0.4f, 1.0f), //dxf color code 206
aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 207
aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 208
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 209
aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 210
aiColor4D (1.0f, 0.7f ,1.0f, 1.0f), //dxf color code 211
aiColor4D (0.7f, 0.0f ,0.7f, 1.0f), //dxf color code 212
aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 213
aiColor4D (0.5f, 0.0f ,0.5f, 1.0f), //dxf color code 214
aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 215
aiColor4D (0.4f, 0.0f ,0.4f, 1.0f), //dxf color code 216
aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 217
aiColor4D (0.3f, 0.0f ,0.3f, 1.0f), //dxf color code 218
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 219
aiColor4D (1.0f, 0.0f ,0.7f, 1.0f), //dxf color code 220
aiColor4D (1.0f, 0.7f ,0.9f, 1.0f), //dxf color code 221
aiColor4D (0.7f, 0.0f ,0.6f, 1.0f), //dxf color code 222
aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 223
aiColor4D (0.5f, 0.0f ,0.4f, 1.0f), //dxf color code 224
aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 225
aiColor4D (0.4f, 0.0f ,0.3f, 1.0f), //dxf color code 226
aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 227
aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 228
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 229
aiColor4D (1.0f, 0.0f ,0.5f, 1.0f), //dxf color code 230
aiColor4D (1.0f, 0.7f ,0.8f, 1.0f), //dxf color code 231
aiColor4D (0.7f, 0.0f ,0.4f, 1.0f), //dxf color code 232
aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 233
aiColor4D (0.5f, 0.0f ,0.3f, 1.0f), //dxf color code 234
aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 235
aiColor4D (0.4f, 0.0f ,0.2f, 1.0f), //dxf color code 236
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 237
aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 238
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 239
aiColor4D (1.0f, 0.0f ,0.2f, 1.0f), //dxf color code 240
aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 241
aiColor4D (0.7f, 0.0f ,0.2f, 1.0f), //dxf color code 242
aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 243
aiColor4D (0.5f, 0.0f ,0.1f, 1.0f), //dxf color code 244
aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 245
aiColor4D (0.4f, 0.0f ,0.1f, 1.0f), //dxf color code 246
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 247
aiColor4D (0.3f, 0.0f ,0.1f, 1.0f), //dxf color code 248
aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 249
aiColor4D (0.2f, 0.2f ,0.2f, 1.0f), //dxf color code 250
aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 251
aiColor4D (0.4f, 0.4f ,0.4f, 1.0f), //dxf color code 252
aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 253
aiColor4D (0.7f, 0.7f ,0.7f, 1.0f), //dxf color code 254
aiColor4D (1.0f, 1.0f ,1.0f, 1.0f) //dxf color code 255
};
#define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
@ -372,8 +613,12 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
// XXX order
aiMatrix4x4 trafo, tmp;
aiMatrix4x4::Translation(-bl_src.base,trafo);
trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
//Need to translate position before scaling the insert
//otherwise the position ends up being the position*scaling
//STH 2024.01.17
trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
//trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
// XXX rotation currently ignored - I didn't find an appropriate sample model.
if (insert.angle != 0.f) {

View File

@ -1807,7 +1807,7 @@ void FBXExporter::WriteObjects ()
p.AddP70numberA("DeformPercent", 0.0);
sdnode.AddChild(p);
// TODO: Normally just one weight per channel, adding stub for later development
std::vector<float>fFullWeights;
std::vector<double>fFullWeights;
fFullWeights.push_back(100.);
sdnode.AddChild("FullWeights", fFullWeights);
sdnode.Dump(outstream, binary, indent);

View File

@ -2725,6 +2725,10 @@ template <> size_t GenericFill<IfcSpatialStructureElement>(const DB& db, const L
do { // convert the 'CompositionType' argument
std::shared_ptr<const DataType> arg = params[base++];
if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSpatialStructureElement,2>::aux_is_derived[1]=true; break; }
if (dynamic_cast<const UNSET *>(&*arg)) {
// Consider assigning the default value as in->CompositionType = "ELEMENT".
break;
}
try { GenericConvert( in->CompositionType, arg, db ); break; }
catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSpatialStructureElement to be a `IfcElementCompositionEnum`")); }
} while (false);

View File

@ -1234,7 +1234,10 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Parse the XML
// Find the scene root from document root.
const pugi::xml_node &sceneRoot = documentRoot.child("irr_scene");
if (!sceneRoot) throw new DeadlyImportError("IRR: <irr_scene> not found in file");
if (!sceneRoot) {
delete root;
throw new DeadlyImportError("IRR: <irr_scene> not found in file");
}
for (pugi::xml_node &child : sceneRoot.children()) {
// XML elements are either nodes, animators, attributes, or materials
if (!ASSIMP_stricmp(child.name(), "node")) {

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -69,14 +69,6 @@ static constexpr aiImporterDesc desc = {
"xml irrmesh"
};
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
IRRMeshImporter::IRRMeshImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
IRRMeshImporter::~IRRMeshImporter() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool IRRMeshImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -116,8 +108,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
// Check whether we can read from the file
if (file == nullptr)
if (file == nullptr) {
throw DeadlyImportError("Failed to open IRRMESH file ", pFile);
}
// Construct the irrXML parser
XmlParser parser;
@ -148,13 +141,11 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
bool useColors = false;
/*
** irrmesh files have a top level <mesh> owning multiple <buffer> nodes.
** Each <buffer> contains <material>, <vertices>, and <indices>
** <material> tags here directly owns the material data specs
** <vertices> are a vertex per line, contains position, UV1 coords, maybe UV2, normal, tangent, bitangent
** <boundingbox> is ignored, I think assimp recalculates those?
*/
// irrmesh files have a top level <mesh> owning multiple <buffer> nodes.
// Each <buffer> contains <material>, <vertices>, and <indices>
// <material> tags here directly owns the material data specs
// <vertices> are a vertex per line, contains position, UV1 coords, maybe UV2, normal, tangent, bitangent
// <boundingbox> is ignored, I think assimp recalculates those?
// Parse the XML file
pugi::xml_node const &meshNode = root.child("mesh");
@ -201,7 +192,6 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// This is possible ... remove the mesh from the list and skip further reading
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero vertices");
releaseMaterial(&curMat);
// releaseMesh(&curMesh);
continue; // Bail out early
};
@ -250,7 +240,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
};
// We know what format buffer is, collect numbers
ParseBufferVertices(verticesNode.text().get(), vertexFormat,
std::string v = verticesNode.text().get();
const char *end = v.c_str() + v.size();
ParseBufferVertices(v.c_str(), end, vertexFormat,
curVertices, curNormals,
curTangents, curBitangents,
curUVs, curUV2s, curColors, useColors);
@ -329,8 +321,10 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// NOTE this might explode for UTF-16 and wchars
const char *sz = indicesNode.text().get();
const char *end = sz + std::strlen(sz);
// For each index loop over aiMesh faces
while (SkipSpacesAndLineEnd(&sz)) {
while (SkipSpacesAndLineEnd(&sz, end)) {
if (curFace >= faceEnd) {
ASSIMP_LOG_ERROR("IRRMESH: Too many indices");
break;
@ -354,12 +348,18 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// Copy over data to aiMesh
*pcV++ = curVertices[idx];
if (pcN) *pcN++ = curNormals[idx];
if (pcT) *pcT++ = curTangents[idx];
if (pcB) *pcB++ = curBitangents[idx];
if (pcC0) *pcC0++ = curColors[idx];
if (pcT0) *pcT0++ = curUVs[idx];
if (pcT1) *pcT1++ = curUV2s[idx];
if (pcN)
*pcN++ = curNormals[idx];
if (pcT)
*pcT++ = curTangents[idx];
if (pcB)
*pcB++ = curBitangents[idx];
if (pcC0)
*pcC0++ = curColors[idx];
if (pcT0)
*pcT0++ = curUVs[idx];
if (pcT1)
*pcT1++ = curUV2s[idx];
// start new face
if (++curIdx == 3) {
@ -368,8 +368,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
}
}
// We should be at the end of mFaces
if (curFace != faceEnd)
if (curFace != faceEnd) {
ASSIMP_LOG_ERROR("IRRMESH: Not enough indices");
}
}
// Finish processing the mesh - do some small material workarounds
@ -379,8 +380,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
aiMaterial *mat = (aiMaterial *)curMat;
mat->AddProperty(&curColors[0].a, 1, AI_MATKEY_OPACITY);
}
// textMeaning = 2;
// end of previous buffer. A material and a mesh should be there
if (!curMat || !curMesh) {
ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
@ -421,37 +421,37 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
};
}
void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFormat,
void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, VertexFormat vertexFormat,
std::vector<aiVector3D> &vertices, std::vector<aiVector3D> &normals,
std::vector<aiVector3D> &tangents, std::vector<aiVector3D> &bitangents,
std::vector<aiVector3D> &UVs, std::vector<aiVector3D> &UV2s,
std::vector<aiColor4D> &colors, bool &useColors) {
// read vertices
do {
SkipSpacesAndLineEnd(&sz);
SkipSpacesAndLineEnd(&sz, end);
aiVector3D temp;
aiColor4D c;
// Read the vertex position
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
vertices.push_back(temp);
// Read the vertex normals
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
normals.push_back(temp);
// read the vertex colors
@ -463,14 +463,14 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
useColors = true;
colors.push_back(c);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
// read the first UV coordinate set
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
temp.z = 0.f;
temp.y = 1.f - temp.y; // DX to OGL
UVs.push_back(temp);
@ -480,7 +480,7 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
// read the (optional) second UV coordinate set
if (vertexFormat == VertexFormat::t2coord) {
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
temp.y = 1.f - temp.y; // DX to OGL
@ -490,33 +490,32 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
else if (vertexFormat == VertexFormat::tangent) {
// tangents
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
temp.y *= -1.0f;
tangents.push_back(temp);
// bitangents
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
SkipSpaces(&sz, end);
temp.y *= -1.0f;
bitangents.push_back(temp);
}
} while (SkipLine(&sz));
/* IMPORTANT: We assume that each vertex is specified in one
line. So we can skip the rest of the line - unknown vertex
elements are ignored.
*/
} while (SkipLine(&sz, end));
// IMPORTANT: We assume that each vertex is specified in one
// line. So we can skip the rest of the line - unknown vertex
// elements are ignored.
}
#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -62,8 +62,11 @@ namespace Assimp {
*/
class IRRMeshImporter : public BaseImporter, public IrrlichtBase {
public:
IRRMeshImporter();
~IRRMeshImporter() override;
/// @brief The class constructor.
IRRMeshImporter() = default;
/// @brief The class destructor.
~IRRMeshImporter() override = default;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
@ -93,7 +96,7 @@ private:
tangent = 2, // "tangents" - standard + tangents and bitangents
};
void ParseBufferVertices(const char *sz, VertexFormat vertexFormat,
void ParseBufferVertices(const char *sz, const char *end, VertexFormat vertexFormat,
std::vector<aiVector3D> &vertices, std::vector<aiVector3D> &normals,
std::vector<aiVector3D> &tangents, std::vector<aiVector3D> &bitangents,
std::vector<aiVector3D> &UVs, std::vector<aiVector3D> &UV2s,

View File

@ -135,21 +135,23 @@ void IrrlichtBase::ReadVectorProperty(VectorProperty &out, pugi::xml_node& vecto
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// three floats, separated with commas
const char *ptr = attrib.value();
size_t len = std::strlen(ptr);
const char *end = ptr + len;
SkipSpaces(&ptr);
SkipSpaces(&ptr, end);
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.x);
SkipSpaces(&ptr);
SkipSpaces(&ptr, end);
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
SkipSpaces(ptr + 1, &ptr);
SkipSpaces(ptr + 1, &ptr, end);
}
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.y);
SkipSpaces(&ptr);
SkipSpaces(&ptr, end);
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
SkipSpaces(ptr + 1, &ptr);
SkipSpaces(ptr + 1, &ptr, end);
}
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.z);
}

View File

@ -152,7 +152,7 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator &it,
LE_NCONST uint16_t*& cursor,
const uint16_t* const end,
unsigned int max) {

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -78,14 +78,14 @@ static constexpr aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Recursive parsing of LWS files
void LWS::Element::Parse(const char *&buffer) {
for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
void LWS::Element::Parse(const char *&buffer, const char *end) {
for (; SkipSpacesAndLineEnd(&buffer, end); SkipLine(&buffer, end)) {
// begin of a new element with children
bool sub = false;
if (*buffer == '{') {
++buffer;
SkipSpaces(&buffer);
SkipSpaces(&buffer, end);
sub = true;
} else if (*buffer == '}')
return;
@ -98,16 +98,15 @@ void LWS::Element::Parse(const char *&buffer) {
while (!IsSpaceOrNewLine(*buffer))
++buffer;
children.back().tokens[0] = std::string(cur, (size_t)(buffer - cur));
SkipSpaces(&buffer);
SkipSpaces(&buffer, end);
if (children.back().tokens[0] == "Plugin") {
ASSIMP_LOG_VERBOSE_DEBUG("LWS: Skipping over plugin-specific data");
// strange stuff inside Plugin/Endplugin blocks. Needn't
// follow LWS syntax, so we skip over it
for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
for (; SkipSpacesAndLineEnd(&buffer, end); SkipLine(&buffer, end)) {
if (!::strncmp(buffer, "EndPlugin", 9)) {
//SkipLine(&buffer);
break;
}
}
@ -122,7 +121,7 @@ void LWS::Element::Parse(const char *&buffer) {
// parse more elements recursively
if (sub) {
children.back().Parse(buffer);
children.back().Parse(buffer, end);
}
}
}
@ -155,6 +154,8 @@ const aiImporterDesc *LWSImporter::GetInfo() const {
return &desc;
}
static constexpr int MagicHackNo = 150392;
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void LWSImporter::SetupProperties(const Importer *pImp) {
@ -163,11 +164,11 @@ void LWSImporter::SetupProperties(const Importer *pImp) {
// AI_CONFIG_IMPORT_LWS_ANIM_START
first = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_START,
150392 /* magic hack */);
MagicHackNo /* magic hack */);
// AI_CONFIG_IMPORT_LWS_ANIM_END
last = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_END,
150392 /* magic hack */);
MagicHackNo /* magic hack */);
if (last < first) {
std::swap(last, first);
@ -191,15 +192,16 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
for (++it; it != dad.children.end(); ++it) {
const char *c = (*it).tokens[1].c_str();
const char *end = c + (*it).tokens[1].size();
if ((*it).tokens[0] == "Key") {
fill.keys.emplace_back();
LWO::Key &key = fill.keys.back();
float f;
SkipSpaces(&c);
SkipSpaces(&c, end);
c = fast_atoreal_move<float>(c, key.value);
SkipSpaces(&c);
SkipSpaces(&c, end);
c = fast_atoreal_move<float>(c, f);
key.time = f;
@ -231,13 +233,13 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
ASSIMP_LOG_ERROR("LWS: Unknown span type");
}
for (unsigned int i = 0; i < num; ++i) {
SkipSpaces(&c);
SkipSpaces(&c, end);
c = fast_atoreal_move<float>(c, key.params[i]);
}
} else if ((*it).tokens[0] == "Behaviors") {
SkipSpaces(&c);
SkipSpaces(&c, end);
fill.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
SkipSpaces(&c, end);
fill.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
}
}
@ -245,47 +247,45 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
// ------------------------------------------------------------------------------------------------
// Read animation channels in the old LightWave animation format
void LWSImporter::ReadEnvelope_Old(
std::list<LWS::Element>::const_iterator &it,
const std::list<LWS::Element>::const_iterator &end,
LWS::NodeDesc &nodes,
unsigned int /*version*/) {
unsigned int num, sub_num;
if (++it == end) goto unexpected_end;
void LWSImporter::ReadEnvelope_Old(std::list<LWS::Element>::const_iterator &it,const std::list<LWS::Element>::const_iterator &endIt,
LWS::NodeDesc &nodes, unsigned int) {
if (++it == endIt) {
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
return;
}
num = strtoul10((*it).tokens[0].c_str());
const unsigned int num = strtoul10((*it).tokens[0].c_str());
for (unsigned int i = 0; i < num; ++i) {
nodes.channels.emplace_back();
LWO::Envelope &envl = nodes.channels.back();
envl.index = i;
envl.type = (LWO::EnvelopeType)(i + 1);
if (++it == end) {
goto unexpected_end;
if (++it == endIt) {
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
return;
}
sub_num = strtoul10((*it).tokens[0].c_str());
const unsigned int sub_num = strtoul10((*it).tokens[0].c_str());
for (unsigned int n = 0; n < sub_num; ++n) {
if (++it == end) goto unexpected_end;
if (++it == endIt) {
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
return;
}
// parse value and time, skip the rest for the moment.
LWO::Key key;
const char *c = fast_atoreal_move<float>((*it).tokens[0].c_str(), key.value);
SkipSpaces(&c);
const char *end = c + (*it).tokens[0].size();
SkipSpaces(&c, end);
float f;
fast_atoreal_move<float>((*it).tokens[0].c_str(), f);
key.time = f;
envl.keys.push_back(key);
envl.keys.emplace_back(key);
}
}
return;
unexpected_end:
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
}
// ------------------------------------------------------------------------------------------------
@ -296,7 +296,6 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
// the name depends on the type. We break LWS's strange naming convention
// and return human-readable, but still machine-parsable and unique, strings.
if (src.type == LWS::NodeDesc::OBJECT) {
if (src.path.length()) {
std::string::size_type s = src.path.find_last_of("\\/");
if (s == std::string::npos) {
@ -501,7 +500,8 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Parse the file structure
LWS::Element root;
const char *dummy = &mBuffer[0];
root.Parse(dummy);
const char *dummyEnd = dummy + mBuffer.size();
root.Parse(dummy, dummyEnd);
// Construct a Batch-importer to read more files recursively
BatchLoader batch(pIOHandler);
@ -540,6 +540,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Now read all elements in a very straightforward manner
for (; it != root.children.end(); ++it) {
const char *c = (*it).tokens[1].c_str();
const char *end = c + (*it).tokens[1].size();
// 'FirstFrame': begin of animation slice
if ((*it).tokens[0] == "FirstFrame") {
@ -567,14 +568,14 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
LWS::NodeDesc d;
d.type = LWS::NodeDesc::OBJECT;
if (version >= 4) { // handle LWSC 4 explicit ID
SkipSpaces(&c);
SkipSpaces(&c, end);
d.number = strtoul16(c, &c) & AI_LWS_MASK;
} else {
d.number = cur_object++;
}
// and add the file to the import list
SkipSpaces(&c);
SkipSpaces(&c, end);
std::string path = FindLWOFile(c);
d.path = path;
d.id = batch.AddLoadRequest(path, 0, &props);
@ -588,7 +589,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
SkipSpaces(&c);
SkipSpaces(&c, end);
} else {
d.number = cur_object++;
}
@ -604,7 +605,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
d.type = LWS::NodeDesc::OBJECT;
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
SkipSpaces(&c);
SkipSpaces(&c, end);
} else {
d.number = cur_object++;
}
@ -668,26 +669,25 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// two ints per envelope
LWO::Envelope &env = *envelopeIt;
env.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
SkipSpaces(&c, end);
env.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
SkipSpaces(&c, end);
}
}
}
// 'ParentItem': specifies the parent of the current element
else if ((*it).tokens[0] == "ParentItem") {
if (nodes.empty())
if (nodes.empty()) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentItem\'");
else
} else {
nodes.back().parent = strtoul16(c, &c);
}
}
// 'ParentObject': deprecated one for older formats
else if (version < 3 && (*it).tokens[0] == "ParentObject") {
if (nodes.empty())
if (nodes.empty()) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentObject\'");
else {
} else {
nodes.back().parent = strtoul10(c, &c) | (1u << 28u);
}
}
@ -700,19 +700,20 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
} else
} else {
d.number = cur_camera++;
}
nodes.push_back(d);
num_camera++;
}
// 'CameraName': set name of currently active camera
else if ((*it).tokens[0] == "CameraName") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'CameraName\'");
else
} else {
nodes.back().name = c;
}
}
// 'AddLight': add a light to the scenegraph
else if ((*it).tokens[0] == "AddLight") {
@ -723,19 +724,20 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
} else
} else {
d.number = cur_light++;
}
nodes.push_back(d);
num_light++;
}
// 'LightName': set name of currently active light
else if ((*it).tokens[0] == "LightName") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightName\'");
else
} else {
nodes.back().name = c;
}
}
// 'LightIntensity': set intensity of currently active light
else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity") {
@ -753,62 +755,58 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
// 'LightType': set type of currently active light
else if ((*it).tokens[0] == "LightType") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightType\'");
else
} else {
nodes.back().lightType = strtoul10(c);
}
}
// 'LightFalloffType': set falloff type of currently active light
else if ((*it).tokens[0] == "LightFalloffType") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightFalloffType\'");
else
} else {
nodes.back().lightFalloffType = strtoul10(c);
}
}
// 'LightConeAngle': set cone angle of currently active light
else if ((*it).tokens[0] == "LightConeAngle") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightConeAngle\'");
else
} else {
nodes.back().lightConeAngle = fast_atof(c);
}
}
// 'LightEdgeAngle': set area where we're smoothing from min to max intensity
else if ((*it).tokens[0] == "LightEdgeAngle") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightEdgeAngle\'");
else
} else {
nodes.back().lightEdgeAngle = fast_atof(c);
}
}
// 'LightColor': set color of currently active light
else if ((*it).tokens[0] == "LightColor") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
else {
} else {
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.r);
SkipSpaces(&c);
SkipSpaces(&c, end);
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.g);
SkipSpaces(&c);
SkipSpaces(&c, end);
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.b);
}
}
// 'PivotPosition': position of local transformation origin
else if ((*it).tokens[0] == "PivotPosition" || (*it).tokens[0] == "PivotPoint") {
if (nodes.empty())
if (nodes.empty()) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
else {
} else {
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.x);
SkipSpaces(&c);
SkipSpaces(&c, end);
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.y);
SkipSpaces(&c);
SkipSpaces(&c, end);
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.z);
// Mark pivotPos as set
nodes.back().isPivotSet = true;
@ -818,7 +816,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// resolve parenting
for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
// check whether there is another node which calls us a parent
for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
if (dit != ndIt && *ndIt == (*dit).parent) {
@ -854,7 +851,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
aiNode *nd = master->mRootNode = new aiNode();
// allocate storage for cameras&lights
if (num_camera) {
if (num_camera > 0u) {
master->mCameras = new aiCamera *[master->mNumCameras = num_camera];
}
aiCamera **cams = master->mCameras;

View File

@ -76,7 +76,7 @@ public:
std::list<Element> children;
//! Recursive parsing function
void Parse(const char *&buffer);
void Parse(const char *&buffer, const char *end);
};
#define AI_LWS_MASK (0xffffffff >> 4u)

View File

@ -123,12 +123,12 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
// remove comments from it (C++ style)
CommentRemover::RemoveLineComments("//", &_buff[0]);
const char *buff = &_buff[0];
const char *end = buff + _buff.size();
Q3Shader::ShaderDataBlock *curData = nullptr;
Q3Shader::ShaderMapBlock *curMap = nullptr;
// read line per line
for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
if (*buff == '{') {
++buff;
@ -140,21 +140,21 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
}
// read this data section
for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
if (*buff == '{') {
++buff;
// add new map section
curData->maps.emplace_back();
curMap = &curData->maps.back();
for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
// 'map' - Specifies texture file name
if (TokenMatchI(buff, "map", 3) || TokenMatchI(buff, "clampmap", 8)) {
curMap->name = GetNextToken(buff);
curMap->name = GetNextToken(buff, end);
}
// 'blendfunc' - Alpha blending mode
else if (TokenMatchI(buff, "blendfunc", 9)) {
const std::string blend_src = GetNextToken(buff);
const std::string blend_src = GetNextToken(buff, end);
if (blend_src == "add") {
curMap->blend_src = Q3Shader::BLEND_GL_ONE;
curMap->blend_dest = Q3Shader::BLEND_GL_ONE;
@ -166,12 +166,12 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
curMap->blend_dest = Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
} else {
curMap->blend_src = StringToBlendFunc(blend_src);
curMap->blend_dest = StringToBlendFunc(GetNextToken(buff));
curMap->blend_dest = StringToBlendFunc(GetNextToken(buff, end));
}
}
// 'alphafunc' - Alpha testing mode
else if (TokenMatchI(buff, "alphafunc", 9)) {
const std::string at = GetNextToken(buff);
const std::string at = GetNextToken(buff, end);
if (at == "GT0") {
curMap->alpha_test = Q3Shader::AT_GT0;
} else if (at == "LT128") {
@ -186,7 +186,6 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
break;
}
}
} else if (*buff == '}') {
++buff;
curData = nullptr;
@ -195,7 +194,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
// 'cull' specifies culling behaviour for the model
else if (TokenMatchI(buff, "cull", 4)) {
SkipSpaces(&buff);
SkipSpaces(&buff, end);
if (!ASSIMP_strincmp(buff, "back", 4)) { // render face's backside, does not function in Q3 engine (bug)
curData->cull = Q3Shader::CULL_CCW;
} else if (!ASSIMP_strincmp(buff, "front", 5)) { // is not valid keyword in Q3, but occurs in shaders
@ -213,9 +212,10 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
curData = &fill.blocks.back();
// get the name of this section
curData->name = GetNextToken(buff);
curData->name = GetNextToken(buff, end);
}
}
return true;
}
@ -232,6 +232,7 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
const size_t s = file->FileSize();
std::vector<char> _buff(s + 1);
const char *buff = &_buff[0];
const char *end = buff + _buff.size();
file->Read(&_buff[0], s, 1);
_buff[s] = 0;
@ -240,10 +241,10 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
// read token by token and fill output table
for (; *buff;) {
SkipSpacesAndLineEnd(&buff);
SkipSpacesAndLineEnd(&buff, end);
// get first identifier
std::string ss = GetNextToken(buff);
std::string ss = GetNextToken(buff, end);
// ignore tokens starting with tag_
if (!::strncmp(&ss[0], "tag_", std::min((size_t)4, ss.length())))
@ -253,8 +254,9 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
SkinData::TextureEntry &entry = fill.textures.back();
entry.first = ss;
entry.second = GetNextToken(buff);
entry.second = GetNextToken(buff, end);
}
return true;
}
@ -293,7 +295,7 @@ void Q3Shader::ConvertShaderToMaterial(aiMaterial *out, const ShaderDataBlock &s
// - in any case: set it as diffuse texture
//
// If the texture is using 'filter' blending
// - take as lightmap
// - take as light-map
//
// Textures with alpha funcs
// - aiTextureFlags_UseAlpha is set (otherwise aiTextureFlags_NoAlpha is explicitly set)

View File

@ -210,7 +210,7 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
const unsigned int guess = (unsigned int)(fWeightsPerVert * iNewNum);
meshSrc.mWeights.reserve(guess + (guess >> 3)); // + 12.5% as buffer
for (FaceList::const_iterator iter = meshSrc.mFaces.begin(), iterEnd = meshSrc.mFaces.end(); iter != iterEnd; ++iter) {
for (FaceArray::const_iterator iter = meshSrc.mFaces.begin(), iterEnd = meshSrc.mFaces.end(); iter != iterEnd; ++iter) {
const aiFace &face = *iter;
for (unsigned int i = 0; i < 3; ++i) {
if (face.mIndices[0] >= meshSrc.mVertices.size()) {
@ -231,7 +231,7 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5MESH
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneArray &bones) {
ai_assert(nullptr != piParent);
ai_assert(!piParent->mNumChildren);
@ -282,7 +282,7 @@ void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &b
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5ANIM
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneArray &bones, const aiNodeAnim **node_anims) {
ai_assert(nullptr != piParent);
ai_assert(!piParent->mNumChildren);
@ -402,7 +402,7 @@ void MD5Importer::LoadMD5MeshFile() {
// copy texture coordinates
aiVector3D *pv = mesh->mTextureCoords[0];
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
pv->x = (*iter).mUV.x;
pv->y = 1.0f - (*iter).mUV.y; // D3D to OpenGL
pv->z = 0.0f;
@ -412,7 +412,7 @@ void MD5Importer::LoadMD5MeshFile() {
unsigned int *piCount = new unsigned int[meshParser.mJoints.size()];
::memset(piCount, 0, sizeof(unsigned int) * meshParser.mJoints.size());
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
/* FIX for some invalid exporters */
@ -447,7 +447,7 @@ void MD5Importer::LoadMD5MeshFile() {
}
pv = mesh->mVertices;
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
// compute the final vertex position from all single weights
*pv = aiVector3D();
@ -585,14 +585,14 @@ void MD5Importer::LoadMD5AnimFile() {
// 1 tick == 1 frame
anim->mTicksPerSecond = animParser.fFrameRate;
for (FrameList::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end(); iter != iterEnd; ++iter) {
for (FrameArray::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end(); iter != iterEnd; ++iter) {
double dTime = (double)(*iter).iIndex;
aiNodeAnim **pcAnimNode = anim->mChannels;
if (!(*iter).mValues.empty() || iter == animParser.mFrames.begin()) /* be sure we have at least one frame */
{
// now process all values in there ... read all joints
MD5::BaseFrameDesc *pcBaseFrame = &animParser.mBaseFrames[0];
for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
for (AnimBoneArray::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
++pcAnimNode, ++pcBaseFrame) {
if ((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -118,7 +118,7 @@ protected:
* @param node_anims Generated node animations
*/
void AttachChilds_Anim(int iParentID, aiNode *piParent,
AnimBoneList &bones, const aiNodeAnim **node_anims);
AnimBoneArray &bones, const aiNodeAnim **node_anims);
// -------------------------------------------------------------------
/** Construct node hierarchy from a given MD5MESH
@ -126,7 +126,7 @@ protected:
* @param piParent Parent node to attach to
* @param bones Input bones
*/
void AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones);
void AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneArray &bones);
// -------------------------------------------------------------------
/** Build unique vertex buffers from a given MD5ANIM

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2023, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -138,14 +138,16 @@ bool MD5Parser::ParseSection(Section &out) {
char *sz = buffer;
while (!IsSpaceOrNewLine(*buffer)) {
++buffer;
if (buffer == bufferEnd)
if (buffer == bufferEnd) {
return false;
}
}
out.mName = std::string(sz, (uintptr_t)(buffer - sz));
while (IsSpace(*buffer)) {
++buffer;
if (buffer == bufferEnd)
if (buffer == bufferEnd) {
return false;
}
}
bool running = true;
@ -153,14 +155,16 @@ bool MD5Parser::ParseSection(Section &out) {
if ('{' == *buffer) {
// it is a normal section so read all lines
++buffer;
if (buffer == bufferEnd)
if (buffer == bufferEnd) {
return false;
}
bool run = true;
while (run) {
while (IsSpaceOrNewLine(*buffer)) {
++buffer;
if (buffer == bufferEnd)
if (buffer == bufferEnd) {
return false;
}
}
if ('\0' == *buffer) {
return false; // seems this was the last section
@ -175,18 +179,21 @@ bool MD5Parser::ParseSection(Section &out) {
elem.iLineNumber = lineNumber;
elem.szStart = buffer;
elem.end = bufferEnd;
// terminate the line with zero
while (!IsLineEnd(*buffer)) {
++buffer;
if (buffer == bufferEnd)
if (buffer == bufferEnd) {
return false;
}
}
if (*buffer) {
++lineNumber;
*buffer++ = '\0';
if (buffer == bufferEnd)
if (buffer == bufferEnd) {
return false;
}
}
}
break;
@ -194,89 +201,107 @@ bool MD5Parser::ParseSection(Section &out) {
// it is an element at global scope. Parse its value and go on
sz = buffer;
while (!IsSpaceOrNewLine(*buffer++)) {
if (buffer == bufferEnd)
if (buffer == bufferEnd) {
return false;
}
}
out.mGlobalValue = std::string(sz, (uintptr_t)(buffer - sz));
continue;
}
break;
}
if (buffer == bufferEnd)
if (buffer == bufferEnd) {
return false;
}
while (IsSpaceOrNewLine(*buffer)) {
if (buffer == bufferEnd) {
break;
}
++buffer;
if (buffer == bufferEnd)
return false;
}
return '\0' != *buffer;
}
// ------------------------------------------------------------------------------------------------
// Some dirty macros just because they're so funny and easy to debug
// skip all spaces ... handle EOL correctly
#define AI_MD5_SKIP_SPACES() \
if (!SkipSpaces(&sz)) \
MD5Parser::ReportWarning("Unexpected end of line", elem.iLineNumber);
inline void AI_MD5_SKIP_SPACES(const char **sz, const char *bufferEnd, int linenumber) {
if (!SkipSpaces(sz, bufferEnd)) {
MD5Parser::ReportWarning("Unexpected end of line", linenumber);
}
}
// read a triple float in brackets: (1.0 1.0 1.0)
#define AI_MD5_READ_TRIPLE(vec) \
AI_MD5_SKIP_SPACES(); \
if ('(' != *sz++) \
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber); \
AI_MD5_SKIP_SPACES(); \
sz = fast_atoreal_move<float>(sz, (float &)vec.x); \
AI_MD5_SKIP_SPACES(); \
sz = fast_atoreal_move<float>(sz, (float &)vec.y); \
AI_MD5_SKIP_SPACES(); \
sz = fast_atoreal_move<float>(sz, (float &)vec.z); \
AI_MD5_SKIP_SPACES(); \
if (')' != *sz++) \
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
inline void AI_MD5_READ_TRIPLE(aiVector3D &vec, const char **sz, const char *bufferEnd, int linenumber) {
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
if ('(' != **sz) {
MD5Parser::ReportWarning("Unexpected token: ( was expected", linenumber);
++*sz;
}
++*sz;
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
*sz = fast_atoreal_move<float>(*sz, (float &)vec.x);
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
*sz = fast_atoreal_move<float>(*sz, (float &)vec.y);
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
*sz = fast_atoreal_move<float>(*sz, (float &)vec.z);
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
if (')' != **sz) {
MD5Parser::ReportWarning("Unexpected token: ) was expected", linenumber);
}
++*sz;
}
// parse a string, enclosed in quotation marks or not
#define AI_MD5_PARSE_STRING(out) \
bool bQuota = (*sz == '\"'); \
const char *szStart = sz; \
while (!IsSpaceOrNewLine(*sz)) \
++sz; \
const char *szEnd = sz; \
if (bQuota) { \
szStart++; \
if ('\"' != *(szEnd -= 1)) { \
MD5Parser::ReportWarning("Expected closing quotation marks in string", \
elem.iLineNumber); \
continue; \
} \
} \
out.length = (size_t)(szEnd - szStart); \
::memcpy(out.data, szStart, out.length); \
inline bool AI_MD5_PARSE_STRING(const char **sz, const char *bufferEnd, aiString &out, int linenumber) {
bool bQuota = (**sz == '\"');
const char *szStart = *sz;
while (!IsSpaceOrNewLine(**sz)) {
++*sz;
if (*sz == bufferEnd) break;
}
const char *szEnd = *sz;
if (bQuota) {
szStart++;
if ('\"' != *(szEnd -= 1)) {
MD5Parser::ReportWarning("Expected closing quotation marks in string", linenumber);
++*sz;
}
}
out.length = (ai_uint32)(szEnd - szStart);
::memcpy(out.data, szStart, out.length);
out.data[out.length] = '\0';
return true;
}
// parse a string, enclosed in quotation marks
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
out.length = 0; \
while ('\"' != *sz && '\0' != *sz) \
++sz; \
if ('\0' != *sz) { \
const char *szStart = ++sz; \
while ('\"' != *sz && '\0' != *sz) \
++sz; \
if ('\0' != *sz) { \
const char *szEnd = (sz++); \
out.length = (ai_uint32)(szEnd - szStart); \
::memcpy(out.data, szStart, out.length); \
} \
} \
inline void AI_MD5_PARSE_STRING_IN_QUOTATION(const char **sz, const char *bufferEnd, aiString &out) {
out.length = 0u;
while (('\"' != **sz && '\0' != **sz) && *sz != bufferEnd) {
++*sz;
}
if ('\0' != **sz) {
const char *szStart = ++(*sz);
while (('\"' != **sz && '\0' != **sz) && *sz != bufferEnd) {
++*sz;
}
if ('\0' != **sz) {
const char *szEnd = *sz;
++*sz;
out.length = (ai_uint32)(szEnd - szStart);
::memcpy(out.data, szStart, out.length);
}
}
out.data[out.length] = '\0';
}
// ------------------------------------------------------------------------------------------------
// .MD5MESH parsing function
MD5MeshParser::MD5MeshParser(SectionList &mSections) {
MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
ASSIMP_LOG_DEBUG("MD5MeshParser begin");
// now parse all sections
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "numMeshes") {
mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
} else if ((*iter).mName == "numJoints") {
@ -288,14 +313,15 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
BoneDesc &desc = mJoints.back();
const char *sz = elem.szStart;
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
AI_MD5_SKIP_SPACES();
AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mName);
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
// negative values, at least -1, is allowed here
desc.mParentIndex = (int)strtol10(sz, &sz);
AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
AI_MD5_READ_TRIPLE(desc.mPositionXYZ, &sz, elem.end, elem.iLineNumber);
AI_MD5_READ_TRIPLE(desc.mRotationQuat, &sz, elem.end, elem.iLineNumber); // normalized quaternion, so w is not there
}
} else if ((*iter).mName == "mesh") {
mMeshes.emplace_back();
@ -306,52 +332,52 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
// shader attribute
if (TokenMatch(sz, "shader", 6)) {
AI_MD5_SKIP_SPACES();
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader);
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mShader);
}
// numverts attribute
else if (TokenMatch(sz, "numverts", 8)) {
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
desc.mVertices.resize(strtoul10(sz));
}
// numtris attribute
else if (TokenMatch(sz, "numtris", 7)) {
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
desc.mFaces.resize(strtoul10(sz));
}
// numweights attribute
else if (TokenMatch(sz, "numweights", 10)) {
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
desc.mWeights.resize(strtoul10(sz));
}
// vert attribute
// "vert 0 ( 0.394531 0.513672 ) 0 1"
else if (TokenMatch(sz, "vert", 4)) {
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
const unsigned int idx = ::strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (idx >= desc.mVertices.size())
desc.mVertices.resize(idx + 1);
VertexDesc &vert = desc.mVertices[idx];
if ('(' != *sz++)
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber);
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.x);
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.y);
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (')' != *sz++)
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
vert.mFirstWeight = ::strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
vert.mNumWeights = ::strtoul10(sz, &sz);
}
// tri attribute
// "tri 0 15 13 12"
else if (TokenMatch(sz, "tri", 3)) {
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
const unsigned int idx = strtoul10(sz, &sz);
if (idx >= desc.mFaces.size())
desc.mFaces.resize(idx + 1);
@ -359,24 +385,24 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
aiFace &face = desc.mFaces[idx];
face.mIndices = new unsigned int[face.mNumIndices = 3];
for (unsigned int i = 0; i < 3; ++i) {
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
face.mIndices[i] = strtoul10(sz, &sz);
}
}
// weight attribute
// "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
else if (TokenMatch(sz, "weight", 6)) {
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
const unsigned int idx = strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (idx >= desc.mWeights.size())
desc.mWeights.resize(idx + 1);
WeightDesc &weight = desc.mWeights[idx];
weight.mBone = strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move<float>(sz, weight.mWeight);
AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
AI_MD5_READ_TRIPLE(weight.vOffsetPosition, &sz, elem.end, elem.iLineNumber);
}
}
}
@ -386,12 +412,12 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
// ------------------------------------------------------------------------------------------------
// .MD5ANIM parsing function
MD5AnimParser::MD5AnimParser(SectionList &mSections) {
MD5AnimParser::MD5AnimParser(SectionArray &mSections) {
ASSIMP_LOG_DEBUG("MD5AnimParser begin");
fFrameRate = 24.0f;
mNumAnimatedComponents = UINT_MAX;
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "hierarchy") {
// "sheath" 0 63 6
for (const auto &elem : (*iter).mElements) {
@ -399,18 +425,18 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
AnimBoneDesc &desc = mAnimatedBones.back();
const char *sz = elem.szStart;
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
AI_MD5_SKIP_SPACES();
AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mName);
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
// parent index - negative values are allowed (at least -1)
desc.mParentIndex = ::strtol10(sz, &sz);
// flags (highest is 2^6-1)
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (63 < (desc.iFlags = ::strtoul10(sz, &sz))) {
MD5Parser::ReportWarning("Invalid flag combination in hierarchy section", elem.iLineNumber);
}
AI_MD5_SKIP_SPACES();
AI_MD5_SKIP_SPACES(& sz, elem.end, elem.iLineNumber);
// index of the first animation keyframe component for this joint
desc.iFirstKeyIndex = ::strtoul10(sz, &sz);
@ -423,8 +449,8 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
mBaseFrames.emplace_back();
BaseFrameDesc &desc = mBaseFrames.back();
AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
AI_MD5_READ_TRIPLE(desc.vRotationQuat);
AI_MD5_READ_TRIPLE(desc.vPositionXYZ, &sz, elem.end, elem.iLineNumber);
AI_MD5_READ_TRIPLE(desc.vRotationQuat, &sz, elem.end, elem.iLineNumber);
}
} else if ((*iter).mName == "frame") {
if (!(*iter).mGlobalValue.length()) {
@ -444,7 +470,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
// now read all elements (continuous list of floats)
for (const auto &elem : (*iter).mElements) {
const char *sz = elem.szStart;
while (SkipSpacesAndLineEnd(&sz)) {
while (SkipSpacesAndLineEnd(&sz, elem.end)) {
float f;
sz = fast_atoreal_move<float>(sz, f);
desc.mValues.push_back(f);
@ -471,11 +497,11 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
// ------------------------------------------------------------------------------------------------
// .MD5CAMERA parsing function
MD5CameraParser::MD5CameraParser(SectionList &mSections) {
MD5CameraParser::MD5CameraParser(SectionArray &mSections) {
ASSIMP_LOG_DEBUG("MD5CameraParser begin");
fFrameRate = 24.0f;
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "numFrames") {
frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
} else if ((*iter).mName == "frameRate") {
@ -492,9 +518,9 @@ MD5CameraParser::MD5CameraParser(SectionList &mSections) {
frames.emplace_back();
CameraAnimFrameDesc &cur = frames.back();
AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
AI_MD5_READ_TRIPLE(cur.vRotationQuat);
AI_MD5_SKIP_SPACES();
AI_MD5_READ_TRIPLE(cur.vPositionXYZ, &sz, elem.end, elem.iLineNumber);
AI_MD5_READ_TRIPLE(cur.vRotationQuat, &sz, elem.end, elem.iLineNumber);
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
cur.fFOV = fast_atof(sz);
}
}

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2023, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -68,12 +68,14 @@ struct Element {
//! Elements are terminated with \0
char* szStart;
const char *end;
//! Original line number (can be used in error messages
//! if a parsing error occurs)
unsigned int iLineNumber;
};
using ElementList = std::vector<Element>;
using ElementArray = std::vector<Element>;
// ---------------------------------------------------------------------------
/** Represents a section of a MD5 file (such as the mesh or the joints section)
@ -86,7 +88,7 @@ struct Section {
unsigned int iLineNumber;
//! List of all elements which have been parsed in this section.
ElementList mElements;
ElementArray mElements;
//! Name of the section
std::string mName;
@ -96,7 +98,7 @@ struct Section {
std::string mGlobalValue;
};
using SectionList = std::vector<Section>;
using SectionArray = std::vector<Section>;
// ---------------------------------------------------------------------------
/** Basic information about a joint
@ -132,7 +134,7 @@ struct BoneDesc : BaseJointDescription {
unsigned int mMap;
};
using BoneList = std::vector<BoneDesc>;
using BoneArray = std::vector<BoneDesc>;
// ---------------------------------------------------------------------------
/** Represents a bone (joint) descriptor in a MD5Anim file
@ -145,7 +147,7 @@ struct AnimBoneDesc : BaseJointDescription {
unsigned int iFirstKeyIndex;
};
using AnimBoneList = std::vector< AnimBoneDesc >;
using AnimBoneArray = std::vector< AnimBoneDesc >;
// ---------------------------------------------------------------------------
/** Represents a base frame descriptor in a MD5Anim file
@ -155,7 +157,7 @@ struct BaseFrameDesc {
aiVector3D vRotationQuat;
};
using BaseFrameList = std::vector<BaseFrameDesc>;
using BaseFrameArray = std::vector<BaseFrameDesc>;
// ---------------------------------------------------------------------------
/** Represents a camera animation frame in a MDCamera file
@ -164,7 +166,7 @@ struct CameraAnimFrameDesc : BaseFrameDesc {
float fFOV;
};
using CameraFrameList = std::vector<CameraAnimFrameDesc>;
using CameraFrameArray = std::vector<CameraAnimFrameDesc>;
// ---------------------------------------------------------------------------
/** Represents a frame descriptor in a MD5Anim file
@ -177,7 +179,7 @@ struct FrameDesc {
std::vector< float > mValues;
};
using FrameList = std::vector<FrameDesc>;
using FrameArray = std::vector<FrameDesc>;
// ---------------------------------------------------------------------------
/** Represents a vertex descriptor in a MD5 file
@ -199,7 +201,7 @@ struct VertexDesc {
unsigned int mNumWeights;
};
using VertexList = std::vector<VertexDesc>;
using VertexArray = std::vector<VertexDesc>;
// ---------------------------------------------------------------------------
/** Represents a vertex weight descriptor in a MD5 file
@ -216,27 +218,27 @@ struct WeightDesc {
aiVector3D vOffsetPosition;
};
using WeightList = std::vector<WeightDesc>;
using FaceList = std::vector<aiFace>;
using WeightArray = std::vector<WeightDesc>;
using FaceArray = std::vector<aiFace>;
// ---------------------------------------------------------------------------
/** Represents a mesh in a MD5 file
*/
struct MeshDesc {
//! Weights of the mesh
WeightList mWeights;
WeightArray mWeights;
//! Vertices of the mesh
VertexList mVertices;
VertexArray mVertices;
//! Faces of the mesh
FaceList mFaces;
FaceArray mFaces;
//! Name of the shader (=texture) to be assigned to the mesh
aiString mShader;
};
using MeshList = std::vector<MeshDesc>;
using MeshArray = std::vector<MeshDesc>;
// ---------------------------------------------------------------------------
// Convert a quaternion to its usual representation
@ -269,13 +271,13 @@ public:
*
* @param mSections List of file sections (output of MD5Parser)
*/
explicit MD5MeshParser(SectionList& mSections);
explicit MD5MeshParser(SectionArray& mSections);
//! List of all meshes
MeshList mMeshes;
MeshArray mMeshes;
//! List of all joints
BoneList mJoints;
BoneArray mJoints;
};
// remove this flag if you need to the bounding box data
@ -292,20 +294,20 @@ public:
*
* @param mSections List of file sections (output of MD5Parser)
*/
explicit MD5AnimParser(SectionList& mSections);
explicit MD5AnimParser(SectionArray& mSections);
//! Output frame rate
float fFrameRate;
//! List of animation bones
AnimBoneList mAnimatedBones;
AnimBoneArray mAnimatedBones;
//! List of base frames
BaseFrameList mBaseFrames;
BaseFrameArray mBaseFrames;
//! List of animation frames
FrameList mFrames;
FrameArray mFrames;
//! Number of animated components
unsigned int mNumAnimatedComponents;
@ -322,7 +324,7 @@ public:
*
* @param mSections List of file sections (output of MD5Parser)
*/
explicit MD5CameraParser(SectionList& mSections);
explicit MD5CameraParser(SectionArray& mSections);
//! Output frame rate
float fFrameRate;
@ -331,7 +333,7 @@ public:
std::vector<unsigned int> cuts;
//! Frames
CameraFrameList frames;
CameraFrameArray frames;
};
// ---------------------------------------------------------------------------
@ -375,7 +377,7 @@ public:
void ReportWarning (const char* warn);
//! List of all sections which have been read
SectionList mSections;
SectionArray mSections;
private:
bool ParseSection(Section& out);
@ -388,7 +390,7 @@ private:
private:
char* buffer;
char* bufferEnd;
const char* bufferEnd;
unsigned int fileSize;
unsigned int lineNumber;
};
@ -406,7 +408,7 @@ inline void MD5Parser::ReportError(const char* error) {
// -------------------------------------------------------------------
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
++lineNumber;
return Assimp::SkipLine(in ,out);
return Assimp::SkipLine(in, out, bufferEnd);
}
// -------------------------------------------------------------------
@ -450,7 +452,7 @@ inline bool MD5Parser::SkipSpacesAndLineEnd() {
// -------------------------------------------------------------------
inline bool MD5Parser::SkipSpaces() {
return Assimp::SkipSpaces((const char**)&buffer);
return Assimp::SkipSpaces((const char**)&buffer, bufferEnd);
}
} // namespace Assimp

View File

@ -123,9 +123,8 @@ aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture *pcTexture) {
// Read a texture from a MDL3 file
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char *szData) {
const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
pcHeader->skinheight);
const size_t len = pcHeader->skinwidth * pcHeader->skinheight;
VALIDATE_FILE_SIZE(szData + len);
// allocate a new texture object
aiTexture *pcNew = new aiTexture();

View File

@ -85,7 +85,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_FLOAT(f) \
SkipSpaces(&sz); \
SkipSpaces(&sz, lineEnd); \
if (!IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
// ------------------------------------------------------------------------------------------------
@ -111,7 +111,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
ASSIMP_LOG_WARN("NFF2: Unexpected EOF, can't read next token"); \
break; \
} \
SkipSpaces(line, &sz); \
SkipSpaces(line, &sz, lineEnd); \
} while (IsLineEnd(*sz))
// ------------------------------------------------------------------------------------------------
@ -148,9 +148,9 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo> &output,
// No read the file line per line
char line[4096];
const char *sz;
const char *sz, *lineEnd = &line[2095]+1;
while (GetNextLine(buffer, line)) {
SkipSpaces(line, &sz);
SkipSpaces(line, &sz, lineEnd);
// 'version' defines the version of the file format
if (TokenMatch(sz, "version", 7)) {
@ -198,18 +198,16 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo> &output,
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void NFFImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if (!file)
throw DeadlyImportError("Failed to open NFF file ", pFile, ".");
void NFFImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> stream(pIOHandler->Open(file, "rb"));
if (!stream) {
throw DeadlyImportError("Failed to open NFF file ", file, ".");
}
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(), mBuffer2);
TextFileToBuffer(stream.get(), mBuffer2);
const char *buffer = &mBuffer2[0];
// mesh arrays - separate here to make the handling of the pointers below easier.
@ -219,8 +217,10 @@ void NFFImporter::InternReadFile(const std::string &pFile,
std::vector<MeshInfo> meshesLocked;
char line[4096];
const char *lineEnd = &line[4096];
const char *sz;
// camera parameters
aiVector3D camPos, camUp(0.f, 1.f, 0.f), camLookAt(0.f, 0.f, 1.f);
ai_real angle = 45.f;
@ -265,7 +265,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
CommentRemover::RemoveLineComments("//", &mBuffer2[0]);
while (GetNextLine(buffer, line)) {
SkipSpaces(line, &sz);
SkipSpaces(line, &sz, lineEnd);
if (TokenMatch(sz, "version", 7)) {
ASSIMP_LOG_INFO("NFF (Sense8) file format: ", sz);
} else if (TokenMatch(sz, "viewpos", 7)) {
@ -295,7 +295,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// material table - an external file
if (TokenMatch(sz, "mtable", 6)) {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz3 = sz;
while (!IsSpaceOrNewLine(*sz))
++sz;
@ -316,12 +316,12 @@ void NFFImporter::InternReadFile(const std::string &pFile,
std::string::size_type sepPos;
if ((std::string::npos == (sepPos = path.find_last_of('\\')) || !sepPos) &&
(std::string::npos == (sepPos = path.find_last_of('/')) || !sepPos)) {
sepPos = pFile.find_last_of('\\');
sepPos = file.find_last_of('\\');
if (std::string::npos == sepPos) {
sepPos = pFile.find_last_of('/');
sepPos = file.find_last_of('/');
}
if (std::string::npos != sepPos) {
path = pFile.substr(0, sepPos + 1) + path;
path = file.substr(0, sepPos + 1) + path;
}
}
LoadNFF2MaterialTable(materialTable, path, pIOHandler);
@ -351,7 +351,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// parse all other attributes in the line
while (true) {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
if (IsLineEnd(*sz)) break;
// color definition
@ -403,23 +403,20 @@ void NFFImporter::InternReadFile(const std::string &pFile,
tempIdx.reserve(10);
for (unsigned int i = 0; i < num; ++i) {
AI_NFF2_GET_NEXT_TOKEN();
SkipSpaces(line, &sz);
SkipSpaces(line, &sz, lineEnd);
unsigned int numIdx = strtoul10(sz, &sz);
// read all faces indices
if (numIdx) {
// mesh.faces.push_back(numIdx);
// tempIdx.erase(tempIdx.begin(),tempIdx.end());
tempIdx.resize(numIdx);
for (unsigned int a = 0; a < numIdx; ++a) {
SkipSpaces(sz, &sz);
SkipSpaces(sz, &sz, lineEnd);
unsigned int m = strtoul10(sz, &sz);
if (m >= (unsigned int)tempPositions.size()) {
ASSIMP_LOG_ERROR("NFF2: Vertex index overflow");
m = 0;
}
// mesh.vertices.push_back (tempPositions[idx]);
tempIdx[a] = m;
}
}
@ -432,7 +429,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
shader.color = aiColor3D(1.f, 1.f, 1.f);
aiColor4D c = aiColor4D(1.f, 1.f, 1.f, 1.f);
while (true) {
SkipSpaces(sz, &sz);
SkipSpaces(sz, &sz, lineEnd);
if (IsLineEnd(*sz)) break;
// per-polygon colors
@ -510,7 +507,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// Material ID?
else if (!materialTable.empty() && TokenMatch(sz, "matid", 5)) {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
matIdx = strtoul10(sz, &sz);
if (matIdx >= materialTable.size()) {
ASSIMP_LOG_ERROR("NFF2: Material index overflow.");
@ -527,7 +524,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
shader.specular = mat.specular;
shader.shininess = mat.shininess;
} else
SkipToken(sz);
SkipToken(sz, lineEnd);
}
// search the list of all shaders we have for this object whether
@ -649,7 +646,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
sz = &line[1];
out = currentMesh;
}
SkipSpaces(sz, &sz);
SkipSpaces(sz, &sz, lineEnd);
unsigned int m = strtoul10(sz);
// ---- flip the face order
@ -677,13 +674,13 @@ void NFFImporter::InternReadFile(const std::string &pFile,
}
if (out == currentMeshWithUVCoords) {
// FIX: in one test file this wraps over multiple lines
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
if (IsLineEnd(*sz)) {
GetNextLine(buffer, line);
sz = line;
}
AI_NFF_PARSE_FLOAT(v.x);
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
if (IsLineEnd(*sz)) {
GetNextLine(buffer, line);
sz = line;
@ -717,7 +714,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// if the next one is NOT a number we assume it is a texture file name
// this feature is used by some NFF files on the internet and it has
// been implemented as it can be really useful
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
if (!IsNumeric(*sz)) {
// TODO: Support full file names with spaces and quotation marks ...
const char *p = sz;
@ -731,10 +728,8 @@ void NFFImporter::InternReadFile(const std::string &pFile,
} else {
AI_NFF_PARSE_FLOAT(s.ambient); // optional
}
}
// 'shader' - other way to specify a texture
else if (TokenMatch(sz, "shader", 6)) {
SkipSpaces(&sz);
} else if (TokenMatch(sz, "shader", 6)) { // 'shader' - other way to specify a texture
SkipSpaces(&sz, lineEnd);
const char *old = sz;
while (!IsSpaceOrNewLine(*sz))
++sz;
@ -889,7 +884,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
}
// 'tess' - tessellation
else if (TokenMatch(sz, "tess", 4)) {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
iTesselation = strtoul10(sz);
}
// 'from' - camera position
@ -929,7 +924,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// '' - comment
else if ('#' == line[0]) {
const char *space;
SkipSpaces(&line[1], &space);
SkipSpaces(&line[1], &space, lineEnd);
if (!IsLineEnd(*space)) {
ASSIMP_LOG_INFO(space);
}

View File

@ -84,10 +84,10 @@ const aiImporterDesc *OFFImporter::GetInfo() const {
// skip blank space, lines and comments
static void NextToken(const char **car, const char *end) {
SkipSpacesAndLineEnd(car);
SkipSpacesAndLineEnd(car, end);
while (*car < end && (**car == '#' || **car == '\n' || **car == '\r')) {
SkipLine(car);
SkipSpacesAndLineEnd(car);
SkipLine(car, end);
SkipSpacesAndLineEnd(car, end);
}
}
@ -195,6 +195,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
char line[4096];
buffer = car;
const char *sz = car;
const char *lineEnd = &line[4096];
// now read all vertex lines
for (unsigned int i = 0; i < numVertices; ++i) {
@ -210,13 +211,13 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// stop at dimensions: this allows loading 1D or 2D coordinate vertices
for (unsigned int dim = 0; dim < dimensions; ++dim) {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move<ai_real>(sz, *vec[dim]);
}
// if has homogeneous coordinate, divide others by this one
if (hasHomogenous) {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
ai_real w = 1.;
sz = fast_atoreal_move<ai_real>(sz, w);
for (unsigned int dim = 0; dim < dimensions; ++dim) {
@ -227,11 +228,11 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// read optional normals
if (hasNormals) {
aiVector3D &n = mesh->mNormals[i];
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.x);
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.y);
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
fast_atoreal_move<ai_real>(sz, (ai_real &)n.z);
}
@ -241,22 +242,22 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// in theory should be testing type !
if (hasColors) {
aiColor4D &c = mesh->mColors[0][i];
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.r);
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.g);
} else {
c.g = 0.;
}
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.b);
} else {
c.b = 0.;
}
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.a);
} else {
c.a = 1.;
@ -264,9 +265,9 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
if (hasTexCoord) {
aiVector3D &t = mesh->mTextureCoords[0][i];
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)t.x);
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
fast_atoreal_move<ai_real>(sz, (ai_real &)t.y);
}
}
@ -280,7 +281,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
unsigned int idx;
sz = line;
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
idx = strtoul10(sz, &sz);
if (!idx || idx > 9) {
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
@ -291,7 +292,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
faces->mNumIndices = idx;
faces->mIndices = new unsigned int[faces->mNumIndices];
for (unsigned int m = 0; m < faces->mNumIndices; ++m) {
SkipSpaces(&sz);
SkipSpaces(&sz, lineEnd);
idx = strtoul10(sz, &sz);
if (idx >= numVertices) {
ASSIMP_LOG_ERROR("OFF: Vertex index is out of range");

View File

@ -64,6 +64,7 @@ ObjFileParser::ObjFileParser() :
m_pModel(nullptr),
m_uiLine(0),
m_buffer(),
mEnd(&m_buffer[Buffersize]),
m_pIO(nullptr),
m_progress(nullptr),
m_originalObjFileName() {
@ -97,8 +98,6 @@ ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::stri
parseFile(streamBuffer);
}
ObjFileParser::~ObjFileParser() = default;
void ObjFileParser::setBuffer(std::vector<char> &buffer) {
m_DataIt = buffer.begin();
m_DataItEnd = buffer.end();
@ -121,6 +120,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
while (streamBuffer.getNextDataLine(buffer, '\\')) {
m_DataIt = buffer.begin();
m_DataItEnd = buffer.end();
mEnd = &buffer[buffer.size() - 1] + 1;
// Handle progress reporting
const size_t filePos(streamBuffer.getFilePos());
@ -130,7 +130,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
m_progress->UpdateFileRead(processed, progressTotal);
}
// handle cstype section end (http://paulbourke.net/dataformats/obj/)
// handle c-stype section end (http://paulbourke.net/dataformats/obj/)
if (insideCstype) {
switch (*m_DataIt) {
case 'e': {
@ -301,18 +301,19 @@ size_t ObjFileParser::getNumComponentsInDataDefinition() {
} else if (IsLineEnd(*tmp)) {
end_of_definition = true;
}
if (!SkipSpaces(&tmp)) {
if (!SkipSpaces(&tmp, mEnd)) {
break;
}
const bool isNum(IsNumeric(*tmp) || isNanOrInf(tmp));
SkipToken(tmp);
SkipToken(tmp, mEnd);
if (isNum) {
++numComponents;
}
if (!SkipSpaces(&tmp)) {
if (!SkipSpaces(&tmp, mEnd)) {
break;
}
}
return numComponents;
}
@ -487,8 +488,9 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
++iStep;
}
if (iPos == 1 && !vt && vn)
if (iPos == 1 && !vt && vn) {
iPos = 2; // skip texture coords for normals if there are no tex coords
}
if (iVal > 0) {
// Store parsed index
@ -577,8 +579,9 @@ void ObjFileParser::getMaterialDesc() {
// Get name
std::string strName(pStart, &(*m_DataIt));
strName = trim_whitespaces(strName);
if (strName.empty())
if (strName.empty()) {
skip = true;
}
// If the current mesh has the same material, we simply ignore that 'usemtl' command
// There is no need to create another object or even mesh here

View File

@ -41,6 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJ_FILEPARSER_H_INC
#define OBJ_FILEPARSER_H_INC
#include "ObjFileData.h"
#include <assimp/IOStreamBuffer.h>
#include <assimp/material.h>
#include <assimp/mesh.h>
@ -53,14 +55,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
namespace ObjFile {
struct Model;
struct Object;
struct Material;
struct Point3;
struct Point2;
} // namespace ObjFile
class ObjFileImporter;
class IOSystem;
class ProgressHandler;
@ -79,7 +73,7 @@ public:
/// @brief Constructor with data array.
ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem *io, ProgressHandler *progress, const std::string &originalObjFileName);
/// @brief Destructor
~ObjFileParser();
~ObjFileParser() = default;
/// @brief If you want to load in-core data.
void setBuffer(std::vector<char> &buffer);
/// @brief Model getter.
@ -149,6 +143,7 @@ private:
unsigned int m_uiLine;
//! Helper buffer
char m_buffer[Buffersize];
const char *mEnd;
/// Pointer to IO system instance.
IOSystem *m_pIO;
//! Pointer to progress handler

View File

@ -159,7 +159,8 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
mBuffer = (unsigned char *)&mBuffer2[0];
char *szMe = (char *)&this->mBuffer[0];
SkipSpacesAndLineEnd(szMe, (const char **)&szMe);
const char *end = &mBuffer2[0] + mBuffer2.size();
SkipSpacesAndLineEnd(szMe, (const char **)&szMe, end);
// determine the format of the file data and construct the aiMesh
PLY::DOM sPlyDom;
@ -167,7 +168,7 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (TokenMatch(szMe, "format", 6)) {
if (TokenMatch(szMe, "ascii", 5)) {
SkipLine(szMe, (const char **)&szMe);
SkipLine(szMe, (const char **)&szMe, end);
if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) {
if (mGeneratedMesh != nullptr) {
delete (mGeneratedMesh);

View File

@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#include <utility>
using namespace Assimp;
namespace Assimp {
// ------------------------------------------------------------------------------------------------
PLY::EDataType PLY::Property::ParseDataType(std::vector<char> &buffer) {
@ -296,7 +296,7 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
return true;
}
//parse the number of occurrences of this element
// parse the number of occurrences of this element
const char *pCur = (char *)&buffer[0];
pOut->NumOccur = strtoul10(pCur, &pCur);
@ -321,13 +321,13 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
return true;
}
// ------------------------------------------------------------------------------------------------
bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
ret = Assimp::SkipSpaces(pCur, &pCur);
ret = Assimp::SkipSpaces(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@ -339,10 +339,11 @@ bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) {
bool PLY::DOM::SkipLine(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
ret = Assimp::SkipLine(pCur, &pCur);
ret = Assimp::SkipLine(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@ -369,10 +370,11 @@ bool PLY::DOM::TokenMatch(std::vector<char> &buffer, const char *token, unsigned
bool PLY::DOM::SkipSpacesAndLineEnd(std::vector<char> &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur);
ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@ -426,7 +428,7 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char>
} else {
// ignore unknown header elements
if (!streamBuffer.getNextLine(buffer))
return false;
return false;
}
}
@ -446,7 +448,7 @@ bool PLY::DOM::ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std
std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
// parse all element instances
//construct vertices and faces
// construct vertices and faces
for (; i != alElements.end(); ++i, ++a) {
if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip) {
PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), nullptr, loader);
@ -528,7 +530,7 @@ bool PLY::DOM::ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM *p_pcOut, P
return false;
}
//get next line after header
// get next line after header
streamBuffer.getNextLine(buffer);
if (!p_pcOut->ParseElementInstanceLists(streamBuffer, buffer, loader)) {
ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstance() failure");
@ -558,23 +560,24 @@ bool PLY::ElementInstanceList::ParseInstanceList(
}
} else {
const char *pCur = (const char *)&buffer[0];
const char *end = pCur + buffer.size();
// be sure to have enough storage
for (unsigned int i = 0; i < pcElement->NumOccur; ++i) {
if (p_pcOut)
PLY::ElementInstance::ParseInstance(pCur, pcElement, &p_pcOut->alInstances[i]);
PLY::ElementInstance::ParseInstance(pCur, end, pcElement, &p_pcOut->alInstances[i]);
else {
ElementInstance elt;
PLY::ElementInstance::ParseInstance(pCur, pcElement, &elt);
PLY::ElementInstance::ParseInstance(pCur, end, pcElement, &elt);
// Create vertex or face
if (pcElement->eSemantic == EEST_Vertex) {
//call loader instance from here
// call loader instance from here
loader->LoadVertex(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_Face) {
//call loader instance from here
// call loader instance from here
loader->LoadFace(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_TriStrip) {
//call loader instance from here
// call loader instance from here
loader->LoadFace(pcElement, &elt, i);
}
}
@ -611,13 +614,13 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary(
// Create vertex or face
if (pcElement->eSemantic == EEST_Vertex) {
//call loader instance from here
// call loader instance from here
loader->LoadVertex(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_Face) {
//call loader instance from here
// call loader instance from here
loader->LoadFace(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_TriStrip) {
//call loader instance from here
// call loader instance from here
loader->LoadFace(pcElement, &elt, i);
}
}
@ -626,7 +629,7 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary(
}
// ------------------------------------------------------------------------------------------------
bool PLY::ElementInstance::ParseInstance(const char *&pCur,
bool PLY::ElementInstance::ParseInstance(const char *&pCur, const char *end,
const PLY::Element *pcElement,
PLY::ElementInstance *p_pcOut) {
ai_assert(nullptr != pcElement);
@ -638,7 +641,7 @@ bool PLY::ElementInstance::ParseInstance(const char *&pCur,
std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
for (; i != p_pcOut->alProperties.end(); ++i, ++a) {
if (!(PLY::PropertyInstance::ParseInstance(pCur, &(*a), &(*i)))) {
if (!(PLY::PropertyInstance::ParseInstance(pCur, end, &(*a), &(*i)))) {
ASSIMP_LOG_WARN("Unable to parse property instance. "
"Skipping this element instance");
@ -678,13 +681,13 @@ bool PLY::ElementInstance::ParseInstanceBinary(
}
// ------------------------------------------------------------------------------------------------
bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
const PLY::Property *prop, PLY::PropertyInstance *p_pcOut) {
bool PLY::PropertyInstance::ParseInstance(const char *&pCur, const char *end, const PLY::Property *prop,
PLY::PropertyInstance *p_pcOut) {
ai_assert(nullptr != prop);
ai_assert(nullptr != p_pcOut);
// skip spaces at the beginning
if (!SkipSpaces(&pCur)) {
if (!SkipSpaces(&pCur, end)) {
return false;
}
@ -699,7 +702,7 @@ bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
// parse all list elements
p_pcOut->avList.resize(iNum);
for (unsigned int i = 0; i < iNum; ++i) {
if (!SkipSpaces(&pCur))
if (!SkipSpaces(&pCur, end))
return false;
PLY::PropertyInstance::ParseValue(pCur, prop->eType, &p_pcOut->avList[i]);
@ -711,7 +714,7 @@ bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
PLY::PropertyInstance::ParseValue(pCur, prop->eType, &v);
p_pcOut->avList.push_back(v);
}
SkipSpacesAndLineEnd(&pCur);
SkipSpacesAndLineEnd(&pCur, end);
return true;
}
@ -774,7 +777,7 @@ bool PLY::PropertyInstance::ParseValue(const char *&pCur,
ai_assert(nullptr != pCur);
ai_assert(nullptr != out);
//calc element size
// calc element size
bool ret = true;
switch (eType) {
case EDT_UInt:
@ -824,7 +827,7 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
bool p_bBE) {
ai_assert(nullptr != out);
//calc element size
// calc element size
unsigned int lsize = 0;
switch (eType) {
case EDT_Char:
@ -852,11 +855,11 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
break;
}
//read the next file block if needed
// read the next file block if needed
if (bufferSize < lsize) {
std::vector<char> nbuffer;
if (streamBuffer.getNextBlock(nbuffer)) {
//concat buffer contents
// concat buffer contents
buffer = std::vector<char>(buffer.end() - bufferSize, buffer.end());
buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end());
nbuffer.clear();
@ -958,4 +961,6 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
return ret;
}
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER

View File

@ -324,7 +324,7 @@ public:
// -------------------------------------------------------------------
//! Parse a property instance
static bool ParseInstance(const char* &pCur,
static bool ParseInstance(const char* &pCur, const char *end,
const Property* prop, PropertyInstance* p_pcOut);
// -------------------------------------------------------------------
@ -364,7 +364,7 @@ public:
// -------------------------------------------------------------------
//! Parse an element instance
static bool ParseInstance(const char* &pCur,
static bool ParseInstance(const char *&pCur, const char *end,
const Element* pcElement, ElementInstance* p_pcOut);
// -------------------------------------------------------------------

View File

@ -395,7 +395,10 @@ void Q3BSPFileImporter::createTriangleTopology(const Q3BSP::Q3BSPModel *pModel,
m_pCurrentFace->mIndices = new unsigned int[3];
m_pCurrentFace->mIndices[idx] = vertIdx;
}
}
} else {
m_pCurrentFace->mIndices[idx] = vertIdx;
}
pMesh->mVertices[vertIdx].Set(pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z);
pMesh->mNormals[vertIdx].Set(pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z);

View File

@ -104,11 +104,12 @@ void RAWImporter::InternReadFile(const std::string &pFile,
// now read all lines
char line[4096];
const char *end = &line[4096];
while (GetNextLine(buffer, line)) {
// if the line starts with a non-numeric identifier, it marks
// the beginning of a new group
const char *sz = line;
SkipSpaces(&sz);
SkipSpaces(&sz, end);
if (IsLineEnd(*sz)) continue;
if (!IsNumeric(*sz)) {
const char *sz2 = sz;
@ -117,8 +118,8 @@ void RAWImporter::InternReadFile(const std::string &pFile,
const unsigned int length = (unsigned int)(sz2 - sz);
// find an existing group with this name
for (std::vector<GroupInformation>::iterator it = outGroups.begin(), end = outGroups.end();
it != end; ++it) {
for (std::vector<GroupInformation>::iterator it = outGroups.begin(), endIt = outGroups.end();
it != endIt; ++it) {
if (length == (*it).name.length() && !::strcmp(sz, (*it).name.c_str())) {
curGroup = it;
sz2 = nullptr;
@ -134,7 +135,7 @@ void RAWImporter::InternReadFile(const std::string &pFile,
float data[12];
unsigned int num;
for (num = 0; num < 12; ++num) {
if (!SkipSpaces(&sz) || !IsNumeric(*sz)) break;
if (!SkipSpaces(&sz, end) || !IsNumeric(*sz)) break;
sz = fast_atoreal_move<float>(sz, data[num]);
}
if (num != 12 && num != 9) {

View File

@ -82,8 +82,10 @@ static constexpr aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
SMDImporter::SMDImporter() :
configFrameID(),
pScene( nullptr ),
configFrameID(),
mBuffer(),
mEnd(nullptr),
pScene(nullptr),
iFileSize( 0 ),
iSmallestFrame( INT_MAX ),
dLengthOfAnim( 0.0 ),
@ -92,9 +94,6 @@ SMDImporter::SMDImporter() :
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
SMDImporter::~SMDImporter() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
@ -632,13 +631,13 @@ void SMDImporter::ParseFile() {
// read line per line ...
for ( ;; ) {
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent, mEnd)) {
break;
}
// "version <n> \n", <n> should be 1 for hl and hl2 SMD files
if (TokenMatch(szCurrent,"version",7)) {
if(!SkipSpaces(szCurrent,&szCurrent)) break;
if(!SkipSpaces(szCurrent,&szCurrent, mEnd)) break;
if (1 != strtoul10(szCurrent,&szCurrent)) {
ASSIMP_LOG_WARN("SMD.version is not 1. This "
"file format is not known. Continuing happily ...");
@ -647,26 +646,26 @@ void SMDImporter::ParseFile() {
}
// "nodes\n" - Starts the node section
if (TokenMatch(szCurrent,"nodes",5)) {
ParseNodesSection(szCurrent,&szCurrent);
ParseNodesSection(szCurrent, &szCurrent, mEnd);
continue;
}
// "triangles\n" - Starts the triangle section
if (TokenMatch(szCurrent,"triangles",9)) {
ParseTrianglesSection(szCurrent,&szCurrent);
ParseTrianglesSection(szCurrent, &szCurrent, mEnd);
continue;
}
// "vertexanimation\n" - Starts the vertex animation section
if (TokenMatch(szCurrent,"vertexanimation",15)) {
bHasUVs = false;
ParseVASection(szCurrent,&szCurrent);
ParseVASection(szCurrent, &szCurrent, mEnd);
continue;
}
// "skeleton\n" - Starts the skeleton section
if (TokenMatch(szCurrent,"skeleton",8)) {
ParseSkeletonSection(szCurrent,&szCurrent);
ParseSkeletonSection(szCurrent, &szCurrent, mEnd);
continue;
}
SkipLine(szCurrent,&szCurrent);
SkipLine(szCurrent, &szCurrent, mEnd);
}
}
@ -683,6 +682,7 @@ void SMDImporter::ReadSmd(const std::string &pFile, IOSystem* pIOHandler) {
// Allocate storage and copy the contents of the file to a memory buffer
mBuffer.resize(iFileSize + 1);
TextFileToBuffer(file.get(), mBuffer);
mEnd = &mBuffer[mBuffer.size() - 1] + 1;
iSmallestFrame = INT_MAX;
bHasUVs = true;
@ -723,26 +723,26 @@ unsigned int SMDImporter::GetTextureIndex(const std::string& filename) {
// ------------------------------------------------------------------------------------------------
// Parse the nodes section of the file
void SMDImporter::ParseNodesSection(const char* szCurrent, const char** szCurrentOut) {
void SMDImporter::ParseNodesSection(const char* szCurrent, const char** szCurrentOut, const char *end) {
for ( ;; ) {
// "end\n" - Ends the nodes section
if (0 == ASSIMP_strincmp(szCurrent,"end",3) && IsSpaceOrNewLine(*(szCurrent+3))) {
if (0 == ASSIMP_strincmp(szCurrent, "end", 3) && IsSpaceOrNewLine(*(szCurrent+3))) {
szCurrent += 4;
break;
}
ParseNodeInfo(szCurrent,&szCurrent);
ParseNodeInfo(szCurrent,&szCurrent, end);
}
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
*szCurrentOut = szCurrent;
}
// ------------------------------------------------------------------------------------------------
// Parse the triangles section of the file
void SMDImporter::ParseTrianglesSection(const char* szCurrent, const char** szCurrentOut) {
void SMDImporter::ParseTrianglesSection(const char *szCurrent, const char **szCurrentOut, const char *end) {
// Parse a triangle, parse another triangle, parse the next triangle ...
// and so on until we reach a token that looks quite similar to "end"
for ( ;; ) {
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
break;
}
@ -750,17 +750,17 @@ void SMDImporter::ParseTrianglesSection(const char* szCurrent, const char** szCu
if (TokenMatch(szCurrent,"end",3)) {
break;
}
ParseTriangle(szCurrent,&szCurrent);
ParseTriangle(szCurrent,&szCurrent, end);
}
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
*szCurrentOut = szCurrent;
}
// ------------------------------------------------------------------------------------------------
// Parse the vertex animation section of the file
void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOut) {
void SMDImporter::ParseVASection(const char *szCurrent, const char **szCurrentOut, const char *end) {
unsigned int iCurIndex = 0;
for ( ;; ) {
if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
break;
}
@ -774,10 +774,10 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
// NOTE: The doc says that time values COULD be negative ...
// NOTE2: this is the shape key -> valve docs
int iTime = 0;
if(!ParseSignedInt(szCurrent,&szCurrent,iTime) || configFrameID != (unsigned int)iTime) {
if (!ParseSignedInt(szCurrent, &szCurrent, end, iTime) || configFrameID != (unsigned int)iTime) {
break;
}
SkipLine(szCurrent,&szCurrent);
SkipLine(szCurrent,&szCurrent, end);
} else {
if(0 == iCurIndex) {
asTriangles.emplace_back();
@ -785,7 +785,7 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
if (++iCurIndex == 3) {
iCurIndex = 0;
}
ParseVertex(szCurrent,&szCurrent,asTriangles.back().avVertices[iCurIndex],true);
ParseVertex(szCurrent,&szCurrent, end, asTriangles.back().avVertices[iCurIndex],true);
}
}
@ -794,16 +794,16 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
asTriangles.pop_back();
}
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
*szCurrentOut = szCurrent;
}
// ------------------------------------------------------------------------------------------------
// Parse the skeleton section of the file
void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCurrentOut) {
void SMDImporter::ParseSkeletonSection(const char *szCurrent, const char **szCurrentOut, const char *end) {
int iTime = 0;
for ( ;; ) {
if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
break;
}
@ -811,15 +811,15 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCur
if (TokenMatch(szCurrent,"end",3)) {
break;
} else if (TokenMatch(szCurrent,"time",4)) {
// "time <n>\n" - Specifies the current animation frame
if(!ParseSignedInt(szCurrent,&szCurrent,iTime)) {
// "time <n>\n" - Specifies the current animation frame
if (!ParseSignedInt(szCurrent, &szCurrent, end, iTime)) {
break;
}
iSmallestFrame = std::min(iSmallestFrame,iTime);
SkipLine(szCurrent,&szCurrent);
SkipLine(szCurrent, &szCurrent, end);
} else {
ParseSkeletonElement(szCurrent,&szCurrent,iTime);
ParseSkeletonElement(szCurrent, &szCurrent, end, iTime);
}
}
*szCurrentOut = szCurrent;
@ -827,16 +827,16 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCur
// ------------------------------------------------------------------------------------------------
#define SMDI_PARSE_RETURN { \
SkipLine(szCurrent,&szCurrent); \
SkipLine(szCurrent,&szCurrent, end); \
*szCurrentOut = szCurrent; \
return; \
}
// ------------------------------------------------------------------------------------------------
// Parse a node line
void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut) {
void SMDImporter::ParseNodeInfo(const char *szCurrent, const char **szCurrentOut, const char *end) {
unsigned int iBone = 0;
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
if ( !ParseUnsignedInt(szCurrent,&szCurrent,iBone) || !SkipSpaces(szCurrent,&szCurrent)) {
SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
if ( !ParseUnsignedInt(szCurrent, &szCurrent, end, iBone) || !SkipSpaces(szCurrent,&szCurrent, end)) {
throw DeadlyImportError("Unexpected EOF/EOL while parsing bone index");
}
if (iBone == UINT_MAX) {
@ -877,7 +877,7 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut
szCurrent = szEnd;
// the only negative bone parent index that could occur is -1 AFAIK
if(!ParseSignedInt(szCurrent,&szCurrent,(int&)bone.iParent)) {
if(!ParseSignedInt(szCurrent, &szCurrent, end, (int&)bone.iParent)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone parent index. Assuming -1");
SMDI_PARSE_RETURN;
}
@ -888,12 +888,12 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut
// ------------------------------------------------------------------------------------------------
// Parse a skeleton element
void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCurrentOut,int iTime) {
void SMDImporter::ParseSkeletonElement(const char *szCurrent, const char **szCurrentOut, const char *end, int iTime) {
aiVector3D vPos;
aiVector3D vRot;
unsigned int iBone = 0;
if(!ParseUnsignedInt(szCurrent,&szCurrent,iBone)) {
if (!ParseUnsignedInt(szCurrent, &szCurrent, end, iBone)) {
ASSIMP_LOG_ERROR("Unexpected EOF/EOL while parsing bone index");
SMDI_PARSE_RETURN;
}
@ -907,27 +907,27 @@ void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCur
SMD::Bone::Animation::MatrixKey& key = bone.sAnim.asKeys.back();
key.dTime = (double)iTime;
if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.x)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.x");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.y)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.y");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.z)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.z)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.z");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.x)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.x");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.y)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.y");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.z)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.z)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.z");
SMDI_PARSE_RETURN;
}
@ -947,11 +947,11 @@ void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCur
// ------------------------------------------------------------------------------------------------
// Parse a triangle
void SMDImporter::ParseTriangle(const char* szCurrent, const char** szCurrentOut) {
void SMDImporter::ParseTriangle(const char *szCurrent, const char **szCurrentOut, const char *end) {
asTriangles.emplace_back();
SMD::Face& face = asTriangles.back();
if(!SkipSpaces(szCurrent,&szCurrent)) {
if(!SkipSpaces(szCurrent, &szCurrent, end)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing a triangle");
return;
}
@ -963,19 +963,19 @@ void SMDImporter::ParseTriangle(const char* szCurrent, const char** szCurrentOut
// ... and get the index that belongs to this file name
face.iTexture = GetTextureIndex(std::string(szLast,(uintptr_t)szCurrent-(uintptr_t)szLast));
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
// load three vertices
for (auto &avVertex : face.avVertices) {
ParseVertex(szCurrent,&szCurrent, avVertex);
ParseVertex(szCurrent, &szCurrent, end, avVertex);
}
*szCurrentOut = szCurrent;
}
// ------------------------------------------------------------------------------------------------
// Parse a float
bool SMDImporter::ParseFloat(const char* szCurrent, const char** szCurrentOut, float& out) {
if(!SkipSpaces(&szCurrent)) {
bool SMDImporter::ParseFloat(const char *szCurrent, const char **szCurrentOut, const char *end, float &out) {
if (!SkipSpaces(&szCurrent, end)) {
return false;
}
@ -985,8 +985,8 @@ bool SMDImporter::ParseFloat(const char* szCurrent, const char** szCurrentOut, f
// ------------------------------------------------------------------------------------------------
// Parse an unsigned int
bool SMDImporter::ParseUnsignedInt(const char* szCurrent, const char** szCurrentOut, unsigned int& out) {
if(!SkipSpaces(&szCurrent)) {
bool SMDImporter::ParseUnsignedInt(const char *szCurrent, const char **szCurrentOut, const char *end, unsigned int &out) {
if(!SkipSpaces(&szCurrent, end)) {
return false;
}
@ -996,8 +996,8 @@ bool SMDImporter::ParseUnsignedInt(const char* szCurrent, const char** szCurrent
// ------------------------------------------------------------------------------------------------
// Parse a signed int
bool SMDImporter::ParseSignedInt(const char* szCurrent, const char** szCurrentOut, int& out) {
if(!SkipSpaces(&szCurrent)) {
bool SMDImporter::ParseSignedInt(const char *szCurrent, const char **szCurrentOut, const char *end, int &out) {
if(!SkipSpaces(&szCurrent, end)) {
return false;
}
@ -1008,37 +1008,37 @@ bool SMDImporter::ParseSignedInt(const char* szCurrent, const char** szCurrentOu
// ------------------------------------------------------------------------------------------------
// Parse a vertex
void SMDImporter::ParseVertex(const char* szCurrent,
const char** szCurrentOut, SMD::Vertex& vertex,
const char **szCurrentOut, const char *end, SMD::Vertex &vertex,
bool bVASection /*= false*/) {
if (SkipSpaces(&szCurrent) && IsLineEnd(*szCurrent)) {
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
return ParseVertex(szCurrent,szCurrentOut,vertex,bVASection);
if (SkipSpaces(&szCurrent, end) && IsLineEnd(*szCurrent)) {
SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
return ParseVertex(szCurrent, szCurrentOut, end, vertex, bVASection);
}
if(!ParseSignedInt(szCurrent,&szCurrent,(int&)vertex.iParentNode)) {
if(!ParseSignedInt(szCurrent, &szCurrent, end, (int&)vertex.iParentNode)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.parent");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.x)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.x");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.y)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.y");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.z)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.z)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.z");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.x)) {
if(!ParseFloat(szCurrent,&szCurrent,end, (float&)vertex.nor.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.x");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.y)) {
if(!ParseFloat(szCurrent,&szCurrent, end, (float&)vertex.nor.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.y");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.z)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.nor.z)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.z");
SMDI_PARSE_RETURN;
}
@ -1047,11 +1047,11 @@ void SMDImporter::ParseVertex(const char* szCurrent,
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.x)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.uv.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.x");
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.y)) {
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.uv.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.y");
SMDI_PARSE_RETURN;
}
@ -1059,16 +1059,16 @@ void SMDImporter::ParseVertex(const char* szCurrent,
// now read the number of bones affecting this vertex
// all elements from now are fully optional, we don't need them
unsigned int iSize = 0;
if(!ParseUnsignedInt(szCurrent,&szCurrent,iSize)) {
if(!ParseUnsignedInt(szCurrent, &szCurrent, end, iSize)) {
SMDI_PARSE_RETURN;
}
vertex.aiBoneLinks.resize(iSize,std::pair<unsigned int, float>(0,0.0f));
for (auto &aiBoneLink : vertex.aiBoneLinks) {
if(!ParseUnsignedInt(szCurrent,&szCurrent,aiBoneLink.first)) {
if(!ParseUnsignedInt(szCurrent, &szCurrent, end, aiBoneLink.first)) {
SMDI_PARSE_RETURN;
}
if(!ParseFloat(szCurrent,&szCurrent,aiBoneLink.second)) {
if(!ParseFloat(szCurrent, &szCurrent, end, aiBoneLink.second)) {
SMDI_PARSE_RETURN;
}
}
@ -1077,6 +1077,6 @@ void SMDImporter::ParseVertex(const char* szCurrent,
SMDI_PARSE_RETURN;
}
}
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_SMD_IMPORTER

View File

@ -162,7 +162,7 @@ struct Bone {
class ASSIMP_API SMDImporter : public BaseImporter {
public:
SMDImporter();
~SMDImporter() override;
~SMDImporter() override = default;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
@ -206,7 +206,7 @@ protected:
* the next section (or to EOF)
*/
void ParseTrianglesSection(const char* szCurrent,
const char** szCurrentOut);
const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse the vertex animation section in VTA files
@ -216,7 +216,7 @@ protected:
* the next section (or to EOF)
*/
void ParseVASection(const char* szCurrent,
const char** szCurrentOut);
const char **szCurrentOu, const char *end);
// -------------------------------------------------------------------
/** Parse the nodes section of the SMD file
@ -226,7 +226,7 @@ protected:
* the next section (or to EOF)
*/
void ParseNodesSection(const char* szCurrent,
const char** szCurrentOut);
const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse the skeleton section of the SMD file
@ -236,7 +236,7 @@ protected:
* the next section (or to EOF)
*/
void ParseSkeletonSection(const char* szCurrent,
const char** szCurrentOut);
const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse a single triangle in the SMD file
@ -245,8 +245,7 @@ protected:
* \param szCurrentOut Receives the output cursor position
*/
void ParseTriangle(const char* szCurrent,
const char** szCurrentOut);
const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse a single vertex in the SMD file
@ -256,7 +255,7 @@ protected:
* \param vertex Vertex to be filled
*/
void ParseVertex(const char* szCurrent,
const char** szCurrentOut, SMD::Vertex& vertex,
const char **szCurrentOut, const char *end, SMD::Vertex &vertex,
bool bVASection = false);
// -------------------------------------------------------------------
@ -271,32 +270,31 @@ protected:
/** Parse a line in the skeleton section
*/
void ParseSkeletonElement(const char* szCurrent,
const char** szCurrentOut,int iTime);
const char **szCurrentOut, const char *end, int iTime);
// -------------------------------------------------------------------
/** Parse a line in the nodes section
*/
void ParseNodeInfo(const char* szCurrent,
const char** szCurrentOut);
const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse a floating-point value
*/
bool ParseFloat(const char* szCurrent,
const char** szCurrentOut, float& out);
const char **szCurrentOut, const char *end, float &out);
// -------------------------------------------------------------------
/** Parse an unsigned integer. There may be no sign!
*/
bool ParseUnsignedInt(const char* szCurrent,
const char** szCurrentOut, unsigned int& out);
const char **szCurrentOut, const char *end, unsigned int &out);
// -------------------------------------------------------------------
/** Parse a signed integer. Signs (+,-) are handled.
*/
bool ParseSignedInt(const char* szCurrent,
const char** szCurrentOut, int& out);
const char **szCurrentOut, const char *end, int &out);
// -------------------------------------------------------------------
/** Fix invalid time values in the file
@ -304,7 +302,7 @@ protected:
void FixTimeValues();
// -------------------------------------------------------------------
/** Add all children of a bone as subnodes to a node
/** Add all children of a bone as sub-nodes to a node
* \param pcNode Parent node
* \param iParent Parent bone index
*/
@ -329,17 +327,15 @@ protected:
// -------------------------------------------------------------------
inline bool SkipLine( const char* in, const char** out)
{
Assimp::SkipLine(in,out);
inline bool SkipLine( const char* in, const char** out, const char *end) {
Assimp::SkipLine(in, out, end);
++iLineNumber;
return true;
}
// -------------------------------------------------------------------
inline bool SkipSpacesAndLineEnd( const char* in, const char** out)
{
inline bool SkipSpacesAndLineEnd(const char *in, const char **out, const char *end) {
++iLineNumber;
return Assimp::SkipSpacesAndLineEnd(in,out);
return Assimp::SkipSpacesAndLineEnd(in, out, end);
}
private:
@ -349,6 +345,7 @@ private:
/** Buffer to hold the loaded file */
std::vector<char> mBuffer;
char *mEnd;
/** Output scene to be filled
*/

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -40,9 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file STEPFileReader.cpp
/**
* @file STEPFileReader.cpp
* @brief Implementation of the STEP file parser, which fills a
* STEP::DB with data read from a file.
* STEP::DB with data read from a file.
*/
#include "STEPFileReader.h"
@ -58,34 +58,28 @@ using namespace Assimp;
namespace EXPRESS = STEP::EXPRESS;
// ------------------------------------------------------------------------------------------------
std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = std::string())
{
std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = std::string()) {
return line == STEP::SyntaxError::LINE_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(line ",line,") ",s) );
}
// ------------------------------------------------------------------------------------------------
std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = std::string())
{
std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = std::string()) {
return entity == STEP::TypeError::ENTITY_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(entity #",entity,") ",s));
}
// ------------------------------------------------------------------------------------------------
STEP::SyntaxError::SyntaxError (const std::string& s,uint64_t line /* = LINE_NOT_SPECIFIED */)
: DeadlyImportError(AddLineNumber(s,line))
{
STEP::SyntaxError::SyntaxError (const std::string& s,uint64_t line) : DeadlyImportError(AddLineNumber(s,line)) {
// empty
}
// ------------------------------------------------------------------------------------------------
STEP::TypeError::TypeError (const std::string& s,uint64_t entity /* = ENTITY_NOT_SPECIFIED */,uint64_t line /*= LINE_NOT_SPECIFIED*/)
: DeadlyImportError(AddLineNumber(AddEntityID(s,entity),line))
{
STEP::TypeError::TypeError (const std::string& s,uint64_t entity, uint64_t line) : DeadlyImportError(AddLineNumber(AddEntityID(s,entity),line)) {
// empty
}
static const char *ISO_Token = "ISO-10303-21;";
static const char *FILE_SCHEMA_Token = "FILE_SCHEMA";
static constexpr char ISO_Token[] = "ISO-10303-21;";
static constexpr char FILE_SCHEMA_Token[] = "FILE_SCHEMA";
// ------------------------------------------------------------------------------------------------
STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(std::move(stream)));
@ -110,8 +104,9 @@ STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
if (s.substr(0,11) == FILE_SCHEMA_Token) {
const char* sz = s.c_str()+11;
SkipSpaces(sz,&sz);
std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz);
const char *end = s.c_str() + s.size();
SkipSpaces(sz,&sz, end);
std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz, end);
// the file schema should be a regular list entity, although it usually contains exactly one entry
// since the list itself is contained in a regular parameter list, we actually have
@ -304,10 +299,10 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
}
// ------------------------------------------------------------------------------------------------
std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/)
std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout, const char *end, uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/)
{
const char* cur = inout;
SkipSpaces(&cur);
SkipSpaces(&cur, end);
if (*cur == ',' || IsSpaceOrNewLine(*cur)) {
throw STEP::SyntaxError("unexpected token, expected parameter",line);
}
@ -325,7 +320,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
std::transform(s.begin(),s.end(),s.begin(),&ai_tolower<char> );
if (schema->IsKnownToken(s)) {
for(cur = t+1;*cur++ != '(';);
std::shared_ptr<const EXPRESS::DataType> dt = Parse(cur);
std::shared_ptr<const EXPRESS::DataType> dt = Parse(cur, end);
inout = *cur ? cur+1 : cur;
return dt;
}
@ -348,7 +343,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
else if (*cur == '(' ) {
// start of an aggregate, further parsing is done by the LIST factory constructor
inout = cur;
return EXPRESS::LIST::Parse(inout,line,schema);
return EXPRESS::LIST::Parse(inout, end, line, schema);
}
else if (*cur == '.' ) {
// enum (includes boolean)
@ -427,9 +422,10 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
}
// ------------------------------------------------------------------------------------------------
std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/) {
std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout, const char *end,
uint64_t line, const EXPRESS::ConversionSchema* schema) {
const std::shared_ptr<EXPRESS::LIST> list = std::make_shared<EXPRESS::LIST>();
EXPRESS::LIST::MemberList& members = list->members;
EXPRESS::LIST::MemberList& cur_members = list->members;
const char* cur = inout;
if (*cur++ != '(') {
@ -442,19 +438,19 @@ std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uin
count += (*c == ',' ? 1 : 0);
}
members.reserve(count);
cur_members.reserve(count);
for(;;++cur) {
if (!*cur) {
throw STEP::SyntaxError("unexpected end of line while reading list");
}
SkipSpaces(cur,&cur);
SkipSpaces(cur,&cur, end);
if (*cur == ')') {
break;
}
members.push_back( EXPRESS::DataType::Parse(cur,line,schema));
SkipSpaces(cur,&cur);
cur_members.push_back(EXPRESS::DataType::Parse(cur, end, line, schema));
SkipSpaces(cur, &cur, end);
if (*cur != ',') {
if (*cur == ')') {
@ -464,7 +460,7 @@ std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uin
}
}
inout = cur+1;
inout = cur + 1;
return list;
}
@ -543,7 +539,8 @@ void STEP::LazyObject::LazyInit() const {
}
const char* acopy = args;
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,(uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
const char *end = acopy + std::strlen(args);
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy, end, (uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
delete[] args;
args = nullptr;

View File

@ -60,8 +60,7 @@ void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const*
/// @brief Helper to read a file.
template <size_t N, size_t N2>
inline
void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
return ReadFile(db,scheme,arr,N,arr2,N2);
}

View File

@ -98,7 +98,7 @@ static bool IsAsciiSTL(const char *buffer, size_t fileSize) {
const char *bufferEnd = buffer + fileSize;
if (!SkipSpaces(&buffer)) {
if (!SkipSpaces(&buffer, bufferEnd)) {
return false;
}
@ -244,11 +244,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
aiNode *node = new aiNode;
node->mParent = root;
nodes.push_back(node);
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
ai_assert(!IsLineEnd(sz));
sz += 5; // skip the "solid"
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
const char *szMe = sz;
while (!IsSpaceOrNewLine(*sz)) {
sz++;
@ -270,7 +270,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
unsigned int faceVertexCounter = 3;
for (;;) {
// go to the next token
if (!SkipSpacesAndLineEnd(&sz)) {
if (!SkipSpacesAndLineEnd(&sz, bufferEnd)) {
// seems we're finished although there was no end marker
ASSIMP_LOG_WARN("STL: unexpected EOF. \'endsolid\' keyword was expected");
break;
@ -284,7 +284,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
faceVertexCounter = 0;
sz += 6;
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
if (strncmp(sz, "normal", 6)) {
ASSIMP_LOG_WARN("STL: a facet normal vector was expected but not found");
} else {
@ -293,11 +293,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
}
aiVector3D vn;
sz += 7;
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.x);
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.y);
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.z);
normalBuffer.emplace_back(vn);
normalBuffer.emplace_back(vn);
@ -312,13 +312,13 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
sz += 7;
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
positionBuffer.emplace_back();
aiVector3D *vn = &positionBuffer.back();
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->x);
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->y);
SkipSpaces(&sz);
SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->z);
faceVertexCounter++;
}
@ -326,7 +326,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
do {
++sz;
} while (!IsLineEnd(*sz));
SkipSpacesAndLineEnd(&sz);
SkipSpacesAndLineEnd(&sz, bufferEnd);
// finished!
break;
} else { // else skip the whole identifier

View File

@ -199,35 +199,27 @@ public:
}
public:
/** parse a variable from a string and set 'inout' to the character
* behind the last consumed character. An optional schema enables,
* if specified, automatic conversion of custom data types.
*
* @throw SyntaxError
*/
static std::shared_ptr<const EXPRESS::DataType> Parse(const char *&inout,
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
const EXPRESS::ConversionSchema *schema = nullptr);
/// @brief Parse a variable from a string and set 'inout' to the character behind the last consumed character.
///
/// An optional schema enables, if specified, automatic conversion of custom data types.
///
/// @throw SyntaxError
static std::shared_ptr<const EXPRESS::DataType> Parse(const char *&inout, const char *end,
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED, const EXPRESS::ConversionSchema *schema = nullptr);
};
typedef DataType SELECT;
typedef DataType LOGICAL;
// -------------------------------------------------------------------------------
/** Sentinel class to represent explicitly unset (optional) fields ($) */
/// Sentinel class to represent explicitly unset (optional) fields ($)
// -------------------------------------------------------------------------------
class UNSET : public DataType {
public:
private:
};
class UNSET : public DataType {};
// -------------------------------------------------------------------------------
/** Sentinel class to represent explicitly derived fields (*) */
/// Sentinel class to represent explicitly derived fields (*)
// -------------------------------------------------------------------------------
class ISDERIVED : public DataType {
public:
private:
};
class ISDERIVED : public DataType {};
// -------------------------------------------------------------------------------
/** Shared implementation for some of the primitive data type, i.e. int, float
@ -304,7 +296,7 @@ public:
public:
/** @see DaraType::Parse
*/
static std::shared_ptr<const EXPRESS::LIST> Parse(const char *&inout,
static std::shared_ptr<const EXPRESS::LIST> Parse(const char *&inout, const char *end,
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
const EXPRESS::ConversionSchema *schema = nullptr);

View File

@ -320,17 +320,18 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
std::vector<char> _data;
TextFileToBuffer(pb.get(), _data);
const char *data = &_data[0];
const char *end = &_data[_data.size() - 1] + 1;
std::vector<std::pair<std::string, std::string>> tempTextures;
// do a quick search in the UC file for some known, usually texture-related, tags
for (; *data; ++data) {
if (TokenMatchI(data, "#exec", 5)) {
SkipSpacesAndLineEnd(&data);
SkipSpacesAndLineEnd(&data, end);
// #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...]
if (TokenMatchI(data, "TEXTURE", 7)) {
SkipSpacesAndLineEnd(&data);
SkipSpacesAndLineEnd(&data, end);
if (TokenMatchI(data, "IMPORT", 6)) {
tempTextures.emplace_back();
@ -348,14 +349,15 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
me.second = std::string(d, (size_t)(data - d));
}
}
if (!me.first.length() || !me.second.length())
if (!me.first.length() || !me.second.length()) {
tempTextures.pop_back();
}
}
}
// #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
// #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
else if (TokenMatchI(data, "MESHMAP", 7)) {
SkipSpacesAndLineEnd(&data);
SkipSpacesAndLineEnd(&data, end);
if (TokenMatchI(data, "SETTEXTURE", 10)) {
@ -369,8 +371,7 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
} else if (!ASSIMP_strincmp(data, "TEXTURE=", 8)) {
data += 8;
const char *d = data;
for (; !IsSpaceOrNewLine(*data); ++data)
;
for (; !IsSpaceOrNewLine(*data); ++data);
me.second = std::string(d, (size_t)(data - d));
// try to find matching path names, doesn't care if we don't find them
@ -408,7 +409,7 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
// find out how many output meshes and materials we'll have and build material indices
for (Unreal::Triangle &tri : triangles) {
Unreal::TempMat mat(tri);
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(), materials.end(), mat);
auto nt = std::find(materials.begin(), materials.end(), mat);
if (nt == materials.end()) {
// add material
tri.matIndex = static_cast<unsigned int>(materials.size());

View File

@ -359,10 +359,18 @@ void XFileImporter::CreateMeshes(aiScene *pScene, aiNode *pNode, const std::vect
// set up a vertex-linear array of the weights for quick searching if a bone influences a vertex
std::vector<ai_real> oldWeights(sourceMesh->mPositions.size(), 0.0);
for (unsigned int d = 0; d < obone.mWeights.size(); ++d) {
const unsigned int boneIdx = obone.mWeights[d].mVertex;
if (boneIdx < obone.mWeights.size()) {
// TODO The conditional against boneIdx which was added in commit f844c33
// TODO (https://github.com/assimp/assimp/commit/f844c3397d7726477ab0fdca8efd3df56c18366b)
// TODO causes massive breakage as detailed in:
// TODO https://github.com/assimp/assimp/issues/5332
// TODO In cases like this unit tests are less useful, since the model still has
// TODO meshes, textures, animations etc. and asserts against these values may pass;
// TODO when touching importer code, it is crucial that developers also run manual, visual
// TODO checks to ensure there's no obvious breakage _before_ commiting to main branch
//const unsigned int boneIdx = obone.mWeights[d].mVertex;
//if (boneIdx < obone.mWeights.size()) {
oldWeights[obone.mWeights[d].mVertex] = obone.mWeights[d].mWeight;
}
//}
}
// collect all vertex weights that influence a vertex in the new mesh

View File

@ -188,6 +188,51 @@ mg_m_err:
pFaces.clear();
}
void X3DGeoHelper::coordIdx_str2lines_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces) {
std::vector<int32_t> f_data(pCoordIdx);
if (f_data.back() != (-1)) {
f_data.push_back(-1);
}
// reserve average size.
pFaces.reserve(f_data.size() / 2);
for (std::vector<int32_t>::const_iterator startIt = f_data.cbegin(), endIt = f_data.cbegin(); endIt != f_data.cend(); ++endIt) {
// check for end of current polyline
if (*endIt != -1)
continue;
// found end of polyline, check if this is a valid polyline
std::size_t numIndices = std::distance(startIt, endIt);
if (numIndices <= 1)
goto mg_m_err;
// create line faces out of polyline indices
for (int32_t idx0 = *startIt++; startIt != endIt; ++startIt) {
int32_t idx1 = *startIt;
aiFace tface;
tface.mNumIndices = 2;
tface.mIndices = new unsigned int[2];
tface.mIndices[0] = idx0;
tface.mIndices[1] = idx1;
pFaces.push_back(tface);
idx0 = idx1;
}
++startIt;
}
return;
mg_m_err:
for (size_t i = 0, i_e = pFaces.size(); i < i_e; i++)
delete[] pFaces[i].mIndices;
pFaces.clear();
}
void X3DGeoHelper::add_color(aiMesh &pMesh, const std::list<aiColor3D> &pColors, const bool pColorPerVertex) {
std::list<aiColor4D> tcol;
@ -528,4 +573,40 @@ aiMesh *X3DGeoHelper::make_mesh(const std::vector<int32_t> &pCoordIdx, const std
return tmesh;
}
aiMesh *X3DGeoHelper::make_line_mesh(const std::vector<int32_t> &pCoordIdx, const std::list<aiVector3D> &pVertices) {
std::vector<aiFace> faces;
// create faces array from input string with vertices indices.
X3DGeoHelper::coordIdx_str2lines_arr(pCoordIdx, faces);
if (!faces.size()) {
throw DeadlyImportError("Failed to create mesh, faces list is empty.");
}
//
// Create new mesh and copy geometry data.
//
aiMesh *tmesh = new aiMesh;
size_t ts = faces.size();
// faces
tmesh->mFaces = new aiFace[ts];
tmesh->mNumFaces = static_cast<unsigned int>(ts);
for (size_t i = 0; i < ts; i++)
tmesh->mFaces[i] = faces[i];
// vertices
std::list<aiVector3D>::const_iterator vit = pVertices.begin();
ts = pVertices.size();
tmesh->mVertices = new aiVector3D[ts];
tmesh->mNumVertices = static_cast<unsigned int>(ts);
for (size_t i = 0; i < ts; i++) {
tmesh->mVertices[i] = *vit++;
}
// set primitive type and return result.
tmesh->mPrimitiveTypes = aiPrimitiveType_LINE;
return tmesh;
}
} // namespace Assimp

View File

@ -21,6 +21,7 @@ public:
static void polylineIdx_to_lineIdx(const std::list<int32_t> &pPolylineCoordIdx, std::list<int32_t> &pLineCoordIdx);
static void rect_parallel_epiped(const aiVector3D &pSize, std::list<aiVector3D> &pVertices);
static void coordIdx_str2faces_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces, unsigned int &pPrimitiveTypes);
static void coordIdx_str2lines_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces);
static void add_color(aiMesh &pMesh, const std::list<aiColor3D> &pColors, const bool pColorPerVertex);
static void add_color(aiMesh &pMesh, const std::list<aiColor4D> &pColors, const bool pColorPerVertex);
static void add_color(aiMesh &pMesh, const std::vector<int32_t> &pCoordIdx, const std::vector<int32_t> &pColorIdx,
@ -34,6 +35,7 @@ public:
const std::list<aiVector2D> &pTexCoords);
static void add_tex_coord(aiMesh &pMesh, const std::list<aiVector2D> &pTexCoords);
static aiMesh *make_mesh(const std::vector<int32_t> &pCoordIdx, const std::list<aiVector3D> &pVertices);
static aiMesh *make_line_mesh(const std::vector<int32_t> &pCoordIdx, const std::list<aiVector3D> &pVertices);
};
} // namespace Assimp

View File

@ -320,7 +320,7 @@ void X3DImporter::Postprocess_BuildMesh(const X3DNodeElementBase &pNodeElement,
// at first search for <Coordinate> node and create mesh.
for (std::list<X3DNodeElementBase *>::iterator ch_it = tnemesh.Children.begin(); ch_it != tnemesh.Children.end(); ++ch_it) {
if ((*ch_it)->Type == X3DElemType::ENET_Coordinate) {
*pMesh = X3DGeoHelper::make_mesh(tnemesh.CoordIndex, ((X3DNodeElementCoordinate *)*ch_it)->Value);
*pMesh = X3DGeoHelper::make_line_mesh(tnemesh.CoordIndex, ((X3DNodeElementCoordinate *)*ch_it)->Value);
}
}

View File

@ -700,13 +700,14 @@ unsigned int XGLImporter::ReadIDAttr(XmlNode &node) {
float XGLImporter::ReadFloat(XmlNode &node) {
std::string v;
XmlParser::getValueAsString(node, v);
const char *s = v.c_str(), *se;
if (!SkipSpaces(&s)) {
const char *s = v.c_str();
const char *end = v.c_str() + v.size();
if (!SkipSpaces(&s, end)) {
LogError("unexpected EOL, failed to parse index element");
return 0.f;
}
float t;
se = fast_atoreal_move(s, t);
float t{ 0.0f };
const char *se = fast_atoreal_move(s, t);
if (se == s) {
LogError("failed to read float text");
return 0.f;
@ -720,7 +721,8 @@ unsigned int XGLImporter::ReadIndexFromText(XmlNode &node) {
std::string v;
XmlParser::getValueAsString(node, v);
const char *s = v.c_str();
if (!SkipSpaces(&s)) {
const char *end = v.c_str() + v.size();
if (!SkipSpaces(&s, end)) {
LogError("unexpected EOL, failed to parse index element");
return ErrorId;
}
@ -741,16 +743,17 @@ aiVector2D XGLImporter::ReadVec2(XmlNode &node) {
std::string val;
XmlParser::getValueAsString(node, val);
const char *s = val.c_str();
const char *end = val.c_str() + val.size();
ai_real v[2] = {};
for (int i = 0; i < 2; ++i) {
if (!SkipSpaces(&s)) {
if (!SkipSpaces(&s, end)) {
LogError("unexpected EOL, failed to parse vec2");
return vec;
}
v[i] = fast_atof(&s);
SkipSpaces(&s);
SkipSpaces(&s, end);
if (i != 1 && *s != ',') {
LogError("expected comma, failed to parse vec2");
return vec;
@ -769,14 +772,15 @@ aiVector3D XGLImporter::ReadVec3(XmlNode &node) {
std::string v;
XmlParser::getValueAsString(node, v);
const char *s = v.c_str();
const char *end = v.c_str() + v.size();
for (int i = 0; i < 3; ++i) {
if (!SkipSpaces(&s)) {
if (!SkipSpaces(&s, end)) {
LogError("unexpected EOL, failed to parse vec3");
return vec;
}
vec[i] = fast_atof(&s);
SkipSpaces(&s);
SkipSpaces(&s, end);
if (i != 2 && *s != ',') {
LogError("expected comma, failed to parse vec3");
return vec;

View File

@ -547,7 +547,7 @@ struct BufferView : public Object {
BufferViewTarget target; //! The target that the WebGL buffer should be bound to.
void Read(Value &obj, Asset &r);
uint8_t *GetPointer(size_t accOffset);
uint8_t *GetPointerAndTailSize(size_t accOffset, size_t& outTailSize);
};
//! A typed view into a BufferView. A BufferView contains raw binary data.
@ -629,7 +629,7 @@ struct Accessor : public Object {
std::vector<uint8_t> data; //!< Actual data, which may be defaulted to an array of zeros or the original data, with the sparse buffer view applied on top of it.
void PopulateData(size_t numBytes, uint8_t *bytes);
void PopulateData(size_t numBytes, const uint8_t *bytes);
void PatchData(unsigned int elementSize);
};
};

View File

@ -785,12 +785,14 @@ inline void BufferView::Read(Value &obj, Asset &r) {
}
}
inline uint8_t *BufferView::GetPointer(size_t accOffset) {
inline uint8_t *BufferView::GetPointerAndTailSize(size_t accOffset, size_t& outTailSize) {
if (!buffer) {
outTailSize = 0;
return nullptr;
}
uint8_t *basePtr = buffer->GetPointer();
uint8_t * const basePtr = buffer->GetPointer();
if (!basePtr) {
outTailSize = 0;
return nullptr;
}
@ -799,17 +801,25 @@ inline uint8_t *BufferView::GetPointer(size_t accOffset) {
const size_t begin = buffer->EncodedRegion_Current->Offset;
const size_t end = begin + buffer->EncodedRegion_Current->DecodedData_Length;
if ((offset >= begin) && (offset < end)) {
outTailSize = end - offset;
return &buffer->EncodedRegion_Current->DecodedData[offset - begin];
}
}
if (offset >= buffer->byteLength)
{
outTailSize = 0;
return nullptr;
}
outTailSize = buffer->byteLength - offset;
return basePtr + offset;
}
//
// struct Accessor
//
inline void Accessor::Sparse::PopulateData(size_t numBytes, uint8_t *bytes) {
inline void Accessor::Sparse::PopulateData(size_t numBytes, const uint8_t *bytes) {
if (bytes) {
data.assign(bytes, bytes + numBytes);
} else {
@ -818,11 +828,21 @@ inline void Accessor::Sparse::PopulateData(size_t numBytes, uint8_t *bytes) {
}
inline void Accessor::Sparse::PatchData(unsigned int elementSize) {
uint8_t *pIndices = indices->GetPointer(indicesByteOffset);
size_t indicesTailDataSize;
uint8_t *pIndices = indices->GetPointerAndTailSize(indicesByteOffset, indicesTailDataSize);
const unsigned int indexSize = int(ComponentTypeSize(indicesType));
uint8_t *indicesEnd = pIndices + count * indexSize;
uint8_t *pValues = values->GetPointer(valuesByteOffset);
if ((uint64_t)indicesEnd > (uint64_t)pIndices + indicesTailDataSize) {
throw DeadlyImportError("Invalid sparse accessor. Indices outside allocated memory.");
}
size_t valuesTailDataSize;
uint8_t* pValues = values->GetPointerAndTailSize(valuesByteOffset, valuesTailDataSize);
if (elementSize * count > valuesTailDataSize) {
throw DeadlyImportError("Invalid sparse accessor. Indices outside allocated memory.");
}
while (pIndices != indicesEnd) {
size_t offset;
switch (indicesType) {
@ -894,6 +914,9 @@ inline void Accessor::Read(Value &obj, Asset &r) {
if (Value *indicesValue = FindObject(*sparseValue, "indices")) {
//indices bufferView
Value *indiceViewID = FindUInt(*indicesValue, "bufferView");
if (!indiceViewID) {
throw DeadlyImportError("A bufferView value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
}
sparse->indices = r.bufferViews.Retrieve(indiceViewID->GetUint());
//indices byteOffset
sparse->indicesByteOffset = MemberOrDefault(*indicesValue, "byteOffset", size_t(0));
@ -909,6 +932,9 @@ inline void Accessor::Read(Value &obj, Asset &r) {
if (Value *valuesValue = FindObject(*sparseValue, "values")) {
//value bufferView
Value *valueViewID = FindUInt(*valuesValue, "bufferView");
if (!valueViewID) {
throw DeadlyImportError("A bufferView value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
}
sparse->values = r.bufferViews.Retrieve(valueViewID->GetUint());
//value byteOffset
sparse->valuesByteOffset = MemberOrDefault(*valuesValue, "byteOffset", size_t(0));
@ -918,8 +944,18 @@ inline void Accessor::Read(Value &obj, Asset &r) {
const unsigned int elementSize = GetElementSize();
const size_t dataSize = count * elementSize;
sparse->PopulateData(dataSize, bufferView ? bufferView->GetPointer(byteOffset) : nullptr);
sparse->PatchData(elementSize);
if (bufferView) {
size_t bufferViewTailSize;
const uint8_t* bufferViewPointer = bufferView->GetPointerAndTailSize(byteOffset, bufferViewTailSize);
if (dataSize > bufferViewTailSize) {
throw DeadlyImportError("Invalid buffer when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
}
sparse->PopulateData(dataSize, bufferViewPointer);
}
else {
sparse->PopulateData(dataSize, nullptr);
}
sparse->PatchData(elementSize);
}
}

View File

@ -912,6 +912,7 @@ void glTF2Exporter::ExportMaterials() {
if (GetMatSpecular(mat, specular)) {
mAsset->extensionsUsed.KHR_materials_specular = true;
m->materialSpecular = Nullable<MaterialSpecular>(specular);
GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE);
}
MaterialSheen sheen;

View File

@ -1193,6 +1193,10 @@ ENDIF ()
TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
add_compile_options(
"$<$<CONFIG:DEBUG>:-O0;-g3;-ggdb>"
)
IF (ASSIMP_WARNINGS_AS_ERRORS)
MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)")
IF (MSVC)

View File

@ -99,12 +99,12 @@ bool DefaultIOSystem::Exists(const char *pFile) const {
return false;
}
#else
FILE *file = ::fopen(pFile, "rb");
if (!file) {
struct stat statbuf;
stat(pFile, &statbuf);
// test for a regular file
if (!S_ISREG(statbuf.st_mode)) {
return false;
}
::fclose(file);
#endif
return true;
@ -116,6 +116,7 @@ IOStream *DefaultIOSystem::Open(const char *strFile, const char *strMode) {
ai_assert(strFile != nullptr);
ai_assert(strMode != nullptr);
FILE *file;
#ifdef _WIN32
std::wstring name = Utf8ToWide(strFile);
if (name.empty()) {
@ -126,6 +127,7 @@ IOStream *DefaultIOSystem::Open(const char *strFile, const char *strMode) {
#else
file = ::fopen(strFile, strMode);
#endif
if (!file) {
return nullptr;
}

View File

@ -64,10 +64,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The list can be regenerated using the following:
cat <path/to/stb/stb_image.h> | fgrep STBIDEF | fgrep '(' | sed -E 's/\*|\(.+//g' | \
awk '{print "#define " $(NF) " assimp_" $(NF) }' | sort | uniq"
cat "path/to/stb/stb_image.h" | fgrep STBIDEF | fgrep '(' | sed -E 's/\*|\(.+//g' | \
awk '{print "#define " $(NF) " assimp_" $(NF) }' | sort | uniq
*/
#define stbi_convert_iphone_png_to_rgb assimp_stbi_convert_iphone_png_to_rgb
#define stbi_convert_iphone_png_to_rgb_thread assimp_stbi_convert_iphone_png_to_rgb_thread
#define stbi_convert_wchar_to_utf8 assimp_stbi_convert_wchar_to_utf8
#define stbi_failure_reason assimp_stbi_failure_reason
#define stbi_hdr_to_ldr_gamma assimp_stbi_hdr_to_ldr_gamma
@ -87,22 +88,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define stbi_is_hdr_from_memory assimp_stbi_is_hdr_from_memory
#define stbi_ldr_to_hdr_gamma assimp_stbi_ldr_to_hdr_gamma
#define stbi_ldr_to_hdr_scale assimp_stbi_ldr_to_hdr_scale
#define stbi_load assimp_stbi_load
#define stbi_load_16 assimp_stbi_load_16
#define stbi_load_16_from_callbacks assimp_stbi_load_16_from_callbacks
#define stbi_load_16_from_memory assimp_stbi_load_16_from_memory
#define stbi_load assimp_stbi_load
#define stbi_load_from_callbacks assimp_stbi_load_from_callbacks
#define stbi_load_from_file assimp_stbi_load_from_file
#define stbi_load_from_file_16 assimp_stbi_load_from_file_16
#define stbi_load_from_memory assimp_stbi_load_from_memory
#define stbi_load_gif_from_memory assimp_stbi_load_gif_from_memory
#define stbi_loadf assimp_stbi_loadf
#define stbi_loadf_from_callbacks assimp_stbi_loadf_from_callbacks
#define stbi_loadf_from_file assimp_stbi_loadf_from_file
#define stbi_loadf_from_memory assimp_stbi_loadf_from_memory
#define stbi_load_from_callbacks assimp_stbi_load_from_callbacks
#define stbi_load_from_file_16 assimp_stbi_load_from_file_16
#define stbi_load_from_file assimp_stbi_load_from_file
#define stbi_load_from_memory assimp_stbi_load_from_memory
#define stbi_load_gif_from_memory assimp_stbi_load_gif_from_memory
#define stbi_set_flip_vertically_on_load assimp_stbi_set_flip_vertically_on_load
#define stbi_set_flip_vertically_on_load_thread assimp_stbi_set_flip_vertically_on_load_thread
#define stbi_set_unpremultiply_on_load assimp_stbi_set_unpremultiply_on_load
#define stbi_set_unpremultiply_on_load_thread assimp_stbi_set_unpremultiply_on_load_thread
#define stbi_zlib_decode_buffer assimp_stbi_zlib_decode_buffer
#define stbi_zlib_decode_malloc assimp_stbi_zlib_decode_malloc
#define stbi_zlib_decode_malloc_guesssize assimp_stbi_zlib_decode_malloc_guesssize

View File

@ -89,22 +89,27 @@ using namespace Assimp;
namespace Assimp {
void ExportScenePbrt (
const char* pFile,
IOSystem* pIOSystem,
const aiScene* pScene,
const ExportProperties* /*pProperties*/
){
void ExportScenePbrt(const char *pFile, IOSystem *pIOSystem, const aiScene *pScene,
const ExportProperties *) {
std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
path = path + file + ".pbrt";
// initialize the exporter
PbrtExporter exporter(pScene, pIOSystem, path, file);
}
} // end of namespace Assimp
// Constructor
static void create_embedded_textures_folder(const aiScene *scene, IOSystem *pIOSystem) {
if (scene->mNumTextures > 0) {
if (!pIOSystem->Exists("textures")) {
if (!pIOSystem->CreateDirectory("textures")) {
throw DeadlyExportError("Could not create textures/ directory.");
}
}
}
}
PbrtExporter::PbrtExporter(
const aiScene *pScene, IOSystem *pIOSystem,
const std::string &path, const std::string &file) :
@ -127,10 +132,10 @@ PbrtExporter::PbrtExporter(
0.f, 0.f, 1.f, 0.f, //
0.f, 0.f, 0.f, 1.f //
) * mRootTransform;
// Export embedded textures.
if (mScene->mNumTextures > 0)
if (!mIOSystem->CreateDirectory("textures"))
throw DeadlyExportError("Could not create textures/ directory.");
create_embedded_textures_folder(mScene, mIOSystem);
for (unsigned int i = 0; i < mScene->mNumTextures; ++i) {
aiTexture* tex = mScene->mTextures[i];
std::string fn = CleanTextureFilename(tex->mFilename, false);
@ -176,9 +181,6 @@ PbrtExporter::PbrtExporter(
outfile->Write(mOutput.str().c_str(), mOutput.str().length(), 1);
}
// Destructor
PbrtExporter::~PbrtExporter() = default;
void PbrtExporter::WriteMetaData() {
mOutput << "#############################\n";
mOutput << "# Scene metadata:\n";

View File

@ -70,15 +70,33 @@ class ExportProperties;
// ---------------------------------------------------------------------
/** Helper class to export a given scene to a Pbrt file. */
// ---------------------------------------------------------------------
class PbrtExporter
{
class PbrtExporter {
public:
/// Constructor for a specific scene to export
PbrtExporter(const aiScene *pScene, IOSystem *pIOSystem,
const std::string &path, const std::string &file);
/// Destructor
virtual ~PbrtExporter();
virtual ~PbrtExporter() = default;
private:
aiMatrix4x4 GetNodeTransform(const aiString &name) const;
static std::string TransformAsString(const aiMatrix4x4 &m);
static std::string RemoveSuffix(std::string filename);
std::string CleanTextureFilename(const aiString &f, bool rewriteExtension = true) const;
void WriteMetaData();
void WriteWorldDefinition();
void WriteCameras();
void WriteCamera(int i);
void WriteLights();
void WriteTextures();
static bool TextureHasAlphaMask(const std::string &filename);
void WriteMaterials();
void WriteMaterial(int i);
void WriteMesh(aiMesh *mesh);
void WriteInstanceDefinition(int i);
void WriteGeometricObjects(aiNode *node, aiMatrix4x4 parentTransform,
std::map<int, int> &meshUses);
private:
// the scene to export
@ -96,39 +114,11 @@ private:
/// Name of the file (without extension) where the scene will be exported
const std::string mFile;
private:
// A private set to keep track of which textures have been declared
std::set<std::string> mTextureSet;
// Transform to apply to the root node and all root objects such as cameras, lights, etc.
aiMatrix4x4 mRootTransform;
aiMatrix4x4 GetNodeTransform(const aiString& name) const;
static std::string TransformAsString(const aiMatrix4x4& m);
static std::string RemoveSuffix(std::string filename);
std::string CleanTextureFilename(const aiString &f, bool rewriteExtension = true) const;
void WriteMetaData();
void WriteWorldDefinition();
void WriteCameras();
void WriteCamera(int i);
void WriteLights();
void WriteTextures();
static bool TextureHasAlphaMask(const std::string &filename);
void WriteMaterials();
void WriteMaterial(int i);
void WriteMesh(aiMesh* mesh);
void WriteInstanceDefinition(int i);
void WriteGeometricObjects(aiNode* node, aiMatrix4x4 parentTransform,
std::map<int, int> &meshUses);
};
} // namespace Assimp

View File

@ -52,8 +52,9 @@ namespace Assimp {
// -------------------------------------------------------------------------------
void ConvertListToStrings(const std::string &in, std::list<std::string> &out) {
const char *s = in.c_str();
const char *end = in.c_str() + in.size();
while (*s) {
SkipSpacesAndLineEnd(&s);
SkipSpacesAndLineEnd(&s, end);
if (*s == '\'') {
const char *base = ++s;
while (*s != '\'') {
@ -66,7 +67,7 @@ void ConvertListToStrings(const std::string &in, std::list<std::string> &out) {
out.emplace_back(base, (size_t)(s - base));
++s;
} else {
out.push_back(GetNextToken(s));
out.push_back(GetNextToken(s, end));
}
}
}

View File

@ -75,124 +75,129 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess begin");
unsigned int redundantRemoved = 0, unreferencedRemoved = 0;
if (pScene->mNumMaterials) {
// Find out which materials are referenced by meshes
std::vector<bool> abReferenced(pScene->mNumMaterials,false);
for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
if (pScene->mNumMaterials == 0) {
return;
}
// Find out which materials are referenced by meshes
std::vector<bool> abReferenced(pScene->mNumMaterials,false);
for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
// If a list of materials to be excluded was given, match the list with
// our imported materials and 'salt' all positive matches to ensure that
// we get unique hashes later.
if (mConfigFixedMaterials.length()) {
// If a list of materials to be excluded was given, match the list with
// our imported materials and 'salt' all positive matches to ensure that
// we get unique hashes later.
if (mConfigFixedMaterials.length()) {
std::list<std::string> strings;
ConvertListToStrings(mConfigFixedMaterials,strings);
std::list<std::string> strings;
ConvertListToStrings(mConfigFixedMaterials,strings);
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
aiMaterial* mat = pScene->mMaterials[i];
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
aiMaterial* mat = pScene->mMaterials[i];
aiString name;
mat->Get(AI_MATKEY_NAME,name);
aiString name;
mat->Get(AI_MATKEY_NAME,name);
if (name.length) {
std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
if (it != strings.end()) {
if (name.length) {
std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
if (it != strings.end()) {
// Our brilliant 'salt': A single material property with ~ as first
// character to mark it as internal and temporary.
const int dummy = 1;
((aiMaterial*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0);
// Our brilliant 'salt': A single material property with ~ as first
// character to mark it as internal and temporary.
const int dummy = 1;
((aiMaterial*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0);
// Keep this material even if no mesh references it
abReferenced[i] = true;
ASSIMP_LOG_VERBOSE_DEBUG( "Found positive match in exclusion list: \'", name.data, "\'");
}
// Keep this material even if no mesh references it
abReferenced[i] = true;
ASSIMP_LOG_VERBOSE_DEBUG( "Found positive match in exclusion list: \'", name.data, "\'");
}
}
}
}
// TODO: re-implement this algorithm to work in-place
unsigned int *aiMappingTable = new unsigned int[pScene->mNumMaterials];
for ( unsigned int i=0; i<pScene->mNumMaterials; i++ ) {
aiMappingTable[ i ] = 0;
// TODO: re-implement this algorithm to work in-place
unsigned int *aiMappingTable = new unsigned int[pScene->mNumMaterials];
for ( unsigned int i=0; i<pScene->mNumMaterials; i++ ) {
aiMappingTable[ i ] = 0;
}
unsigned int iNewNum = 0;
// Iterate through all materials and calculate a hash for them
// store all hashes in a list and so a quick search whether
// we do already have a specific hash. This allows us to
// determine which materials are identical.
uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];;
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
// No mesh is referencing this material, remove it.
if (!abReferenced[i]) {
++unreferencedRemoved;
delete pScene->mMaterials[i];
pScene->mMaterials[i] = nullptr;
continue;
}
unsigned int iNewNum = 0;
// Iterate through all materials and calculate a hash for them
// store all hashes in a list and so a quick search whether
// we do already have a specific hash. This allows us to
// determine which materials are identical.
uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];;
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
// No mesh is referencing this material, remove it.
if (!abReferenced[i]) {
++unreferencedRemoved;
// Check all previously mapped materials for a matching hash.
// On a match we can delete this material and just make it ref to the same index.
uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
for (unsigned int a = 0; a < i;++a) {
if (abReferenced[a] && me == aiHashes[a]) {
++redundantRemoved;
me = 0;
aiMappingTable[i] = aiMappingTable[a];
delete pScene->mMaterials[i];
pScene->mMaterials[i] = nullptr;
break;
}
}
// This is a new material that is referenced, add to the map.
if (me) {
aiMappingTable[i] = iNewNum++;
}
}
// If the new material count differs from the original,
// we need to rebuild the material list and remap mesh material indexes.
if (iNewNum < 1) {
//throw DeadlyImportError("No materials remaining");
return;
}
if (iNewNum != pScene->mNumMaterials) {
ai_assert(iNewNum > 0);
aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
for (unsigned int p = 0; p < pScene->mNumMaterials;++p)
{
// if the material is not referenced ... remove it
if (!abReferenced[p]) {
continue;
}
// Check all previously mapped materials for a matching hash.
// On a match we can delete this material and just make it ref to the same index.
uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
for (unsigned int a = 0; a < i;++a) {
if (abReferenced[a] && me == aiHashes[a]) {
++redundantRemoved;
me = 0;
aiMappingTable[i] = aiMappingTable[a];
delete pScene->mMaterials[i];
pScene->mMaterials[i] = nullptr;
break;
// generate new names for modified materials that had no names
const unsigned int idx = aiMappingTable[p];
if (ppcMaterials[idx]) {
aiString sz;
if( ppcMaterials[idx]->Get(AI_MATKEY_NAME, sz) != AI_SUCCESS ) {
sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p);
((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
}
}
// This is a new material that is referenced, add to the map.
if (me) {
aiMappingTable[i] = iNewNum++;
} else {
ppcMaterials[idx] = pScene->mMaterials[p];
}
}
// If the new material count differs from the original,
// we need to rebuild the material list and remap mesh material indexes.
if(iNewNum < 1)
throw DeadlyImportError("No materials remaining");
if (iNewNum != pScene->mNumMaterials) {
ai_assert(iNewNum > 0);
aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
for (unsigned int p = 0; p < pScene->mNumMaterials;++p)
{
// if the material is not referenced ... remove it
if (!abReferenced[p]) {
continue;
}
// generate new names for modified materials that had no names
const unsigned int idx = aiMappingTable[p];
if (ppcMaterials[idx]) {
aiString sz;
if( ppcMaterials[idx]->Get(AI_MATKEY_NAME, sz) != AI_SUCCESS ) {
sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p);
((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
}
} else {
ppcMaterials[idx] = pScene->mMaterials[p];
}
}
// update all material indices
for (unsigned int p = 0; p < pScene->mNumMeshes;++p) {
aiMesh* mesh = pScene->mMeshes[p];
ai_assert(nullptr != mesh);
mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
}
// delete the old material list
delete[] pScene->mMaterials;
pScene->mMaterials = ppcMaterials;
pScene->mNumMaterials = iNewNum;
// update all material indices
for (unsigned int p = 0; p < pScene->mNumMeshes;++p) {
aiMesh* mesh = pScene->mMeshes[p];
ai_assert(nullptr != mesh);
mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
}
// delete temporary storage
delete[] aiHashes;
delete[] aiMappingTable;
// delete the old material list
delete[] pScene->mMaterials;
pScene->mMaterials = ppcMaterials;
pScene->mNumMaterials = iNewNum;
}
// delete temporary storage
delete[] aiHashes;
delete[] aiMappingTable;
if (redundantRemoved == 0 && unreferencedRemoved == 0) {
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess finished ");
} else {

View File

@ -111,6 +111,9 @@ void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point)
{
if (triangle == nullptr)
return;
if (IsEdgeSideOfTriangle(*triangle, ep, eq)) {
return;
}

View File

@ -12,7 +12,6 @@ __Importers__:
- ASE
- ASK
- B3D
- [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format))
- [BVH](https://en.wikipedia.org/wiki/Biovision_Hierarchy)
- CSM
- COB
@ -66,6 +65,9 @@ __Importers__:
- XGL
- ZGL
Note: support for [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format)) is deprecated.
It is too time-consuming to maintain an undocumented format which contains so much more than we need.
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
- [C4D](https://en.wikipedia.org/wiki/Cinema_4D) (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange) IMporting geometry + node hierarchy are currently supported

View File

@ -97,7 +97,7 @@ public:
* Create an instance of your derived class and assign it to an
* #Assimp::Importer instance by calling Importer::SetIOHandler().
*/
IOSystem() AI_NO_EXCEPT;
IOSystem() AI_NO_EXCEPT = default;
// -------------------------------------------------------------------
/** @brief Virtual destructor.
@ -105,7 +105,7 @@ public:
* It is safe to be called from within DLL Assimp, we're constructed
* on Assimp's heap.
*/
virtual ~IOSystem();
virtual ~IOSystem() = default;
// -------------------------------------------------------------------
/** @brief For backward compatibility
@ -236,12 +236,6 @@ private:
std::vector<std::string> m_pathStack;
};
// ----------------------------------------------------------------------------
AI_FORCE_INLINE IOSystem::IOSystem() AI_NO_EXCEPT = default;
// ----------------------------------------------------------------------------
AI_FORCE_INLINE IOSystem::~IOSystem() = default;
// ----------------------------------------------------------------------------
// For compatibility, the interface of some functions taking a std::string was
// changed to const char* to avoid crashes between binary incompatible STL

View File

@ -110,6 +110,8 @@ public:
std::string operator* () const;
const char *getEnd() const;
// -----------------------------------------
/** boolean context */
operator bool() const;
@ -139,17 +141,21 @@ public:
private:
line_idx mIdx;
std::string mCur;
const char *mEnd;
StreamReaderLE& mStream;
bool mSwallow, mSkip_empty_lines, mTrim;
};
AI_FORCE_INLINE LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) :
mIdx(0),
mCur(),
mEnd(nullptr),
mStream(stream),
mSwallow(),
mSkip_empty_lines(skip_empty_lines),
mTrim(trim) {
mCur.reserve(1024);
mEnd = mCur.c_str() + 1024;
operator++();
mIdx = 0;
}
@ -203,14 +209,14 @@ AI_FORCE_INLINE LineSplitter &LineSplitter::operator++(int) {
AI_FORCE_INLINE const char *LineSplitter::operator[] (size_t idx) const {
const char* s = operator->()->c_str();
SkipSpaces(&s);
SkipSpaces(&s, mEnd);
for (size_t i = 0; i < idx; ++i) {
for (; !IsSpace(*s); ++s) {
if (IsLineEnd(*s)) {
throw std::range_error("Token index out of range, EOL reached");
}
}
SkipSpaces(&s);
SkipSpaces(&s, mEnd);
}
return s;
}
@ -219,7 +225,7 @@ template <size_t N>
AI_FORCE_INLINE void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
const char* s = operator->()->c_str();
SkipSpaces(&s);
SkipSpaces(&s, mEnd);
for (size_t i = 0; i < N; ++i) {
if (IsLineEnd(*s)) {
throw std::range_error("Token count out of range, EOL reached");
@ -227,7 +233,7 @@ AI_FORCE_INLINE void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
tokens[i] = s;
for (; *s && !IsSpace(*s); ++s);
SkipSpaces(&s);
SkipSpaces(&s, mEnd);
}
}
@ -239,6 +245,10 @@ AI_FORCE_INLINE std::string LineSplitter::operator* () const {
return mCur;
}
AI_FORCE_INLINE const char* LineSplitter::getEnd() const {
return mEnd;
}
AI_FORCE_INLINE LineSplitter::operator bool() const {
return mStream.GetRemainingSize() > 0;
}

View File

@ -102,8 +102,8 @@ AI_FORCE_INLINE bool IsSpaceOrNewLine(char_t in) {
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out) {
while (*in == (char_t)' ' || *in == (char_t)'\t') {
AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out, const char_t *end) {
while ((*in == (char_t)' ' || *in == (char_t)'\t') && in != end) {
++in;
}
*out = in;
@ -112,19 +112,19 @@ AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out) {
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipSpaces(const char_t **inout) {
return SkipSpaces<char_t>(*inout, inout);
AI_FORCE_INLINE bool SkipSpaces(const char_t **inout, const char_t *end) {
return SkipSpaces<char_t>(*inout, inout, end);
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out) {
while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0') {
AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out, const char_t *end) {
while ((*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0') && in != end) {
++in;
}
// files are opened in binary mode. Ergo there are both NL and CR
while (*in == (char_t)'\r' || *in == (char_t)'\n') {
while ((*in == (char_t)'\r' || *in == (char_t)'\n') && in != end) {
++in;
}
*out = in;
@ -133,14 +133,14 @@ AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out) {
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipLine(const char_t **inout) {
return SkipLine<char_t>(*inout, inout);
AI_FORCE_INLINE bool SkipLine(const char_t **inout, const char_t *end) {
return SkipLine<char_t>(*inout, inout, end);
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out) {
while (*in == (char_t)' ' || *in == (char_t)'\t' || *in == (char_t)'\r' || *in == (char_t)'\n') {
AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out, const char_t *end) {
while ((*in == (char_t)' ' || *in == (char_t)'\t' || *in == (char_t)'\r' || *in == (char_t)'\n') && in != end) {
++in;
}
*out = in;
@ -149,8 +149,8 @@ AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out)
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t **inout) {
return SkipSpacesAndLineEnd<char_t>(*inout, inout);
AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t **inout, const char_t *end) {
return SkipSpacesAndLineEnd<char_t>(*inout, inout, end);
}
// ---------------------------------------------------------------------------------
@ -210,16 +210,16 @@ AI_FORCE_INLINE bool TokenMatchI(const char *&in, const char *token, unsigned in
}
// ---------------------------------------------------------------------------------
AI_FORCE_INLINE void SkipToken(const char *&in) {
SkipSpaces(&in);
AI_FORCE_INLINE void SkipToken(const char *&in, const char *end) {
SkipSpaces(&in, end);
while (!IsSpaceOrNewLine(*in)) {
++in;
}
}
// ---------------------------------------------------------------------------------
AI_FORCE_INLINE std::string GetNextToken(const char *&in) {
SkipSpacesAndLineEnd(&in);
AI_FORCE_INLINE std::string GetNextToken(const char *&in, const char *end) {
SkipSpacesAndLineEnd(&in, end);
const char *cur = in;
while (!IsSpaceOrNewLine(*in)) {
++in;

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
Copyright (c) 2006-2024, assimp team
All rights reserved.
@ -523,6 +523,23 @@ struct aiMemoryInfo {
unsigned int total;
}; // !struct aiMemoryInfo
/**
* @brief Type to store a in-memory data buffer.
*/
struct aiBuffer {
const char *data; ///< Begin poiner
const char *end; ///< End pointer
#ifdef __cplusplus
/// @brief The class constructor.
aiBuffer() :
data(nullptr), end(nullptr) {}
/// @brief The class destructor.
~aiBuffer() = default;
#endif //! __cplusplus
};
#ifdef __cplusplus
}
#endif //! __cplusplus

View File

@ -165,6 +165,7 @@ SET( IMPORTERS
unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
unit/ImportExport/RAW/utRAWImportExport.cpp
unit/ImportExport/Terragen/utTerragenImportExport.cpp
unit/ImportExport/Pbrt/utPbrtImportExport.cpp
)
SET( MATERIAL

View File

@ -0,0 +1,535 @@
AC3Db
MATERIAL "ac3dmat1" rgb 1.00 1.00 1.00 amb 0.20 0.20 0.20 emis 0.00 0.00 0.00 spec 0.20 0.20 0.20 shi 128 trans 0
OBJECT world
kids 2
OBJECT light
name "light"
loc 0.000424567 -0.0127304 0
kids 0
OBJECT poly
name "sphere"
texture "earthSpherical.jpg" base
texture empty_texture_no_mapping tiled
texture empty_texture_no_mapping skids
texture empty_texture_no_mapping shad
numvert 167
-0.051576 -0.062833 0.063067 0.224114 -0.961969 0.156168
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.049587 -0.062833 0.055841 0.270337 -0.962554 0.020215
-0.057009 -0.062833 0.068357 0.117917 -0.961035 0.250013
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.064432 -0.062833 0.070294 -0.019618 -0.960685 0.276946
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.071854 -0.062833 0.068357 -0.151973 -0.961267 0.229935
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.077288 -0.062833 0.063067 -0.243865 -0.962202 0.121235
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.079277 -0.062833 0.055841 -0.270337 -0.962554 -0.020215
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.077288 -0.062833 0.048614 -0.224114 -0.961969 -0.156168
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.071854 -0.062833 0.043324 -0.117917 -0.961035 -0.250013
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.064432 -0.062833 0.041388 0.019618 -0.960685 -0.276946
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.057009 -0.062833 0.043324 0.151973 -0.961267 -0.229935
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.049587 0.042114 0.055841 0.270334 0.962554 -0.020215
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.051576 0.042114 0.063067 0.243863 0.962202 0.121233
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.057009 0.042114 0.068357 0.151972 0.961268 0.229933
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.064432 0.042114 0.070294 0.019618 0.960686 0.276944
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.071854 0.042114 0.068357 -0.117915 0.961036 0.250011
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.077288 0.042114 0.063067 -0.224112 0.961970 0.156167
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.079277 0.042114 0.055841 -0.270334 0.962554 0.020215
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.077288 0.042114 0.048614 -0.243863 0.962202 -0.121233
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.071854 0.042114 0.043324 -0.151972 0.961268 -0.229933
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.064432 0.042114 0.041388 -0.019618 0.960686 -0.276944
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.057009 0.042114 0.043324 0.117916 0.961036 -0.250011
-0.035753 -0.057406 0.055841 0.479979 -0.877222 0.010123
-0.049587 -0.062833 0.055841 0.270337 -0.962554 0.020215
-0.051576 -0.062833 0.048614 0.243865 -0.962202 -0.121234
-0.039596 -0.057406 0.041881 0.420061 -0.875943 -0.237219
-0.023874 -0.048773 0.055841 0.687850 -0.725803 0.008451
-0.029308 -0.048773 0.036098 0.598218 -0.723534 -0.344433
-0.014759 -0.037522 0.055841 0.853991 -0.520251 0.006112
-0.021414 -0.037522 0.031661 0.739473 -0.517639 -0.430382
-0.009029 -0.024420 0.055841 0.962274 -0.272063 0.003217
-0.016452 -0.024420 0.028872 0.830450 -0.270187 -0.487187
-0.007075 -0.010360 0.055841 1.000000 -0.000000 0.000000
-0.014759 -0.010360 0.027920 0.860926 0.000265 -0.508731
-0.009029 0.003701 0.055841 0.962274 0.272063 -0.003217
-0.016452 0.003701 0.028872 0.827147 0.270625 -0.492534
-0.014759 0.016803 0.055841 0.853991 0.520251 -0.006112
-0.021414 0.016803 0.031661 0.733264 0.517855 -0.440625
-0.023874 0.028054 0.055841 0.687850 0.725803 -0.008451
-0.029308 0.028054 0.036098 0.589753 0.723523 -0.358756
-0.035753 0.036687 0.055841 0.479979 0.877222 -0.010123
-0.039596 0.036687 0.041881 0.410061 0.875812 -0.254565
-0.049587 0.042114 0.055841 0.270334 0.962554 -0.020215
-0.051576 0.042114 0.048614 0.224112 0.961970 -0.156167
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
-0.039596 -0.057406 0.069801 0.410061 -0.875812 0.254565
-0.035753 -0.057406 0.055841 0.479979 -0.877222 0.010123
-0.050092 -0.057406 0.080021 0.230454 -0.873143 0.429549
-0.064432 -0.057406 0.083761 -0.009683 -0.871880 0.489625
-0.078771 -0.057406 0.080021 -0.247407 -0.873270 0.419748
-0.089268 -0.057406 0.069801 -0.420061 -0.875942 0.237220
-0.093110 -0.057406 0.055841 -0.479980 -0.877221 -0.010124
-0.089268 -0.057406 0.041881 -0.410062 -0.875812 -0.254565
-0.078771 -0.057406 0.031661 -0.230453 -0.873143 -0.429549
-0.064432 -0.057406 0.027920 0.009684 -0.871880 -0.489625
-0.050092 -0.057406 0.031661 0.247407 -0.873271 -0.419748
-0.029308 -0.048773 0.075583 0.589753 -0.723523 0.358757
-0.023874 -0.048773 0.055841 0.687850 -0.725803 0.008451
-0.044153 -0.048773 0.090036 0.333957 -0.719029 0.609483
-0.064432 -0.048773 0.095326 -0.007940 -0.716811 0.697222
-0.084710 -0.048773 0.090036 -0.348006 -0.719035 0.601564
-0.099555 -0.048773 0.075583 -0.598218 -0.723534 0.344434
-0.104989 -0.048773 0.055841 -0.687850 -0.725804 -0.008451
-0.099555 -0.048773 0.036098 -0.589753 -0.723523 -0.358757
-0.084710 -0.048773 0.021645 -0.333958 -0.719029 -0.609483
-0.064432 -0.048773 0.016355 0.007940 -0.716811 -0.697222
-0.044153 -0.048773 0.021645 0.348006 -0.719035 -0.601565
-0.021414 -0.037522 0.080021 0.733263 -0.517855 0.440625
-0.014759 -0.037522 0.055841 0.853991 -0.520251 0.006112
-0.039596 -0.037522 0.097721 0.416448 -0.512938 0.750643
-0.064432 -0.037522 0.104200 -0.005639 -0.510417 0.859908
-0.089268 -0.037522 0.097721 -0.426533 -0.512723 0.745107
-0.107449 -0.037522 0.080021 -0.739473 -0.517640 0.430382
-0.114104 -0.037522 0.055841 -0.853991 -0.520252 -0.006112
-0.107449 -0.037522 0.031661 -0.733262 -0.517857 -0.440626
-0.089268 -0.037522 0.013960 -0.416448 -0.512938 -0.750643
-0.064432 -0.037522 0.007481 0.005639 -0.510417 -0.859908
-0.039595 -0.037522 0.013960 0.426534 -0.512723 -0.745107
-0.016452 -0.024420 0.082810 0.827147 -0.270625 0.492534
-0.009029 -0.024420 0.055841 0.962274 -0.272063 0.003217
-0.036730 -0.024420 0.102553 0.470709 -0.267377 0.840799
-0.064432 -0.024420 0.109779 -0.002929 -0.265584 0.964083
-0.092133 -0.024420 0.102553 -0.475987 -0.266955 0.837957
-0.112412 -0.024420 0.082810 -0.830450 -0.270188 0.487187
-0.119834 -0.024420 0.055841 -0.962274 -0.272062 -0.003217
-0.112412 -0.024420 0.028872 -0.827148 -0.270623 -0.492534
-0.092133 -0.024420 0.009129 -0.470709 -0.267377 -0.840799
-0.064432 -0.024420 0.001903 0.002929 -0.265584 -0.964083
-0.036730 -0.024420 0.009129 0.475987 -0.266954 -0.837957
-0.014759 -0.010360 0.083761 0.860926 -0.000266 0.508731
-0.007075 -0.010360 0.055841 1.000000 -0.000000 0.000000
-0.035753 -0.010360 0.104200 0.491288 -0.000257 0.870997
-0.064432 -0.010360 0.111682 0.000000 -0.000000 1.000000
-0.093110 -0.010360 0.104200 -0.491288 0.000257 0.870997
-0.114104 -0.010360 0.083761 -0.860926 0.000265 0.508731
-0.121788 -0.010360 0.055841 -1.000000 -0.000001 -0.000001
-0.114104 -0.010360 0.027920 -0.860925 -0.000266 -0.508731
-0.093110 -0.010360 0.007481 -0.491288 -0.000256 -0.870997
-0.064432 -0.010360 0.000000 0.000000 -0.000000 -1.000000
-0.035753 -0.010360 0.007481 0.491288 0.000257 -0.870997
-0.016452 0.003701 0.082810 0.830450 0.270188 0.487187
-0.009029 0.003701 0.055841 0.962274 0.272063 -0.003217
-0.036730 0.003701 0.102553 0.475987 0.266955 0.837957
-0.064432 0.003701 0.109779 0.002929 0.265584 0.964083
-0.092133 0.003701 0.102553 -0.470709 0.267377 0.840799
-0.112412 0.003701 0.082810 -0.827147 0.270625 0.492534
-0.119834 0.003701 0.055841 -0.962274 0.272063 0.003217
-0.112412 0.003701 0.028872 -0.830450 0.270186 -0.487188
-0.092133 0.003701 0.009129 -0.475987 0.266954 -0.837957
-0.064432 0.003701 0.001903 -0.002929 0.265583 -0.964083
-0.036730 0.003701 0.009129 0.470710 0.267376 -0.840799
-0.021414 0.016803 0.080021 0.739473 0.517639 0.430383
-0.014759 0.016803 0.055841 0.853991 0.520251 -0.006112
-0.039596 0.016803 0.097721 0.426533 0.512723 0.745107
-0.064432 0.016803 0.104200 0.005639 0.510417 0.859908
-0.089268 0.016803 0.097721 -0.416448 0.512938 0.750643
-0.107449 0.016803 0.080021 -0.733262 0.517857 0.440626
-0.114104 0.016803 0.055841 -0.853991 0.520252 0.006112
-0.107449 0.016803 0.031661 -0.739473 0.517640 -0.430382
-0.089268 0.016803 0.013960 -0.426533 0.512723 -0.745107
-0.064432 0.016803 0.007481 -0.005640 0.510418 -0.859908
-0.039595 0.016803 0.013960 0.416449 0.512938 -0.750643
-0.029308 0.028054 0.075583 0.598218 0.723534 0.344433
-0.023874 0.028054 0.055841 0.687850 0.725803 -0.008451
-0.044153 0.028054 0.090036 0.348006 0.719035 0.601565
-0.064432 0.028054 0.095326 0.007940 0.716811 0.697222
-0.084710 0.028054 0.090036 -0.333958 0.719029 0.609483
-0.099555 0.028054 0.075583 -0.589753 0.723523 0.358757
-0.104989 0.028054 0.055841 -0.687850 0.725804 0.008451
-0.099555 0.028054 0.036098 -0.598218 0.723534 -0.344434
-0.084710 0.028054 0.021645 -0.348006 0.719035 -0.601564
-0.064432 0.028054 0.016355 -0.007940 0.716811 -0.697222
-0.044153 0.028054 0.021645 0.333956 0.719030 -0.609483
-0.039596 0.036687 0.069801 0.420061 0.875943 0.237219
-0.035753 0.036687 0.055841 0.479979 0.877222 -0.010123
-0.050092 0.036687 0.080021 0.247407 0.873271 0.419748
-0.064432 0.036687 0.083761 0.009684 0.871880 0.489625
-0.078771 0.036687 0.080021 -0.230453 0.873143 0.429549
-0.089268 0.036687 0.069801 -0.410062 0.875812 0.254565
-0.093110 0.036687 0.055841 -0.479980 0.877221 0.010124
-0.089268 0.036687 0.041881 -0.420061 0.875942 -0.237220
-0.078771 0.036687 0.031661 -0.247407 0.873270 -0.419748
-0.064432 0.036687 0.027920 -0.009683 0.871880 -0.489625
-0.050092 0.036687 0.031661 0.230454 0.873143 -0.429549
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
numsurf 13
SURF 0x14
mat 0
refs 25
166 0.12500 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
19 0.16667 0.08333 0.20078 0.00100 0.27261 -0.65958 0.06470 0.11207
44 0.08333 0.08333 0.22774 0.00100 0.24337 -0.66338 0.11207 0.06470
45 0.08333 0.16667 0.25662 0.00100 0.24258 -0.70570 0.21651 0.12500
42 -0.00000 0.16667 0.29617 0.00100 0.18165 -0.65455 0.25000 0.00000
45 0.08333 0.16667 0.25662 0.00100 0.24258 -0.70570 0.21651 0.12500
46 -0.00000 0.25000 0.34675 0.00100 0.14154 -0.62617 0.35355 0.00000
47 0.08333 0.25000 0.28254 0.00100 0.23215 -0.72379 0.30619 0.17678
48 -0.00000 0.33333 0.39286 0.00100 0.09463 -0.54477 0.43301 0.00000
49 0.08333 0.33333 0.30010 0.00100 0.20445 -0.70053 0.37500 0.21651
50 -0.00000 0.41667 0.42672 0.00100 0.04684 -0.39635 0.48296 0.00000
51 0.08333 0.41667 0.30053 0.00100 0.14994 -0.59217 0.41826 0.24148
52 -0.00000 0.50000 0.43819 0.27990 0.01216 -0.18101 0.50000 0.00000
53 0.08333 0.50000 0.27797 0.11146 0.07998 -0.31169 0.43301 0.25000
54 -0.00000 0.58333 0.42036 0.71453 0.00746 0.06528 0.48296 0.00000
55 0.08333 0.58333 0.25398 0.77247 0.06825 0.11068 0.41826 0.24148
56 -0.00000 0.66667 0.37732 0.99900 0.03584 0.27934 0.43301 0.00000
57 0.08333 0.66667 0.24356 0.99900 0.12085 0.40243 0.37500 0.21651
58 -0.00000 0.75000 0.32156 0.99900 0.08264 0.41936 0.35355 0.00000
59 0.08333 0.75000 0.23016 0.99900 0.16764 0.51660 0.30619 0.17678
60 -0.00000 0.83333 0.26409 0.99900 0.13155 0.48413 0.25000 0.00000
61 0.08333 0.83333 0.21022 0.99900 0.19350 0.53698 0.21651 0.12500
62 -0.00000 0.91667 0.21082 0.99900 0.17434 0.49121 0.12941 0.00000
63 0.08333 0.91667 0.18721 0.99900 0.20517 0.51082 0.11207 0.06470
64 0.04167 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
SURF 0x14
mat 0
refs 4
42 -0.00000 0.16667 0.29617 0.00100 0.18165 -0.65455 0.25000 0.00000
43 -0.00000 0.08333 0.24596 0.00100 0.21392 -0.64381 0.12941 0.00000
44 0.08333 0.08333 0.22774 0.00100 0.24337 -0.66338 0.11207 0.06470
65 0.04167 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
41 0.16667 0.91667 0.15686 0.99900 0.23923 0.50697 0.06470 0.11207
165 0.12500 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
41 0.16667 0.91667 0.15686 0.99900 0.23923 0.50697 0.06470 0.11207
63 0.08333 0.91667 0.18721 0.99900 0.20517 0.51082 0.11207 0.06470
164 0.16667 0.83333 0.14064 0.99900 0.27287 0.52638 0.12500 0.21651
61 0.08333 0.83333 0.21022 0.99900 0.19350 0.53698 0.21651 0.12500
153 0.16667 0.75000 0.11005 0.99900 0.30883 0.49554 0.17678 0.30619
59 0.08333 0.75000 0.23016 0.99900 0.16764 0.51660 0.30619 0.17678
142 0.16667 0.66667 0.06221 0.99900 0.34565 0.37156 0.21651 0.37500
57 0.08333 0.66667 0.24356 0.99900 0.12085 0.40243 0.37500 0.21651
131 0.16667 0.58333 0.01707 0.75383 0.37997 0.09731 0.24148 0.41826
55 0.08333 0.58333 0.25398 0.77247 0.06825 0.11068 0.41826 0.24148
120 0.16667 0.50000 0.02917 0.16155 0.40148 -0.27285 0.25000 0.43301
53 0.08333 0.50000 0.27797 0.11146 0.07998 -0.31169 0.43301 0.25000
109 0.16667 0.41667 0.09227 0.00100 0.39866 -0.54216 0.24148 0.41826
51 0.08333 0.41667 0.30053 0.00100 0.14994 -0.59217 0.41826 0.24148
98 0.16667 0.33333 0.14840 0.00100 0.37604 -0.66637 0.21651 0.37500
49 0.08333 0.33333 0.30010 0.00100 0.20445 -0.70053 0.37500 0.21651
87 0.16667 0.25000 0.18125 0.00100 0.34374 -0.70421 0.17678 0.30619
47 0.08333 0.25000 0.28254 0.00100 0.23215 -0.72379 0.30619 0.17678
76 0.16667 0.16667 0.19643 0.00100 0.30813 -0.69579 0.12500 0.21651
45 0.08333 0.16667 0.25662 0.00100 0.24258 -0.70570 0.21651 0.12500
76 0.16667 0.16667 0.19643 0.00100 0.30813 -0.69579 0.12500 0.21651
19 0.16667 0.08333 0.20078 0.00100 0.27261 -0.65958 0.06470 0.11207
17 0.25000 0.08333 0.17478 0.00100 0.29109 -0.63431 0.00000 0.12941
20 0.20833 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
39 0.25000 0.91667 0.13138 0.99900 0.26321 0.48188 0.00000 0.12941
40 0.20833 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
39 0.25000 0.91667 0.13138 0.99900 0.26321 0.48188 0.00000 0.12941
41 0.16667 0.91667 0.15686 0.99900 0.23923 0.50697 0.06470 0.11207
163 0.25000 0.83333 0.09337 0.99900 0.32380 0.46306 0.00000 0.25000
164 0.16667 0.83333 0.14064 0.99900 0.27287 0.52638 0.12500 0.21651
152 0.25000 0.75000 0.05350 0.99900 0.38666 0.38881 0.00000 0.35355
153 0.16667 0.75000 0.11005 0.99900 0.30883 0.49554 0.17678 0.30619
141 0.25000 0.66667 0.01921 0.99900 0.44417 0.25077 0.00000 0.43301
142 0.16667 0.66667 0.06221 0.99900 0.34565 0.37156 0.21651 0.37500
130 0.25000 0.58333 0.00104 0.70147 0.48527 0.05732 0.00000 0.48296
131 0.16667 0.58333 0.01707 0.75383 0.37997 0.09731 0.24148 0.41826
119 0.25000 0.50000 0.00634 0.30861 0.50000 -0.15875 0.00000 0.50000
120 0.16667 0.50000 0.02917 0.16155 0.40148 -0.27285 0.25000 0.43301
108 0.25000 0.41667 0.03263 0.00100 0.48620 -0.35427 0.00000 0.48296
109 0.16667 0.41667 0.09227 0.00100 0.39866 -0.54216 0.24148 0.41826
97 0.25000 0.33333 0.07009 0.00100 0.45008 -0.50072 0.00000 0.43301
98 0.16667 0.33333 0.14840 0.00100 0.37604 -0.66637 0.21651 0.37500
86 0.25000 0.25000 0.10926 0.00100 0.40081 -0.59156 0.00000 0.35355
87 0.16667 0.25000 0.18125 0.00100 0.34374 -0.70421 0.17678 0.30619
75 0.25000 0.16667 0.14481 0.00100 0.34608 -0.63293 0.00000 0.25000
76 0.16667 0.16667 0.19643 0.00100 0.30813 -0.69579 0.12500 0.21651
75 0.25000 0.16667 0.14481 0.00100 0.34608 -0.63293 0.00000 0.25000
17 0.25000 0.08333 0.17478 0.00100 0.29109 -0.63431 0.00000 0.12941
15 0.33333 0.08333 0.15726 0.00100 0.29335 -0.59942 -0.06470 0.11207
18 0.29167 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
37 0.33333 0.91667 0.11731 0.99900 0.26926 0.44859 -0.06470 0.11207
38 0.29167 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
37 0.33333 0.91667 0.11731 0.99900 0.26926 0.44859 -0.06470 0.11207
39 0.25000 0.91667 0.13138 0.99900 0.26321 0.48188 0.00000 0.12941
162 0.33333 0.83333 0.07414 0.99900 0.32883 0.39669 -0.12500 0.21651
163 0.25000 0.83333 0.09337 0.99900 0.32380 0.46306 0.00000 0.25000
151 0.33333 0.75000 0.03873 0.99900 0.38213 0.30552 -0.17678 0.30619
152 0.25000 0.75000 0.05350 0.99900 0.38666 0.38881 0.00000 0.35355
140 0.33333 0.66667 0.01433 0.96962 0.42405 0.18283 -0.21651 0.37500
141 0.25000 0.66667 0.01921 0.99900 0.44417 0.25077 0.00000 0.43301
129 0.33333 0.58333 0.00283 0.67965 0.45074 0.03994 -0.24148 0.41826
130 0.25000 0.58333 0.00104 0.70147 0.48527 0.05732 0.00000 0.48296
118 0.33333 0.50000 0.00464 0.37108 0.46020 -0.11023 -0.25000 0.43301
119 0.25000 0.50000 0.00634 0.30861 0.50000 -0.15875 0.00000 0.50000
107 0.33333 0.41667 0.01889 0.06946 0.45233 -0.25504 -0.24148 0.41826
108 0.25000 0.41667 0.03263 0.00100 0.48620 -0.35427 0.00000 0.48296
96 0.33333 0.33333 0.04378 0.00100 0.42865 -0.38353 -0.21651 0.37500
97 0.25000 0.33333 0.07009 0.00100 0.45008 -0.50072 0.00000 0.43301
85 0.33333 0.25000 0.07694 0.00100 0.39190 -0.48717 -0.17678 0.30619
86 0.25000 0.25000 0.10926 0.00100 0.40081 -0.59156 0.00000 0.35355
74 0.33333 0.16667 0.11569 0.00100 0.34553 -0.56015 -0.12500 0.21651
75 0.25000 0.16667 0.14481 0.00100 0.34608 -0.63293 0.00000 0.25000
74 0.33333 0.16667 0.11569 0.00100 0.34553 -0.56015 -0.12500 0.21651
15 0.33333 0.08333 0.15726 0.00100 0.29335 -0.59942 -0.06470 0.11207
13 0.41667 0.08333 0.15134 0.00100 0.28069 -0.56690 -0.11207 0.06470
16 0.37500 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
35 0.41667 0.91667 0.11568 0.99900 0.25826 0.41884 -0.11207 0.06470
36 0.37500 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
35 0.41667 0.91667 0.11568 0.99900 0.25826 0.41884 -0.11207 0.06470
37 0.33333 0.91667 0.11731 0.99900 0.26926 0.44859 -0.06470 0.11207
161 0.41667 0.83333 0.07575 0.99900 0.30096 0.34871 -0.21651 0.12500
162 0.33333 0.83333 0.07414 0.99900 0.32883 0.39669 -0.12500 0.21651
150 0.41667 0.75000 0.04562 0.99900 0.33524 0.25608 -0.30619 0.17678
151 0.33333 0.75000 0.03873 0.99900 0.38213 0.30552 -0.17678 0.30619
139 0.41667 0.66667 0.02569 0.92724 0.36024 0.14834 -0.37500 0.21651
140 0.33333 0.66667 0.01433 0.96962 0.42405 0.18283 -0.21651 0.37500
128 0.41667 0.58333 0.01596 0.67063 0.37568 0.03187 -0.41826 0.24148
129 0.33333 0.58333 0.00283 0.67965 0.45074 0.03994 -0.24148 0.41826
117 0.41667 0.50000 0.01621 0.39994 0.38162 -0.08785 -0.43301 0.25000
118 0.33333 0.50000 0.00464 0.37108 0.46020 -0.11023 -0.25000 0.43301
106 0.41667 0.41667 0.02609 0.13144 0.37828 -0.20590 -0.41826 0.24148
107 0.33333 0.41667 0.01889 0.06946 0.45233 -0.25504 -0.24148 0.41826
95 0.41667 0.33333 0.04522 0.00100 0.36600 -0.31762 -0.37500 0.21651
96 0.33333 0.33333 0.04378 0.00100 0.42865 -0.38353 -0.21651 0.37500
84 0.41667 0.25000 0.07305 0.00100 0.34519 -0.41833 -0.30619 0.17678
85 0.33333 0.25000 0.07694 0.00100 0.39190 -0.48717 -0.17678 0.30619
73 0.41667 0.16667 0.10881 0.00100 0.31647 -0.50313 -0.21651 0.12500
74 0.33333 0.16667 0.11569 0.00100 0.34553 -0.56015 -0.12500 0.21651
73 0.41667 0.16667 0.10881 0.00100 0.31647 -0.50313 -0.21651 0.12500
13 0.41667 0.08333 0.15134 0.00100 0.28069 -0.56690 -0.11207 0.06470
11 0.50000 0.08333 0.15695 0.00100 0.25836 -0.54379 -0.12941 0.00000
14 0.45833 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
33 0.50000 0.91667 0.12506 0.99900 0.23590 0.39836 -0.12941 0.00000
34 0.45833 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
33 0.50000 0.91667 0.12506 0.99900 0.23590 0.39836 -0.12941 0.00000
35 0.41667 0.91667 0.11568 0.99900 0.25826 0.41884 -0.11207 0.06470
160 0.50000 0.83333 0.09377 0.99900 0.25637 0.32013 -0.25000 0.00000
161 0.41667 0.83333 0.07575 0.99900 0.30096 0.34871 -0.21651 0.12500
149 0.50000 0.75000 0.07035 0.99900 0.27148 0.22961 -0.35355 0.00000
150 0.41667 0.75000 0.04562 0.99900 0.33524 0.25608 -0.30619 0.17678
138 0.50000 0.66667 0.05477 0.90616 0.28211 0.13113 -0.43301 0.00000
139 0.41667 0.66667 0.02569 0.92724 0.36024 0.14834 -0.37500 0.21651
127 0.50000 0.58333 0.04697 0.66642 0.28889 0.02798 -0.48296 0.00000
128 0.41667 0.58333 0.01596 0.67063 0.37568 0.03187 -0.41826 0.24148
116 0.50000 0.50000 0.04685 0.41393 0.29223 -0.07709 -0.50000 0.00000
117 0.41667 0.50000 0.01621 0.39994 0.38162 -0.08785 -0.43301 0.25000
105 0.50000 0.41667 0.05433 0.16212 0.29232 -0.18164 -0.48296 0.00000
106 0.41667 0.41667 0.02609 0.13144 0.37828 -0.20590 -0.41826 0.24148
94 0.50000 0.33333 0.06929 0.00100 0.28922 -0.28327 -0.43301 0.00000
95 0.41667 0.33333 0.04522 0.00100 0.36600 -0.31762 -0.37500 0.21651
83 0.50000 0.25000 0.09157 0.00100 0.28277 -0.37947 -0.35355 0.00000
84 0.41667 0.25000 0.07305 0.00100 0.34519 -0.41833 -0.30619 0.17678
72 0.50000 0.16667 0.12093 0.00100 0.27266 -0.46743 -0.25000 0.00000
73 0.41667 0.16667 0.10881 0.00100 0.31647 -0.50313 -0.21651 0.12500
72 0.50000 0.16667 0.12093 0.00100 0.27266 -0.46743 -0.25000 0.00000
11 0.50000 0.08333 0.15695 0.00100 0.25836 -0.54379 -0.12941 0.00000
9 0.58333 0.08333 0.17221 0.00100 0.23253 -0.53297 -0.11207 -0.06470
12 0.54167 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
31 0.58333 0.91667 0.14311 0.99900 0.20878 0.38894 -0.11207 -0.06470
32 0.54167 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
31 0.58333 0.91667 0.14311 0.99900 0.20878 0.38894 -0.11207 -0.06470
33 0.50000 0.91667 0.12506 0.99900 0.23590 0.39836 -0.12941 0.00000
159 0.58333 0.83333 0.12527 0.99900 0.20699 0.30801 -0.21651 -0.12500
160 0.50000 0.83333 0.09377 0.99900 0.25637 0.32013 -0.25000 0.00000
148 0.58333 0.75000 0.11143 0.99900 0.20500 0.21899 -0.30619 -0.17678
149 0.50000 0.75000 0.07035 0.99900 0.27148 0.22961 -0.35355 0.00000
137 0.58333 0.66667 0.10210 0.89651 0.20368 0.12444 -0.37500 -0.21651
138 0.50000 0.66667 0.05477 0.90616 0.28211 0.13113 -0.43301 0.00000
126 0.58333 0.58333 0.09758 0.66389 0.20355 0.02650 -0.41826 -0.24148
127 0.50000 0.58333 0.04697 0.66642 0.28889 0.02798 -0.48296 0.00000
115 0.58333 0.50000 0.09802 0.41933 0.20491 -0.07299 -0.43301 -0.25000
116 0.50000 0.50000 0.04685 0.41393 0.29223 -0.07709 -0.50000 0.00000
104 0.58333 0.41667 0.10346 0.17498 0.20788 -0.17229 -0.41826 -0.24148
105 0.50000 0.41667 0.05433 0.16212 0.29232 -0.18164 -0.48296 0.00000
93 0.58333 0.33333 0.11385 0.00100 0.21242 -0.26969 -0.37500 -0.21651
94 0.50000 0.33333 0.06929 0.00100 0.28922 -0.28327 -0.43301 0.00000
82 0.58333 0.25000 0.12901 0.00100 0.21834 -0.36350 -0.30619 -0.17678
83 0.50000 0.25000 0.09157 0.00100 0.28277 -0.37947 -0.35355 0.00000
71 0.58333 0.16667 0.14863 0.00100 0.22526 -0.45191 -0.21651 -0.12500
72 0.50000 0.16667 0.12093 0.00100 0.27266 -0.46743 -0.25000 0.00000
71 0.58333 0.16667 0.14863 0.00100 0.22526 -0.45191 -0.21651 -0.12500
9 0.58333 0.08333 0.17221 0.00100 0.23253 -0.53297 -0.11207 -0.06470
7 0.66667 0.08333 0.19399 0.00100 0.20888 -0.53519 -0.06470 -0.11207
10 0.62500 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
29 0.66667 0.91667 0.16656 0.99900 0.18279 0.39086 -0.06470 -0.11207
30 0.62500 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
29 0.66667 0.91667 0.16656 0.99900 0.18279 0.39086 -0.06470 -0.11207
31 0.58333 0.91667 0.14311 0.99900 0.20878 0.38894 -0.11207 -0.06470
158 0.66667 0.83333 0.16659 0.99900 0.16130 0.31057 -0.12500 -0.21651
159 0.58333 0.83333 0.12527 0.99900 0.20699 0.30801 -0.21651 -0.12500
147 0.66667 0.75000 0.16588 0.99900 0.14487 0.22131 -0.17678 -0.30619
148 0.58333 0.75000 0.11143 0.99900 0.20500 0.21899 -0.30619 -0.17678
136 0.66667 0.66667 0.16546 0.89633 0.13378 0.12594 -0.21651 -0.37500
137 0.58333 0.66667 0.10210 0.89651 0.20368 0.12444 -0.37500 -0.21651
125 0.66667 0.58333 0.16597 0.66293 0.12819 0.02683 -0.24148 -0.41826
126 0.58333 0.58333 0.09758 0.66389 0.20355 0.02650 -0.41826 -0.24148
114 0.66667 0.50000 0.16776 0.41811 0.12818 -0.07393 -0.25000 -0.43301
115 0.58333 0.50000 0.09802 0.41933 0.20491 -0.07299 -0.43301 -0.25000
103 0.66667 0.41667 0.17097 0.17362 0.13376 -0.17442 -0.24148 -0.41826
104 0.58333 0.41667 0.10346 0.17498 0.20788 -0.17229 -0.41826 -0.24148
92 0.66667 0.33333 0.17556 0.00100 0.14484 -0.27274 -0.21651 -0.37500
93 0.58333 0.33333 0.11385 0.00100 0.21242 -0.26969 -0.37500 -0.21651
81 0.66667 0.25000 0.18129 0.00100 0.16125 -0.36700 -0.17678 -0.30619
82 0.58333 0.25000 0.12901 0.00100 0.21834 -0.36350 -0.30619 -0.17678
70 0.66667 0.16667 0.18769 0.00100 0.18273 -0.45521 -0.12500 -0.21651
71 0.58333 0.16667 0.14863 0.00100 0.22526 -0.45191 -0.21651 -0.12500
70 0.66667 0.16667 0.18769 0.00100 0.18273 -0.45521 -0.12500 -0.21651
7 0.66667 0.08333 0.19399 0.00100 0.20888 -0.53519 -0.06470 -0.11207
5 0.75000 0.08333 0.21789 0.00100 0.19222 -0.55023 0.00000 -0.12941
8 0.70833 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
27 0.75000 0.91667 0.19095 0.99900 0.16283 0.40401 0.00000 -0.12941
28 0.70833 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
27 0.75000 0.91667 0.19095 0.99900 0.16283 0.40401 0.00000 -0.12941
29 0.66667 0.91667 0.16656 0.99900 0.18279 0.39086 -0.06470 -0.11207
157 0.75000 0.83333 0.21201 0.99900 0.12561 0.32796 0.00000 -0.25000
158 0.66667 0.83333 0.16659 0.99900 0.16130 0.31057 -0.12500 -0.21651
146 0.75000 0.75000 0.22797 0.99900 0.09754 0.23688 0.00000 -0.35355
147 0.66667 0.75000 0.16588 0.99900 0.14487 0.22131 -0.17678 -0.30619
135 0.75000 0.66667 0.23948 0.90806 0.07868 0.13588 0.00000 -0.43301
136 0.66667 0.66667 0.16546 0.89633 0.13378 0.12594 -0.21651 -0.37500
124 0.75000 0.58333 0.24702 0.66503 0.06897 0.02906 0.00000 -0.48296
125 0.66667 0.58333 0.16597 0.66293 0.12819 0.02683 -0.24148 -0.41826
113 0.75000 0.50000 0.25094 0.41006 0.06830 -0.08009 0.00000 -0.50000
114 0.66667 0.50000 0.16776 0.41811 0.12818 -0.07393 -0.25000 -0.43301
102 0.75000 0.41667 0.25144 0.15617 0.07651 -0.18841 0.00000 -0.48296
103 0.66667 0.41667 0.17097 0.17362 0.13376 -0.17442 -0.24148 -0.41826
91 0.75000 0.33333 0.24857 0.00100 0.09338 -0.29285 0.00000 -0.43301
92 0.66667 0.33333 0.17556 0.00100 0.14484 -0.27274 -0.21651 -0.37500
80 0.75000 0.25000 0.24221 0.00100 0.11860 -0.39028 0.00000 -0.35355
81 0.66667 0.25000 0.18129 0.00100 0.16125 -0.36700 -0.17678 -0.30619
69 0.75000 0.16667 0.23212 0.00100 0.15175 -0.47734 0.00000 -0.25000
70 0.66667 0.16667 0.18769 0.00100 0.18273 -0.45521 -0.12500 -0.21651
69 0.75000 0.16667 0.23212 0.00100 0.15175 -0.47734 0.00000 -0.25000
5 0.75000 0.08333 0.21789 0.00100 0.19222 -0.55023 0.00000 -0.12941
3 0.83333 0.08333 0.23838 0.00100 0.18630 -0.57670 0.06470 -0.11207
6 0.79167 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
25 0.83333 0.91667 0.21053 0.99900 0.15290 0.42768 0.06470 -0.11207
26 0.79167 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
25 0.83333 0.91667 0.21053 0.99900 0.15290 0.42768 0.06470 -0.11207
27 0.75000 0.91667 0.19095 0.99900 0.16283 0.40401 0.00000 -0.12941
156 0.83333 0.83333 0.25271 0.99900 0.10497 0.36222 0.12500 -0.21651
157 0.75000 0.83333 0.21201 0.99900 0.12561 0.32796 0.00000 -0.25000
145 0.83333 0.75000 0.28799 0.99900 0.06767 0.26941 0.17678 -0.30619
146 0.75000 0.75000 0.22797 0.99900 0.09754 0.23688 0.00000 -0.35355
134 0.83333 0.66667 0.31457 0.93678 0.04237 0.15738 0.21651 -0.37500
135 0.75000 0.66667 0.23948 0.90806 0.07868 0.13588 0.00000 -0.43301
123 0.83333 0.58333 0.33150 0.67193 0.02955 0.03395 0.24148 -0.41826
124 0.75000 0.58333 0.24702 0.66503 0.06897 0.02906 0.00000 -0.48296
112 0.83333 0.50000 0.33844 0.39249 0.02914 -0.09363 0.25000 -0.43301
113 0.75000 0.50000 0.25094 0.41006 0.06830 -0.08009 0.00000 -0.50000
101 0.83333 0.41667 0.33549 0.11627 0.04068 -0.21875 0.24148 -0.41826
102 0.75000 0.41667 0.25144 0.15617 0.07651 -0.18841 0.00000 -0.48296
90 0.83333 0.33333 0.32310 0.00100 0.06342 -0.33527 0.21651 -0.37500
91 0.75000 0.33333 0.24857 0.00100 0.09338 -0.29285 0.00000 -0.43301
79 0.83333 0.25000 0.30202 0.00100 0.09629 -0.43738 0.17678 -0.30619
80 0.75000 0.25000 0.24221 0.00100 0.11860 -0.39028 0.00000 -0.35355
68 0.83333 0.16667 0.27332 0.00100 0.13788 -0.51956 0.12500 -0.21651
69 0.75000 0.16667 0.23212 0.00100 0.15175 -0.47734 0.00000 -0.25000
68 0.83333 0.16667 0.27332 0.00100 0.13788 -0.51956 0.12500 -0.21651
3 0.83333 0.08333 0.23838 0.00100 0.18630 -0.57670 0.06470 -0.11207
0 0.91667 0.08333 0.24936 0.00100 0.19351 -0.61071 0.11207 -0.06470
4 0.87500 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 26
23 0.91667 0.91667 0.21882 0.99900 0.15617 0.45920 0.11207 -0.06470
24 0.87500 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
23 0.91667 0.91667 0.21882 0.99900 0.15617 0.45920 0.11207 -0.06470
25 0.83333 0.91667 0.21053 0.99900 0.15290 0.42768 0.06470 -0.11207
154 0.91667 0.83333 0.27563 0.99900 0.10447 0.41577 0.21651 -0.12500
156 0.83333 0.83333 0.25271 0.99900 0.10497 0.36222 0.12500 -0.21651
143 0.91667 0.75000 0.32918 0.99900 0.05945 0.32703 0.30619 -0.17678
145 0.83333 0.75000 0.28799 0.99900 0.06767 0.26941 0.17678 -0.30619
132 0.91667 0.66667 0.37332 0.99232 0.02664 0.19879 0.37500 -0.21651
134 0.83333 0.66667 0.31457 0.93678 0.04237 0.15738 0.21651 -0.37500
121 0.91667 0.58333 0.40266 0.68601 0.01006 0.04379 0.41826 -0.24148
123 0.83333 0.58333 0.33150 0.67193 0.02955 0.03395 0.24148 -0.41826
110 0.91667 0.50000 0.41387 0.35730 0.01120 -0.12091 0.43301 -0.25000
112 0.83333 0.50000 0.33844 0.39249 0.02914 -0.09363 0.25000 -0.43301
99 0.91667 0.41667 0.40641 0.03864 0.02889 -0.27785 0.41826 -0.24148
101 0.83333 0.41667 0.33549 0.11627 0.04068 -0.21875 0.24148 -0.41826
88 0.91667 0.33333 0.38226 0.00100 0.06003 -0.41261 0.37500 -0.21651
90 0.83333 0.33333 0.32310 0.00100 0.06342 -0.33527 0.21651 -0.37500
77 0.91667 0.25000 0.34511 0.00100 0.10054 -0.51553 0.30619 -0.17678
79 0.83333 0.25000 0.30202 0.00100 0.09629 -0.43738 0.17678 -0.30619
66 0.91667 0.16667 0.29935 0.00100 0.14628 -0.58181 0.21651 -0.12500
68 0.83333 0.16667 0.27332 0.00100 0.13788 -0.51956 0.12500 -0.21651
66 0.91667 0.16667 0.29935 0.00100 0.14628 -0.58181 0.21651 -0.12500
0 0.91667 0.08333 0.24936 0.00100 0.19351 -0.61071 0.11207 -0.06470
2 1.00000 0.08333 0.24596 0.00100 0.21392 -0.64381 0.12941 0.00000
1 0.95833 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
SURF 0x14
mat 0
refs 23
66 0.91667 0.16667 0.29935 0.00100 0.14628 -0.58181 0.21651 -0.12500
2 1.00000 0.08333 0.24596 0.00100 0.21392 -0.64381 0.12941 0.00000
66 0.91667 0.16667 0.29935 0.00100 0.14628 -0.58181 0.21651 -0.12500
67 1.00000 0.16667 0.29617 0.00100 0.18165 -0.65455 0.25000 0.00000
77 0.91667 0.25000 0.34511 0.00100 0.10054 -0.51553 0.30619 -0.17678
78 1.00000 0.25000 0.34675 0.00100 0.14154 -0.62617 0.35355 0.00000
88 0.91667 0.33333 0.38226 0.00100 0.06003 -0.41261 0.37500 -0.21651
89 1.00000 0.33333 0.39286 0.00100 0.09463 -0.54477 0.43301 0.00000
99 0.91667 0.41667 0.40641 0.03864 0.02889 -0.27785 0.41826 -0.24148
100 1.00000 0.41667 0.42672 0.00100 0.04684 -0.39635 0.48296 0.00000
110 0.91667 0.50000 0.41387 0.35730 0.01120 -0.12091 0.43301 -0.25000
111 1.00000 0.50000 0.43819 0.27990 0.01216 -0.18101 0.50000 0.00000
121 0.91667 0.58333 0.40266 0.68601 0.01006 0.04379 0.41826 -0.24148
122 1.00000 0.58333 0.42036 0.71453 0.00746 0.06528 0.48296 0.00000
132 0.91667 0.66667 0.37332 0.99232 0.02664 0.19879 0.37500 -0.21651
133 1.00000 0.66667 0.37732 0.99900 0.03584 0.27934 0.43301 0.00000
143 0.91667 0.75000 0.32918 0.99900 0.05945 0.32703 0.30619 -0.17678
144 1.00000 0.75000 0.32156 0.99900 0.08264 0.41936 0.35355 0.00000
154 0.91667 0.83333 0.27563 0.99900 0.10447 0.41577 0.21651 -0.12500
155 1.00000 0.83333 0.26409 0.99900 0.13155 0.48413 0.25000 0.00000
23 0.91667 0.91667 0.21882 0.99900 0.15617 0.45920 0.11207 -0.06470
21 1.00000 0.91667 0.21082 0.99900 0.17434 0.49121 0.12941 0.00000
22 0.95833 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
kids 0

View File

@ -32,7 +32,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="textures/editor_defaults/default_texture.png" />
<texture name="Texture1" value="assets/default_texture.png" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -89,7 +89,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="skybox/default_skybox2.jpg" />
<texture name="Texture1" value="assets/skybox/default_skybox2.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -128,7 +128,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="skybox/default_skybox1.jpg" />
<texture name="Texture1" value="assets/skybox/default_skybox1.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -167,7 +167,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="skybox/default_skybox0.jpg" />
<texture name="Texture1" value="assets/skybox/default_skybox0.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -206,7 +206,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="skybox/default_skybox3.jpg" />
<texture name="Texture1" value="assets/skybox/default_skybox3.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -245,7 +245,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="skybox/default_skyboxup.jpg" />
<texture name="Texture1" value="assets/skybox/default_skyboxup.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -284,7 +284,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="skybox/default_skyboxdn.jpg" />
<texture name="Texture1" value="assets/skybox/default_skyboxdn.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -329,7 +329,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="Looping" value="true" />
<bool name="ReadOnlyMaterials" value="false" />
<float name="FramesPerSecond" value="0.250000" />
@ -345,7 +345,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -384,7 +384,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -468,7 +468,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="Looping" value="true" />
<bool name="ReadOnlyMaterials" value="false" />
<float name="FramesPerSecond" value="0.250000" />
@ -484,7 +484,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -523,7 +523,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -620,7 +620,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="textures/editor_defaults/default_texture.png" />
<texture name="Texture1" value="assets/default_texture.png" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -678,7 +678,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="textures/editor_defaults/default_texture.png" />
<texture name="Texture1" value="assets/default_texture.png" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -723,7 +723,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="Looping" value="true" />
<bool name="ReadOnlyMaterials" value="false" />
<float name="FramesPerSecond" value="0.250000" />
@ -739,7 +739,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -778,7 +778,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -875,7 +875,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="textures/editor_defaults/default_texture.png" />
<texture name="Texture1" value="assets/default_texture.png" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -920,7 +920,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="Looping" value="true" />
<bool name="ReadOnlyMaterials" value="false" />
<float name="FramesPerSecond" value="0.250000" />
@ -936,7 +936,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -975,7 +975,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />

View File

@ -33,8 +33,8 @@
<float name="Shininess" value="0.750000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="brownground_1-1.jpg" />
<texture name="Texture2" value="1.png" />
<texture name="Texture1" value="assets/brownground_1-1.jpg" />
<texture name="Texture2" value="assets/1.png" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
<bool name="Wireframe" value="false" />
@ -72,8 +72,8 @@
<float name="Shininess" value="0.750000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="crackedground_1-6.jpg" />
<texture name="Texture2" value="1.png" />
<texture name="Texture1" value="assets/crackedground_1-6.jpg" />
<texture name="Texture2" value="assets/1.png" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
<bool name="Wireframe" value="false" />
@ -117,7 +117,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="ReadOnlyMaterials" value="false" />
</attributes>
@ -131,7 +131,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -170,7 +170,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -254,7 +254,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="ReadOnlyMaterials" value="false" />
</attributes>
@ -268,7 +268,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -307,7 +307,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -391,7 +391,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="ReadOnlyMaterials" value="false" />
</attributes>
@ -405,7 +405,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -444,7 +444,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -528,7 +528,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="ReadOnlyMaterials" value="false" />
</attributes>
@ -542,7 +542,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -581,7 +581,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -665,7 +665,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="ReadOnlyMaterials" value="false" />
</attributes>
@ -679,7 +679,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -718,7 +718,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />

View File

@ -19,7 +19,7 @@
<enum name="AutomaticCulling" value="box" />
<int name="DebugDataVisible" value="0" />
<bool name="IsDebugObject" value="false" />
<string name="Mesh" value="dwarf.x" />
<string name="Mesh" value="assets/dwarf.x" />
<bool name="Looping" value="true" />
<bool name="ReadOnlyMaterials" value="false" />
<float name="FramesPerSecond" value="0.025000" />
@ -35,7 +35,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="axe.jpg" />
<texture name="Texture1" value="assets/axe.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />
@ -73,7 +73,7 @@
<float name="Shininess" value="0.000000" />
<float name="Param1" value="0.000000" />
<float name="Param2" value="0.000000" />
<texture name="Texture1" value="dwarf.jpg" />
<texture name="Texture1" value="assets/dwarf.jpg" />
<texture name="Texture2" value="" />
<texture name="Texture3" value="" />
<texture name="Texture4" value="" />

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

View File

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 199 KiB

View File

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

Before

Width:  |  Height:  |  Size: 412 KiB

After

Width:  |  Height:  |  Size: 412 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,11 @@
This skybox is basing on a skydome texture from
http://mikepan.homeip.net/earth
Downloaded November 22th, 08
Distribution note:
"These royalty-free skydome textures work best when applied to a sphere or hemisphere"
Thanks for your great work!

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Some files were not shown because too many files have changed in this diff Show More