From 457dff1bf103617f0ec643dff8b37392eb0e7679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20D=C3=A4hne?= Date: Tue, 11 Jul 2017 19:28:40 +0200 Subject: [PATCH 1/6] X3D importer: Implemented support for binary X3D files --- code/CMakeLists.txt | 3 + code/FIReader.cpp | 1818 +++++++++++++++++++++++++++++++ code/FIReader.hpp | 171 +++ code/X3DImporter.cpp | 324 +++--- code/X3DImporter.hpp | 32 +- code/X3DImporter_Geometry3D.cpp | 22 +- code/X3DImporter_Metadata.cpp | 16 +- code/X3DImporter_Node.hpp | 27 +- code/X3DImporter_Rendering.cpp | 44 +- code/X3DVocabulary.cpp | 1675 ++++++++++++++++++++++++++++ 10 files changed, 3866 insertions(+), 266 deletions(-) create mode 100755 code/FIReader.cpp create mode 100644 code/FIReader.hpp mode change 100644 => 100755 code/X3DImporter.cpp create mode 100644 code/X3DVocabulary.cpp diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 82497467a..0477f5fef 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -647,6 +647,9 @@ ADD_ASSIMP_IMPORTER(X3D X3DImporter_Rendering.cpp X3DImporter_Shape.cpp X3DImporter_Texturing.cpp + FIReader.hpp + FIReader.cpp + X3DVocabulary.cpp ) ADD_ASSIMP_IMPORTER( GLTF diff --git a/code/FIReader.cpp b/code/FIReader.cpp new file mode 100755 index 000000000..617c87be6 --- /dev/null +++ b/code/FIReader.cpp @@ -0,0 +1,1818 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/// \file FIReader.cpp +/// \brief Reader for Fast Infoset encoded binary XML files. +/// \date 2017 +/// \author Patrick Daehne + +#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER + +#include "FIReader.hpp" +#include "Exceptional.h" +#include +#include +#include "MemoryIOWrapper.h" +#include "irrXMLWrapper.h" +#include "../contrib/utf8cpp/source/utf8.h" +#include +#include +#include +#include +#include + +namespace Assimp { + +static const std::string parseErrorMessage = "Fast Infoset parse error"; + +static const char *xmlDeclarations[] = { + "", + "", + "", + "", + "", + "", + "", + "", + "" +}; + +static size_t parseMagic(const uint8_t *data, const uint8_t *dataEnd) { + if (dataEnd - data < 4) { + return 0; + } + uint32_t magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + switch (magic) { + case 0xe0000001: + return 4; + case 0x3c3f786d: // "= xmlDeclarationLength) && (memcmp(xmlDeclaration, data, xmlDeclarationLength) == 0)) { + data += xmlDeclarationLength; + if (dataEnd - data < 4) { + return 0; + } + magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + return magic == 0xe0000001 ? xmlDeclarationLength + 4 : 0; + } + } + return 0; + } + default: + return 0; + } +} + +static std::string parseUTF8String(const uint8_t *data, size_t len) { + return std::string((char*)data, len); +} + +static std::string parseUTF16String(const uint8_t *data, size_t len) { + if (len & 1) { + throw DeadlyImportError(parseErrorMessage); + } + size_t numShorts = len / 2; + std::vector utf16; + utf16.reserve(numShorts); + for (size_t i = 0; i < numShorts; ++i) { + short v = (data[0] << 8) | data[1]; + utf16.push_back(v); + data += 2; + } + std::string result; + utf8::utf16to8(utf16.begin(), utf16.end(), back_inserter(result)); + return result; +} + +struct FIStringValueImpl: public FIStringValue { + inline FIStringValueImpl(std::string &&value_) { value = std::move(value_); } + virtual const std::string &toString() const override { return value; } +}; + +std::shared_ptr FIStringValue::create(std::string &&value) { + return std::make_shared(std::move(value)); +} + +struct FIHexValueImpl: public FIHexValue { + mutable std::string strValue; + mutable bool strValueValid; + inline FIHexValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + os << std::hex << std::uppercase << std::setfill('0'); + std::for_each(value.begin(), value.end(), [&](uint8_t c) { os << std::setw(2) << static_cast(c); }); + strValue = os.str(); + } + return strValue; + }; +}; + +std::shared_ptr FIHexValue::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FIBase64ValueImpl: public FIBase64Value { + mutable std::string strValue; + mutable bool strValueValid; + inline FIBase64ValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + uint8_t c1, c2; + int imod3 = 0; + auto valueSize = value.size(); + for (auto i = 0; i < valueSize; ++i) { + c2 = value[i]; + switch (imod3) { + case 0: + os << basis_64[c2 >> 2]; + imod3 = 1; + break; + case 1: + os << basis_64[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)]; + imod3 = 2; + break; + case 2: + os << basis_64[((c1 & 0x0f) << 2) | ((c2 & 0xc0) >> 6)] << basis_64[c2 & 0x3f]; + imod3 = 0; + break; + } + c1 = c2; + } + switch (imod3) { + case 1: + os << basis_64[(c1 & 0x03) << 4] << "=="; + break; + case 2: + os << basis_64[(c1 & 0x0f) << 2] << '='; + break; + } + strValue = os.str(); + } + return strValue; + }; + static const char basis_64[]; +}; + +const char FIBase64ValueImpl::basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +std::shared_ptr FIBase64Value::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FIShortValueImpl: public FIShortValue { + mutable std::string strValue; + mutable bool strValueValid; + inline FIShortValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + int n = 0; + std::for_each(value.begin(), value.end(), [&](int16_t s) { if (++n > 1) os << ' '; os << s; }); + strValue = os.str(); + } + return strValue; + } +}; + +std::shared_ptr FIShortValue::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FIIntValueImpl: public FIIntValue { + mutable std::string strValue; + mutable bool strValueValid; + inline FIIntValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + int n = 0; + std::for_each(value.begin(), value.end(), [&](int32_t i) { if (++n > 1) os << ' '; os << i; }); + strValue = os.str(); + } + return strValue; + }; +}; + +std::shared_ptr FIIntValue::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FILongValueImpl: public FILongValue { + mutable std::string strValue; + mutable bool strValueValid; + inline FILongValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + int n = 0; + std::for_each(value.begin(), value.end(), [&](int64_t l) { if (++n > 1) os << ' '; os << l; }); + strValue = os.str(); + } + return strValue; + }; +}; + +std::shared_ptr FILongValue::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FIBoolValueImpl: public FIBoolValue { + mutable std::string strValue; + mutable bool strValueValid; + inline FIBoolValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + os << std::boolalpha; + int n = 0; + std::for_each(value.begin(), value.end(), [&](bool b) { if (++n > 1) os << ' '; os << b; }); + strValue = os.str(); + } + return strValue; + }; +}; + +std::shared_ptr FIBoolValue::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FIFloatValueImpl: public FIFloatValue { + mutable std::string strValue; + mutable bool strValueValid; + inline FIFloatValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + int n = 0; + std::for_each(value.begin(), value.end(), [&](float f) { if (++n > 1) os << ' '; os << f; }); + strValue = os.str(); + } + return strValue; + } +}; + +std::shared_ptr FIFloatValue::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FIDoubleValueImpl: public FIDoubleValue { + mutable std::string strValue; + mutable bool strValueValid; + inline FIDoubleValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + int n = 0; + std::for_each(value.begin(), value.end(), [&](double d) { if (++n > 1) os << ' '; os << d; }); + strValue = os.str(); + } + return strValue; + } +}; + +std::shared_ptr FIDoubleValue::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FIUUIDValueImpl: public FIUUIDValue { + mutable std::string strValue; + mutable bool strValueValid; + inline FIUUIDValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } + virtual const std::string &toString() const override { + if (!strValueValid) { + strValueValid = true; + std::ostringstream os; + os << std::hex << std::uppercase << std::setfill('0'); + auto valueSize = value.size(); + for (auto i = 0; i < valueSize; ++i) { + switch (i & 15) { + case 0: + if (i > 0) { + os << ' '; + } + os << std::setw(2) << static_cast(value[i]); + break; + case 4: + case 6: + case 8: + case 10: + os << '-'; + // intentionally fall through! + case 1: + case 2: + case 3: + case 5: + case 7: + case 9: + case 11: + case 12: + case 13: + case 14: + case 15: + os << std::setw(2) << static_cast(value[i]); + break; + } + } + strValue = os.str(); + } + return strValue; + }; +}; + +std::shared_ptr FIUUIDValue::create(std::vector &&value) { + return std::make_shared(std::move(value)); +} + +struct FICDATAValueImpl: public FICDATAValue { + inline FICDATAValueImpl(std::string &&value_) { value = std::move(value_); } + virtual const std::string &toString() const override { return value; } +}; + +std::shared_ptr FICDATAValue::create(std::string &&value) { + return std::make_shared(std::move(value)); +} + +struct FIHexDecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + return FIHexValue::create(std::vector(data, data + len)); + } +}; + +struct FIBase64Decoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + return FIBase64Value::create(std::vector(data, data + len)); + } +}; + +struct FIShortDecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + if (len & 1) { + throw DeadlyImportError(parseErrorMessage); + } + std::vector value; + size_t numShorts = len / 2; + value.reserve(numShorts); + for (size_t i = 0; i < numShorts; ++i) { + int16_t v = (data[0] << 8) | data[1]; + value.push_back(v); + data += 2; + } + return FIShortValue::create(std::move(value)); + } +}; + +struct FIIntDecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + if (len & 3) { + throw DeadlyImportError(parseErrorMessage); + } + std::vector value; + size_t numInts = len / 4; + value.reserve(numInts); + for (size_t i = 0; i < numInts; ++i) { + int32_t v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + value.push_back(v); + data += 4; + } + return FIIntValue::create(std::move(value)); + } +}; + +struct FILongDecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + if (len & 7) { + throw DeadlyImportError(parseErrorMessage); + } + std::vector value; + size_t numLongs = len / 8; + value.reserve(numLongs); + for (size_t i = 0; i < numLongs; ++i) { + int64_t b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7]; + int64_t v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; + value.push_back(v); + data += 8; + } + return FILongValue::create(std::move(value)); + } +}; + +struct FIBoolDecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + if (len < 1) { + throw DeadlyImportError(parseErrorMessage); + } + std::vector value; + uint8_t b = *data++; + size_t unusedBits = b >> 4; + size_t numBools = (len * 8) - 4 - unusedBits; + value.reserve(numBools); + uint8_t mask = 1 << 3; + for (size_t i = 0; i < numBools; ++i) { + if (!mask) { + mask = 1 << 7; + b = *data++; + } + value.push_back((b & mask) != 0); + } + return FIBoolValue::create(std::move(value)); + } +}; + +struct FIFloatDecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + if (len & 3) { + throw DeadlyImportError(parseErrorMessage); + } + std::vector value; + size_t numFloats = len / 4; + value.reserve(numFloats); + for (size_t i = 0; i < numFloats; ++i) { + int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + value.push_back(*(float*)&v); + data += 4; + } + return FIFloatValue::create(std::move(value)); + } +}; + +struct FIDoubleDecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + if (len & 7) { + throw DeadlyImportError(parseErrorMessage); + } + std::vector value; + size_t numDoubles = len / 8; + value.reserve(numDoubles); + for (size_t i = 0; i < numDoubles; ++i) { + long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7]; + long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; + value.push_back(*(double*)&v); + data += 8; + } + return FIDoubleValue::create(std::move(value)); + } +}; + +struct FIUUIDDecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + if (len & 15) { + throw DeadlyImportError(parseErrorMessage); + } + return FIUUIDValue::create(std::vector(data, data + len)); + } +}; + +struct FICDATADecoder: public FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + return FICDATAValue::create(parseUTF8String(data, len)); + } +}; + +class CFIReaderImpl: public FIReader { +public: + + CFIReaderImpl(std::unique_ptr data_, size_t size): + data(std::move(data_)), dataP(data.get()), dataEnd(data.get() + size), currentNodeType(irr::io::EXN_NONE), + emptyElement(false), headerPending(true), terminatorPending(false) + {} + + virtual ~CFIReaderImpl() {} + + virtual bool read() override { + if (headerPending) { + headerPending = false; + parseHeader(); + } + if (terminatorPending) { + terminatorPending = false; + if (elementStack.empty()) { + return false; + } + else { + nodeName = elementStack.top(); + elementStack.pop(); + currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END; + return true; + } + } + if (dataP >= dataEnd) { + return false; + } + uint8_t b = *dataP; + if (b < 0x80) { // Element (C.2.11.2, C.3.7.2) + // C.3 + parseElement(); + return true; + } + else if (b < 0xc0) { // Characters (C.3.7.5) + // C.7 + auto chars = parseNonIdentifyingStringOrIndex3(vocabulary.charactersTable); + nodeName = chars->toString(); + currentNodeType = irr::io::EXN_TEXT; + return true; + } + else if (b < 0xe0) { + if ((b & 0xfc) == 0xc4) { // DTD (C.2.11.5) + // C.9 + ++dataP; + if (b & 0x02) { + /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable); + } + if (b & 0x01) { + /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable); + } + elementStack.push(EmptyString); + currentNodeType = irr::io::EXN_UNKNOWN; + return true; + } + else if ((b & 0xfc) == 0xc8) { // Unexpanded entity reference (C.3.7.4) + // C.6 + ++dataP; + /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable); + if (b & 0x02) { + /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable); + } + if (b & 0x01) { + /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable); + } + currentNodeType = irr::io::EXN_UNKNOWN; + return true; + } + } + else if (b < 0xf0) { + if (b == 0xe1) { // Processing instruction (C.2.11.3, C.3.7.3) + // C.5 + ++dataP; + /*const std::string &target =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable); + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + /*std::shared_ptr data =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable); + currentNodeType = irr::io::EXN_UNKNOWN; + return true; + } + else if (b == 0xe2) { // Comment (C.2.11.4, C.3.7.6) + // C.8 + ++dataP; + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + std::shared_ptr comment = parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable); + nodeName = comment->toString(); + currentNodeType = irr::io::EXN_COMMENT; + return true; + } + } + else { // Terminator (C.2.12, C.3.8) + ++dataP; + if (b == 0xff) { + terminatorPending = true; + } + if (elementStack.empty()) { + return false; + } + else { + nodeName = elementStack.top(); + elementStack.pop(); + currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END; + return true; + } + } + throw DeadlyImportError(parseErrorMessage); + } + + virtual irr::io::EXML_NODE getNodeType() const override { + return currentNodeType; + } + + virtual int getAttributeCount() const override { + return static_cast(attributes.size()); + } + + virtual const char* getAttributeName(int idx) const override { + if (idx < 0 || idx >= (int)attributes.size()) { + return nullptr; + } + return attributes[idx].name.c_str(); + } + + virtual const char* getAttributeValue(int idx) const override { + if (idx < 0 || idx >= (int)attributes.size()) { + return nullptr; + } + return attributes[idx].value->toString().c_str(); + } + + virtual const char* getAttributeValue(const char* name) const override { + const Attribute* attr = getAttributeByName(name); + if (!attr) { + return nullptr; + } + return attr->value->toString().c_str(); + } + + virtual const char* getAttributeValueSafe(const char* name) const override { + const Attribute* attr = getAttributeByName(name); + if (!attr) { + return EmptyString.c_str(); + } + return attr->value->toString().c_str(); + } + + virtual int getAttributeValueAsInt(const char* name) const override { + const Attribute* attr = getAttributeByName(name); + if (!attr) { + return 0; + } + std::shared_ptr intValue = std::dynamic_pointer_cast(attr->value); + if (intValue) { + return intValue->value.size() == 1 ? intValue->value.front() : 0; + } + return stoi(attr->value->toString()); + } + + virtual int getAttributeValueAsInt(int idx) const override { + if (idx < 0 || idx >= (int)attributes.size()) { + return 0; + } + std::shared_ptr intValue = std::dynamic_pointer_cast(attributes[idx].value); + if (intValue) { + return intValue->value.size() == 1 ? intValue->value.front() : 0; + } + return stoi(attributes[idx].value->toString()); + } + + virtual float getAttributeValueAsFloat(const char* name) const override { + const Attribute* attr = getAttributeByName(name); + if (!attr) { + return 0; + } + std::shared_ptr floatValue = std::dynamic_pointer_cast(attr->value); + if (floatValue) { + return floatValue->value.size() == 1 ? floatValue->value.front() : 0; + } + return stof(attr->value->toString()); + } + + virtual float getAttributeValueAsFloat(int idx) const override { + if (idx < 0 || idx >= (int)attributes.size()) { + return 0; + } + std::shared_ptr floatValue = std::dynamic_pointer_cast(attributes[idx].value); + if (floatValue) { + return floatValue->value.size() == 1 ? floatValue->value.front() : 0; + } + return stof(attributes[idx].value->toString()); + } + + virtual const char* getNodeName() const override { + return nodeName.c_str(); + } + + virtual const char* getNodeData() const override { + return nodeName.c_str(); + } + + virtual bool isEmptyElement() const override { + return emptyElement; + } + + virtual irr::io::ETEXT_FORMAT getSourceFormat() const override { + return irr::io::ETF_UTF8; + } + + virtual irr::io::ETEXT_FORMAT getParserFormat() const override { + return irr::io::ETF_UTF8; + } + + virtual std::shared_ptr getAttributeEncodedValue(int idx) const override { + if (idx < 0 || idx >= (int)attributes.size()) { + return nullptr; + } + return attributes[idx].value; + } + + virtual std::shared_ptr getAttributeEncodedValue(const char* name) const override { + const Attribute* attr = getAttributeByName(name); + if (!attr) { + return nullptr; + } + return attr->value; + } + + virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr decoder) override { + decoderMap[algorithmUri] = std::move(decoder); + } + + virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) override { + vocabularyMap[vocabularyUri] = vocabulary; + } + +private: + + struct QName { + std::string prefix; + std::string uri; + std::string name; + inline QName() {} + inline QName(const FIQName &qname): prefix(qname.prefix ? qname.prefix : ""), uri(qname.uri ? qname.uri : ""), name(qname.name) {} + }; + + struct Attribute { + QName qname; + std::string name; + std::shared_ptr value; + }; + + struct Vocabulary { + std::vector restrictedAlphabetTable; + std::vector encodingAlgorithmTable; + std::vector prefixTable; + std::vector namespaceNameTable; + std::vector localNameTable; + std::vector otherNCNameTable; + std::vector otherURITable; + std::vector> attributeValueTable; + std::vector> charactersTable; + std::vector> otherStringTable; + std::vector elementNameTable; + std::vector attributeNameTable; + Vocabulary() { + prefixTable.push_back("xml"); + namespaceNameTable.push_back("http://www.w3.org/XML/1998/namespace"); + } + }; + + const Attribute* getAttributeByName(const char* name) const { + if (!name) { + return 0; + } + std::string n = name; + for (int i=0; i<(int)attributes.size(); ++i) { + if (attributes[i].name == n) { + return &attributes[i]; + } + } + return 0; + } + + size_t parseInt2() { // C.25 + uint8_t b = *dataP++; + if (!(b & 0x40)) { // x0...... (C.25.2) + return b & 0x3f; + } + else if ((b & 0x60) == 0x40) { // x10..... ........ (C.25.3) + if (dataEnd - dataP > 0) { + return (((b & 0x1f) << 8) | *dataP++) + 0x40; + } + } + else if ((b & 0x70) == 0x60) { // x110.... ........ ........ (C.25.4) + if (dataEnd - dataP > 1) { + size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x2040; + dataP += 2; + return result; + } + } + throw DeadlyImportError(parseErrorMessage); + } + + size_t parseInt3() { // C.27 + uint8_t b = *dataP++; + if (!(b & 0x20)) { // xx0..... (C.27.2) + return b & 0x1f; + } + else if ((b & 0x38) == 0x20) { // xx100... ........ (C.27.3) + if (dataEnd - dataP > 0) { + return (((b & 0x07) << 8) | *dataP++) + 0x20; + } + } + else if ((b & 0x38) == 0x28) { // xx101... ........ ........ (C.27.4) + if (dataEnd - dataP > 1) { + size_t result = (((b & 0x07) << 16) | (dataP[0] << 8) | dataP[1]) + 0x820; + dataP += 2; + return result; + } + } + else if ((b & 0x3f) == 0x30) { // xx110000 0000.... ........ ........ (C.27.5) + if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) { + size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x80820; + dataP += 3; + return result; + } + } + throw DeadlyImportError(parseErrorMessage); + } + + size_t parseInt4() { // C.28 + uint8_t b = *dataP++; + if (!(b & 0x10)) { // xxx0.... (C.28.2) + return b & 0x0f; + } + else if ((b & 0x1c) == 0x10) { // xxx100.. ........ (C.28.3) + if (dataEnd - dataP > 0) { + return (((b & 0x03) << 8) | *dataP++) + 0x10; + } + } + else if ((b & 0x1c) == 0x14) { // xxx101.. ........ ........ (C.28.4) + if (dataEnd - dataP > 1) { + size_t result = (((b & 0x03) << 16) | (dataP[0] << 8) | dataP[1]) + 0x410; + dataP += 2; + return result; + } + } + else if ((b & 0x1f) == 0x18) { // xxx11000 0000.... ........ ........ (C.28.5) + if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) { + size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x40410; + dataP += 3; + return result; + } + } + throw DeadlyImportError(parseErrorMessage); + } + + size_t parseSequenceLen() { // C.21 + if (dataEnd - dataP > 0) { + uint8_t b = *dataP++; + if (b < 0x80) { // 0....... (C.21.2) + return b; + } + else if ((b & 0xf0) == 0x80) { // 1000.... ........ ........ (C.21.3) + if (dataEnd - dataP > 1) { + size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x80; + dataP += 2; + return result; + } + } + } + throw DeadlyImportError(parseErrorMessage); + } + + std::string parseNonEmptyOctetString2() { // C.22 + // Parse the length of the string + uint8_t b = *dataP++ & 0x7f; + size_t len; + if (!(b & 0x40)) { // x0...... (C.22.3.1) + len = b + 1; + } + else if (b == 0x40) { // x1000000 ........ (C.22.3.2) + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + len = *dataP++ + 0x41; + } + else if (b == 0x60) { // x1100000 ........ ........ ........ ........ (C.22.3.3) + if (dataEnd - dataP < 4) { + throw DeadlyImportError(parseErrorMessage); + } + len = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x141; + dataP += 4; + } + else { + throw DeadlyImportError(parseErrorMessage); + } + + // Parse the string (C.22.4) + if (dataEnd - dataP < static_cast(len)) { + throw DeadlyImportError(parseErrorMessage); + } + std::string s = parseUTF8String(dataP, len); + dataP += len; + + return s; + } + + size_t parseNonEmptyOctetString5Length() { // C.23 + // Parse the length of the string + size_t b = *dataP++ & 0x0f; + if (!(b & 0x08)) { // xxxx0... (C.23.3.1) + return b + 1; + } + else if (b == 0x08) { // xxxx1000 ........ (C.23.3.2) + if (dataEnd - dataP > 0) { + return *dataP++ + 0x09; + } + } + else if (b == 0x0c) { // xxxx1100 ........ ........ ........ ........ (C.23.3.3) + if (dataEnd - dataP > 3) { + size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x109; + dataP += 4; + return result; + } + } + throw DeadlyImportError(parseErrorMessage); + } + + size_t parseNonEmptyOctetString7Length() { // C.24 + // Parse the length of the string + size_t b = *dataP++ & 0x03; + if (!(b & 0x02)) { // xxxxxx0. (C.24.3.1) + return b + 1; + } + else if (b == 0x02) { // xxxxxx10 ........ (C.24.3.2) + if (dataEnd - dataP > 0) { + return *dataP++ + 0x3; + } + } + else if (b == 0x03) { // xxxxxx11 ........ ........ ........ ........ (C.24.3.3) + if (dataEnd - dataP > 3) { + size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x103; + dataP += 4; + return result; + } + } + throw DeadlyImportError(parseErrorMessage); + } + + std::shared_ptr parseEncodedData(size_t index, size_t len) { + if (index < 32) { + FIDecoder *decoder = defaultDecoder[index]; + if (!decoder) { + throw DeadlyImportError("Invalid encoding algorithm index " + std::to_string(index)); + } + return decoder->decode(dataP, len); + } + else { + if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) { + throw DeadlyImportError("Invalid encoding algorithm index " + std::to_string(index)); + } + std::string uri = vocabulary.encodingAlgorithmTable[index - 32]; + auto it = decoderMap.find(uri); + if (it == decoderMap.end()) { + throw DeadlyImportError("Unsupported encoding algorithm " + uri); + } + else { + return it->second->decode(dataP, len); + } + } + } + + std::shared_ptr parseRestrictedAlphabet(size_t index, size_t len) { + std::string alphabet; + if (index < 16) { + switch (index) { + case 0: // numeric + alphabet = "0123456789-+.e "; + break; + case 1: // date and time + alphabet = "0123456789-:TZ "; + break; + default: + throw DeadlyImportError("Invalid restricted alphabet index " + std::to_string(index)); + } + } + else { + if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) { + throw DeadlyImportError("Invalid restricted alphabet index " + std::to_string(index)); + } + alphabet = vocabulary.restrictedAlphabetTable[index - 16]; + } + std::vector alphabetUTF32; + utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32)); + std::string::size_type alphabetLength = alphabetUTF32.size(); + if (alphabetLength < 2) { + throw DeadlyImportError("Invalid restricted alphabet length " + std::to_string(alphabetLength)); + } + std::string::size_type bitsPerCharacter = 1; + while ((1ull << bitsPerCharacter) <= alphabetLength) { + ++bitsPerCharacter; + } + size_t bitsAvail = 0; + uint8_t mask = (1 << bitsPerCharacter) - 1; + uint32_t bits = 0; + std::string s; + for (size_t i = 0; i < len; ++i) { + bits = (bits << 8) | dataP[i]; + bitsAvail += 8; + while (bitsAvail >= bitsPerCharacter) { + bitsAvail -= bitsPerCharacter; + size_t charIndex = (bits >> bitsAvail) & mask; + if (charIndex < alphabetLength) { + s.push_back(alphabetUTF32[charIndex]); + } + else if (charIndex != mask) { + throw DeadlyImportError(parseErrorMessage); + } + } + } + return FIStringValue::create(std::move(s)); + } + + std::shared_ptr parseEncodedCharacterString3() { // C.19 + std::shared_ptr result; + size_t len; + uint8_t b = *dataP; + if (b & 0x20) { + ++dataP; + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + size_t index = ((b & 0x0f) << 4) | ((*dataP & 0xf0) >> 4); // C.29 + len = parseNonEmptyOctetString5Length(); + if (dataEnd - dataP < static_cast(len)) { + throw DeadlyImportError(parseErrorMessage); + } + if (b & 0x10) { + // encoding algorithm (C.19.3.4) + result = parseEncodedData(index, len); + } + else { + // Restricted alphabet (C.19.3.3) + result = parseRestrictedAlphabet(index, len); + } + } + else { + len = parseNonEmptyOctetString5Length(); + if (dataEnd - dataP < static_cast(len)) { + throw DeadlyImportError(parseErrorMessage); + } + if (b & 0x10) { + // UTF-16 (C.19.3.2) + if (len & 1) { + throw DeadlyImportError(parseErrorMessage); + } + result = FIStringValue::create(parseUTF16String(dataP, len)); + } + else { + // UTF-8 (C.19.3.1) + result = FIStringValue::create(parseUTF8String(dataP, len)); + } + } + dataP += len; + return result; + } + + std::shared_ptr parseEncodedCharacterString5() { // C.20 + std::shared_ptr result; + size_t len; + uint8_t b = *dataP; + if (b & 0x08) { + ++dataP; + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + size_t index = ((b & 0x03) << 6) | ((*dataP & 0xfc) >> 2); /* C.29 */ + len = parseNonEmptyOctetString7Length(); + if (dataEnd - dataP < static_cast(len)) { + throw DeadlyImportError(parseErrorMessage); + } + if (b & 0x04) { + // encoding algorithm (C.20.3.4) + result = parseEncodedData(index, len); + } + else { + // Restricted alphabet (C.20.3.3) + result = parseRestrictedAlphabet(index, len); + } + } + else { + len = parseNonEmptyOctetString7Length(); + if (dataEnd - dataP < static_cast(len)) { + throw DeadlyImportError(parseErrorMessage); + } + if (b & 0x04) { + // UTF-16 (C.20.3.2) + if (len & 1) { + throw DeadlyImportError(parseErrorMessage); + } + result = FIStringValue::create(parseUTF16String(dataP, len)); + } + else { + // UTF-8 (C.20.3.1) + result = FIStringValue::create(parseUTF8String(dataP, len)); + } + } + dataP += len; + return result; + } + + const std::string &parseIdentifyingStringOrIndex(std::vector &stringTable) { // C.13 + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + uint8_t b = *dataP; + if (b & 0x80) { + // We have an index (C.13.4) + size_t index = parseInt2(); + if (index >= stringTable.size()) { + throw DeadlyImportError(parseErrorMessage); + } + return stringTable[index]; + } + else { + // We have a string (C.13.3) + stringTable.push_back(parseNonEmptyOctetString2()); + return stringTable.back(); + } + } + + QName parseNameSurrogate() { // C.16 + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + uint8_t b = *dataP++; + if (b & 0xfc) { // Padding '000000' C.2.5.5 + throw DeadlyImportError(parseErrorMessage); + } + QName result; + size_t index; + if (b & 0x02) { // prefix (C.16.3) + if ((dataEnd - dataP < 1) || (*dataP & 0x80)) { + throw DeadlyImportError(parseErrorMessage); + } + index = parseInt2(); + if (index >= vocabulary.prefixTable.size()) { + throw DeadlyImportError(parseErrorMessage); + } + result.prefix = vocabulary.prefixTable[index]; + } + if (b & 0x01) { // namespace-name (C.16.4) + if ((dataEnd - dataP < 1) || (*dataP & 0x80)) { + throw DeadlyImportError(parseErrorMessage); + } + index = parseInt2(); + if (index >= vocabulary.namespaceNameTable.size()) { + throw DeadlyImportError(parseErrorMessage); + } + result.uri = vocabulary.namespaceNameTable[index]; + } + // local-name + if ((dataEnd - dataP < 1) || (*dataP & 0x80)) { + throw DeadlyImportError(parseErrorMessage); + } + index = parseInt2(); + if (index >= vocabulary.localNameTable.size()) { + throw DeadlyImportError(parseErrorMessage); + } + result.name = vocabulary.localNameTable[index]; + return result; + } + + const QName &parseQualifiedNameOrIndex2(std::vector &qNameTable) { // C.17 + uint8_t b = *dataP; + if ((b & 0x7c) == 0x78) { // x11110.. + // We have a literal (C.17.3) + ++dataP; + QName result; + // prefix (C.17.3.1) + result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string(); + // namespace-name (C.17.3.1) + result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string(); + // local-name + result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable); + qNameTable.push_back(result); + return qNameTable.back(); + } + else { + // We have an index (C.17.4) + size_t index = parseInt2(); + if (index >= qNameTable.size()) { + throw DeadlyImportError(parseErrorMessage); + } + return qNameTable[index]; + } + } + + const QName &parseQualifiedNameOrIndex3(std::vector &qNameTable) { // C.18 + uint8_t b = *dataP; + if ((b & 0x3c) == 0x3c) { // xx1111.. + // We have a literal (C.18.3) + ++dataP; + QName result; + // prefix (C.18.3.1) + result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string(); + // namespace-name (C.18.3.1) + result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string(); + // local-name + result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable); + qNameTable.push_back(result); + return qNameTable.back(); + } + else { + // We have an index (C.18.4) + size_t index = parseInt3(); + if (index >= qNameTable.size()) { + throw DeadlyImportError(parseErrorMessage); + } + return qNameTable[index]; + } + } + + std::shared_ptr parseNonIdentifyingStringOrIndex1(std::vector> &valueTable) { // C.14 + uint8_t b = *dataP; + if (b == 0xff) { // C.26.2 + // empty string + ++dataP; + return EmptyFIString; + } + else if (b & 0x80) { // C.14.4 + // We have an index + size_t index = parseInt2(); + if (index >= valueTable.size()) { + throw DeadlyImportError(parseErrorMessage); + } + return valueTable[index]; + } + else { // C.14.3 + // We have a literal + std::shared_ptr result = parseEncodedCharacterString3(); + if (b & 0x40) { // C.14.3.1 + valueTable.push_back(result); + } + return result; + } + } + + std::shared_ptr parseNonIdentifyingStringOrIndex3(std::vector> &valueTable) { // C.15 + uint8_t b = *dataP; + if (b & 0x20) { // C.15.4 + // We have an index + size_t index = parseInt4(); + if (index >= valueTable.size()) { + throw DeadlyImportError(parseErrorMessage); + } + return valueTable[index]; + } + else { // C.15.3 + // We have a literal + std::shared_ptr result = parseEncodedCharacterString5(); + if (b & 0x10) { // C.15.3.1 + valueTable.push_back(result); + } + return result; + } + } + + void parseElement() { + // C.3 + + attributes.clear(); + + uint8_t b = *dataP; + bool hasAttributes = (b & 0x40) != 0; // C.3.3 + if ((b & 0x3f) == 0x38) { // C.3.4.1 + // Parse namespaces + ++dataP; + for (;;) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + b = *dataP++; + if (b == 0xf0) { // C.3.4.3 + break; + } + if ((b & 0xfc) != 0xcc) { // C.3.4.2 + throw DeadlyImportError(parseErrorMessage); + } + // C.12 + Attribute attr; + attr.qname.prefix = "xmlns"; + attr.qname.name = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string(); + attr.qname.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string(); + attr.name = attr.qname.name.empty() ? "xmlns" : "xmlns:" + attr.qname.name; + attr.value = FIStringValue::create(std::string(attr.qname.uri)); + attributes.push_back(attr); + } + if ((dataEnd - dataP < 1) || (*dataP & 0xc0)) { + throw DeadlyImportError(parseErrorMessage); + } + } + + // Parse Element name (C.3.5) + const QName &elemName = parseQualifiedNameOrIndex3(vocabulary.elementNameTable); + nodeName = elemName.prefix.empty() ? elemName.name : elemName.prefix + ':' + elemName.name; + + if (hasAttributes) { + for (;;) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + b = *dataP; + if (b < 0x80) { // C.3.6.1 + // C.4 + Attribute attr; + attr.qname = parseQualifiedNameOrIndex2(vocabulary.attributeNameTable); + attr.name = attr.qname.prefix.empty() ? attr.qname.name : attr.qname.prefix + ':' + attr.qname.name; + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + attr.value = parseNonIdentifyingStringOrIndex1(vocabulary.attributeValueTable); + attributes.push_back(attr); + } + else { + if ((b & 0xf0) != 0xf0) { // C.3.6.2 + throw DeadlyImportError(parseErrorMessage); + } + emptyElement = b == 0xff; // C.3.6.2, C.3.8 + ++dataP; + break; + } + } + } + else { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + b = *dataP; + switch (b) { + case 0xff: + terminatorPending = true; + // Intentionally fall through + case 0xf0: + emptyElement = true; + ++dataP; + break; + default: + emptyElement = false; + } + } + if (!emptyElement) { + elementStack.push(nodeName); + } + + currentNodeType = irr::io::EXN_ELEMENT; + } + + void parseHeader() { + // Parse header (C.1.3) + size_t magicSize = parseMagic(dataP, dataEnd); + if (!magicSize) { + throw DeadlyImportError(parseErrorMessage); + } + dataP += magicSize; + // C.2.3 + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + uint8_t b = *dataP++; + if (b & 0x40) { + // Parse additional data (C.2.4) + size_t len = parseSequenceLen(); + for (size_t i = 0; i < len; ++i) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + /*std::string id =*/ parseNonEmptyOctetString2(); + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + /*std::string data =*/ parseNonEmptyOctetString2(); + } + } + if (b & 0x20) { + // Parse initial vocabulary (C.2.5) + if (dataEnd - dataP < 2) { + throw DeadlyImportError(parseErrorMessage); + } + uint16_t b1 = (dataP[0] << 8) | dataP[1]; + dataP += 2; + if (b1 & 0x1000) { + // External vocabulary (C.2.5.2) + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + std::string uri = parseNonEmptyOctetString2(); + auto it = vocabularyMap.find(uri); + if (it == vocabularyMap.end()) { + throw DeadlyImportError("Unknown vocabulary " + uri); + } + const FIVocabulary *externalVocabulary = it->second; + if (externalVocabulary->restrictedAlphabetTable) { + std::copy(externalVocabulary->restrictedAlphabetTable, externalVocabulary->restrictedAlphabetTable + externalVocabulary->restrictedAlphabetTableSize, std::back_inserter(vocabulary.restrictedAlphabetTable)); + } + if (externalVocabulary->encodingAlgorithmTable) { + std::copy(externalVocabulary->encodingAlgorithmTable, externalVocabulary->encodingAlgorithmTable + externalVocabulary->encodingAlgorithmTableSize, std::back_inserter(vocabulary.encodingAlgorithmTable)); + } + if (externalVocabulary->prefixTable) { + std::copy(externalVocabulary->prefixTable, externalVocabulary->prefixTable + externalVocabulary->prefixTableSize, std::back_inserter(vocabulary.prefixTable)); + } + if (externalVocabulary->namespaceNameTable) { + std::copy(externalVocabulary->namespaceNameTable, externalVocabulary->namespaceNameTable + externalVocabulary->namespaceNameTableSize, std::back_inserter(vocabulary.namespaceNameTable)); + } + if (externalVocabulary->localNameTable) { + std::copy(externalVocabulary->localNameTable, externalVocabulary->localNameTable + externalVocabulary->localNameTableSize, std::back_inserter(vocabulary.localNameTable)); + } + if (externalVocabulary->otherNCNameTable) { + std::copy(externalVocabulary->otherNCNameTable, externalVocabulary->otherNCNameTable + externalVocabulary->otherNCNameTableSize, std::back_inserter(vocabulary.otherNCNameTable)); + } + if (externalVocabulary->otherURITable) { + std::copy(externalVocabulary->otherURITable, externalVocabulary->otherURITable + externalVocabulary->otherURITableSize, std::back_inserter(vocabulary.otherURITable)); + } + if (externalVocabulary->attributeValueTable) { + std::copy(externalVocabulary->attributeValueTable, externalVocabulary->attributeValueTable + externalVocabulary->attributeValueTableSize, std::back_inserter(vocabulary.attributeValueTable)); + } + if (externalVocabulary->charactersTable) { + std::copy(externalVocabulary->charactersTable, externalVocabulary->charactersTable + externalVocabulary->charactersTableSize, std::back_inserter(vocabulary.charactersTable)); + } + if (externalVocabulary->otherStringTable) { + std::copy(externalVocabulary->otherStringTable, externalVocabulary->otherStringTable + externalVocabulary->otherStringTableSize, std::back_inserter(vocabulary.otherStringTable)); + } + if (externalVocabulary->elementNameTable) { + std::copy(externalVocabulary->elementNameTable, externalVocabulary->elementNameTable + externalVocabulary->elementNameTableSize, std::back_inserter(vocabulary.elementNameTable)); + } + if (externalVocabulary->attributeNameTable) { + std::copy(externalVocabulary->attributeNameTable, externalVocabulary->attributeNameTable + externalVocabulary->attributeNameTableSize, std::back_inserter(vocabulary.attributeNameTable)); + } + } + if (b1 & 0x0800) { + // Parse restricted alphabets (C.2.5.3) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.restrictedAlphabetTable.push_back(parseNonEmptyOctetString2()); + } + } + if (b1 & 0x0400) { + // Parse encoding algorithms (C.2.5.3) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.encodingAlgorithmTable.push_back(parseNonEmptyOctetString2()); + } + } + if (b1 & 0x0200) { + // Parse prefixes (C.2.5.3) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.prefixTable.push_back(parseNonEmptyOctetString2()); + } + } + if (b1 & 0x0100) { + // Parse namespace names (C.2.5.3) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.namespaceNameTable.push_back(parseNonEmptyOctetString2()); + } + } + if (b1 & 0x0080) { + // Parse local names (C.2.5.3) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.localNameTable.push_back(parseNonEmptyOctetString2()); + } + } + if (b1 & 0x0040) { + // Parse other ncnames (C.2.5.3) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.otherNCNameTable.push_back(parseNonEmptyOctetString2()); + } + } + if (b1 & 0x0020) { + // Parse other uris (C.2.5.3) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.otherURITable.push_back(parseNonEmptyOctetString2()); + } + } + if (b1 & 0x0010) { + // Parse attribute values (C.2.5.4) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.attributeValueTable.push_back(parseEncodedCharacterString3()); + } + } + if (b1 & 0x0008) { + // Parse content character chunks (C.2.5.4) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.charactersTable.push_back(parseEncodedCharacterString3()); + } + } + if (b1 & 0x0004) { + // Parse other strings (C.2.5.4) + for (size_t len = parseSequenceLen(); len > 0; --len) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + vocabulary.otherStringTable.push_back(parseEncodedCharacterString3()); + } + } + if (b1 & 0x0002) { + // Parse element name surrogates (C.2.5.5) + for (size_t len = parseSequenceLen(); len > 0; --len) { + vocabulary.elementNameTable.push_back(parseNameSurrogate()); + } + } + if (b1 & 0x0001) { + // Parse attribute name surrogates (C.2.5.5) + for (size_t len = parseSequenceLen(); len > 0; --len) { + vocabulary.attributeNameTable.push_back(parseNameSurrogate()); + } + } + } + if (b & 0x10) { + // Parse notations (C.2.6) + for (;;) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + uint8_t b1 = *dataP++; + if (b1 == 0xf0) { + break; + } + if ((b1 & 0xfc) != 0xc0) { + throw DeadlyImportError(parseErrorMessage); + } + /* C.11 */ + /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable); + if (b1 & 0x02) { + /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable); + } + if (b1 & 0x01) { + /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable); + } + } + } + if (b & 0x08) { + // Parse unparsed entities (C.2.7) + for (;;) { + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + uint8_t b1 = *dataP++; + if (b1 == 0xf0) { + break; + } + if ((b1 & 0xfe) != 0xd0) { + throw DeadlyImportError(parseErrorMessage); + } + /* C.10 */ + /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable); + /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable); + if (b1 & 0x01) { + /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable); + } + /*const std::string ¬ationName =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable); + } + } + if (b & 0x04) { + // Parse character encoding scheme (C.2.8) + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + /*std::string characterEncodingScheme =*/ parseNonEmptyOctetString2(); + } + if (b & 0x02) { + // Parse standalone flag (C.2.9) + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + uint8_t b1 = *dataP++; + if (b1 & 0xfe) { + throw DeadlyImportError(parseErrorMessage); + } + //bool standalone = b1 & 0x01; + } + if (b & 0x01) { + // Parse version (C.2.10) + if (dataEnd - dataP < 1) { + throw DeadlyImportError(parseErrorMessage); + } + /*std::shared_ptr version =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable); + } + } + + std::unique_ptr data; + uint8_t *dataP, *dataEnd; + irr::io::EXML_NODE currentNodeType; + bool emptyElement; + bool headerPending; + bool terminatorPending; + Vocabulary vocabulary; + std::vector attributes; + std::stack elementStack; + std::string nodeName; + std::map> decoderMap; + std::map vocabularyMap; + + static const std::string EmptyString; + static std::shared_ptr EmptyFIString; + + static FIHexDecoder hexDecoder; + static FIBase64Decoder base64Decoder; + static FIShortDecoder shortDecoder; + static FIIntDecoder intDecoder; + static FILongDecoder longDecoder; + static FIBoolDecoder boolDecoder; + static FIFloatDecoder floatDecoder; + static FIDoubleDecoder doubleDecoder; + static FIUUIDDecoder uuidDecoder; + static FICDATADecoder cdataDecoder; + static FIDecoder *defaultDecoder[32]; +}; + +const std::string CFIReaderImpl::EmptyString; +std::shared_ptr CFIReaderImpl::EmptyFIString = FIStringValue::create(std::string()); + +FIHexDecoder CFIReaderImpl::hexDecoder; +FIBase64Decoder CFIReaderImpl::base64Decoder; +FIShortDecoder CFIReaderImpl::shortDecoder; +FIIntDecoder CFIReaderImpl::intDecoder; +FILongDecoder CFIReaderImpl::longDecoder; +FIBoolDecoder CFIReaderImpl::boolDecoder; +FIFloatDecoder CFIReaderImpl::floatDecoder; +FIDoubleDecoder CFIReaderImpl::doubleDecoder; +FIUUIDDecoder CFIReaderImpl::uuidDecoder; +FICDATADecoder CFIReaderImpl::cdataDecoder; + +FIDecoder *CFIReaderImpl::defaultDecoder[32] = { + &hexDecoder, + &base64Decoder, + &shortDecoder, + &intDecoder, + &longDecoder, + &boolDecoder, + &floatDecoder, + &doubleDecoder, + &uuidDecoder, + &cdataDecoder +}; + +class CXMLReaderImpl : public FIReader +{ +public: + + //! Constructor + CXMLReaderImpl(std::unique_ptr> reader_) + : reader(std::move(reader_)) + {} + + virtual ~CXMLReaderImpl() {} + + virtual bool read() override { + return reader->read(); + } + + virtual irr::io::EXML_NODE getNodeType() const override { + return reader->getNodeType(); + } + + virtual int getAttributeCount() const override { + return reader->getAttributeCount(); + } + + virtual const char* getAttributeName(int idx) const override { + return reader->getAttributeName(idx); + } + + virtual const char* getAttributeValue(int idx) const override { + return reader->getAttributeValue(idx); + } + + virtual const char* getAttributeValue(const char* name) const override { + return reader->getAttributeValue(name); + } + + virtual const char* getAttributeValueSafe(const char* name) const override { + return reader->getAttributeValueSafe(name); + } + + virtual int getAttributeValueAsInt(const char* name) const override { + return reader->getAttributeValueAsInt(name); + } + + virtual int getAttributeValueAsInt(int idx) const override { + return reader->getAttributeValueAsInt(idx); + } + + virtual float getAttributeValueAsFloat(const char* name) const override { + return reader->getAttributeValueAsFloat(name); + } + + virtual float getAttributeValueAsFloat(int idx) const override { + return reader->getAttributeValueAsFloat(idx); + } + + virtual const char* getNodeName() const override { + return reader->getNodeName(); + } + + virtual const char* getNodeData() const override { + return reader->getNodeData(); + } + + virtual bool isEmptyElement() const override { + return reader->isEmptyElement(); + } + + virtual irr::io::ETEXT_FORMAT getSourceFormat() const override { + return reader->getSourceFormat(); + } + + virtual irr::io::ETEXT_FORMAT getParserFormat() const override { + return reader->getParserFormat(); + } + + virtual std::shared_ptr getAttributeEncodedValue(int idx) const override { + return nullptr; + } + + virtual std::shared_ptr getAttributeEncodedValue(const char* name) const override { + return nullptr; + } + + virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr decoder) override {} + + virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) override {} + +private: + + std::unique_ptr> reader; +}; + +static std::unique_ptr readFile(IOStream *stream, size_t &size, bool &isFI) { + size = stream->FileSize(); + std::unique_ptr data = std::unique_ptr(new uint8_t[size]); + if (stream->Read(data.get(), size, 1) != 1) { + size = 0; + data.reset(); + } + isFI = parseMagic(data.get(), data.get() + size) > 0; + return data; +} + +std::unique_ptr FIReader::create(IOStream *stream) +{ + size_t size; + bool isFI; + auto data = readFile(stream, size, isFI); + if (isFI) { + return std::unique_ptr(new CFIReaderImpl(std::move(data), size)); + } + else { + auto memios = std::unique_ptr(new MemoryIOStream(data.release(), size, true)); + auto callback = std::unique_ptr(new CIrrXML_IOStreamReader(memios.get())); + return std::unique_ptr(new CXMLReaderImpl(std::unique_ptr>(createIrrXMLReader(callback.get())))); + } +} + +}// namespace Assimp + +#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/FIReader.hpp b/code/FIReader.hpp new file mode 100644 index 000000000..05f13ecac --- /dev/null +++ b/code/FIReader.hpp @@ -0,0 +1,171 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/// \file FIReader.hpp +/// \brief Reader for Fast Infoset encoded binary XML files. +/// \date 2017 +/// \author Patrick Daehne + +#ifndef INCLUDED_AI_FI_READER_H +#define INCLUDED_AI_FI_READER_H + +#include +#include +#include +#include + +namespace Assimp { + +struct FIValue { + virtual const std::string &toString() const = 0; +}; + +struct FIStringValue: public FIValue { + std::string value; + static std::shared_ptr create(std::string &&value); +}; + +struct FIByteValue: public FIValue { + std::vector value; +}; + +struct FIHexValue: public FIByteValue { + static std::shared_ptr create(std::vector &&value); +}; + +struct FIBase64Value: public FIByteValue { + static std::shared_ptr create(std::vector &&value); +}; + +struct FIShortValue: public FIValue { + std::vector value; + static std::shared_ptr create(std::vector &&value); +}; + +struct FIIntValue: public FIValue { + std::vector value; + static std::shared_ptr create(std::vector &&value); +}; + +struct FILongValue: public FIValue { + std::vector value; + static std::shared_ptr create(std::vector &&value); +}; + +struct FIBoolValue: public FIValue { + std::vector value; + static std::shared_ptr create(std::vector &&value); +}; + +struct FIFloatValue: public FIValue { + std::vector value; + static std::shared_ptr create(std::vector &&value); +}; + +struct FIDoubleValue: public FIValue { + std::vector value; + static std::shared_ptr create(std::vector &&value); +}; + +struct FIUUIDValue: public FIByteValue { + static std::shared_ptr create(std::vector &&value); +}; + +struct FICDATAValue: public FIStringValue { + static std::shared_ptr create(std::string &&value); +}; + +struct FIDecoder { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) = 0; +}; + +struct FIQName { + const char *name; + const char *prefix; + const char *uri; +}; + +struct FIVocabulary { + const char **restrictedAlphabetTable; + size_t restrictedAlphabetTableSize; + const char **encodingAlgorithmTable; + size_t encodingAlgorithmTableSize; + const char **prefixTable; + size_t prefixTableSize; + const char **namespaceNameTable; + size_t namespaceNameTableSize; + const char **localNameTable; + size_t localNameTableSize; + const char **otherNCNameTable; + size_t otherNCNameTableSize; + const char **otherURITable; + size_t otherURITableSize; + const std::shared_ptr *attributeValueTable; + size_t attributeValueTableSize; + const std::shared_ptr *charactersTable; + size_t charactersTableSize; + const std::shared_ptr *otherStringTable; + size_t otherStringTableSize; + const FIQName *elementNameTable; + size_t elementNameTableSize; + const FIQName *attributeNameTable; + size_t attributeNameTableSize; +}; + +class IOStream; + +class FIReader: public irr::io::IIrrXMLReader { +public: + + virtual std::shared_ptr getAttributeEncodedValue(int idx) const = 0; + + virtual std::shared_ptr getAttributeEncodedValue(const char *name) const = 0; + + virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr decoder) = 0; + + virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) = 0; + + static std::unique_ptr create(IOStream *stream); + +};// class IFIReader + +}// namespace Assimp + +#endif // INCLUDED_AI_FI_READER_H diff --git a/code/X3DImporter.cpp b/code/X3DImporter.cpp old mode 100644 new mode 100755 index 2edb1b081..c71453211 --- a/code/X3DImporter.cpp +++ b/code/X3DImporter.cpp @@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Header files, Assimp. #include #include "fast_atof.h" +#include "FIReader.hpp" // Header files, stdlib. #include @@ -66,15 +67,16 @@ const aiImporterDesc X3DImporter::Description = { "smalcom", "", "See documentation in source code. Chapter: Limitations.", - aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, + aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, 0, 0, 0, 0, - "x3d" + "x3d x3db" }; -const std::string X3DImporter::whitespace(" ,\t\n\r"); +const std::regex X3DImporter::pattern_nws(R"([^, \t\r\n]+)"); +const std::regex X3DImporter::pattern_true(R"(^\s*(?:true|1)\s*$)", std::regex::icase); X3DImporter::X3DImporter() : NodeElement_Cur( nullptr ) @@ -83,7 +85,6 @@ X3DImporter::X3DImporter() } X3DImporter::~X3DImporter() { - delete mReader; // Clear() is accounting if data already is deleted. So, just check again if all data is deleted. Clear(); } @@ -370,38 +371,65 @@ bool X3DImporter::XML_SearchNode(const std::string& pNodeName) bool X3DImporter::XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx) { -std::string val(mReader->getAttributeValue(pAttrIdx)); + auto boolValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); + if (boolValue) { + if (boolValue->value.size() == 1) { + return boolValue->value.front(); + } + throw DeadlyImportError("Invalid bool value"); + } + else { + std::string val(mReader->getAttributeValue(pAttrIdx)); - if(val == "false") - return false; - else if(val == "true") - return true; - else - throw DeadlyImportError("Bool attribute value can contain \"false\" or \"true\" not the \"" + val + "\""); + if(val == "false") + return false; + else if(val == "true") + return true; + else + throw DeadlyImportError("Bool attribute value can contain \"false\" or \"true\" not the \"" + val + "\""); + } } float X3DImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx) { - std::string val; - float tvalf; + auto floatValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); + if (floatValue) { + if (floatValue->value.size() == 1) { + return floatValue->value.front(); + } + throw DeadlyImportError("Invalid float value"); + } + else { + std::string val; + float tvalf; - ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val); - fast_atoreal_move(val.c_str(), tvalf, false); + ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val); + fast_atoreal_move(val.c_str(), tvalf, false); - return tvalf; + return tvalf; + } } int32_t X3DImporter::XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx) { - return strtol10(mReader->getAttributeValue(pAttrIdx)); + auto intValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); + if (intValue) { + if (intValue->value.size() == 1) { + return intValue->value.front(); + } + throw DeadlyImportError("Invalid int value"); + } + else { + return strtol10(mReader->getAttributeValue(pAttrIdx)); + } } void X3DImporter::XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue) { - std::list tlist; - std::list::iterator it; + std::vector tlist; + std::vector::iterator it; - XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist); + XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist); if(tlist.size() != 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx)); it = tlist.begin(); @@ -412,10 +440,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& void X3DImporter::XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue) { - std::list tlist; - std::list::iterator it; + std::vector tlist; + std::vector::iterator it; - XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist); + XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist); if(tlist.size() != 2) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx)); it = tlist.begin(); @@ -425,10 +453,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D void X3DImporter::XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue) { - std::list tlist; - std::list::iterator it; + std::vector tlist; + std::vector::iterator it; - XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist); + XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist); if(tlist.size() != 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx)); it = tlist.begin(); @@ -437,166 +465,75 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D pValue.z = *it; } -void X3DImporter::XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list& pValue) -{ - const char *tok_cur = mReader->getAttributeValue(pAttrIdx); - const char *tok_end = tok_cur + strlen(tok_cur); - - for(;;) - { - while((tok_cur < tok_end) && (whitespace.find_first_of(*tok_cur) != std::string::npos)) tok_cur++;// skip spaces between values. - if (tok_cur >= tok_end) - break; - - if(strncmp(tok_cur, "true", 4) == 0) - { - pValue.push_back(true); - tok_cur += 4; - } - else if(strncmp(tok_cur, "false", 5) == 0) - { - pValue.push_back(false); - tok_cur += 5; - } - else - { - Throw_IncorrectAttrValue(mReader->getAttributeName(pAttrIdx)); - } - }// for(;;) -} - void X3DImporter::XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector& pValue) { - std::list tlist; - - XML_ReadNode_GetAttrVal_AsListB(pAttrIdx, tlist);// read as list - // and copy to array - if(tlist.size() > 0) - { - pValue.reserve(tlist.size()); - for(std::list::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue) -{ - const char* tstr = mReader->getAttributeValue(pAttrIdx); - const char* tstr_end = tstr + strlen(tstr); - - do - { - const char* ostr; - - int32_t tval32; - - while((tstr < tstr_end) && (whitespace.find_first_of(*tstr) != std::string::npos)) tstr++;// skip spaces between values. - - tval32 = strtol10(tstr, &ostr); - if(ostr == tstr) break; - - tstr = ostr; - pValue.push_back(tval32); - } while(tstr < tstr_end); + auto boolValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); + if (boolValue) { + pValue = boolValue->value; + } + else { + const char *val = mReader->getAttributeValue(pAttrIdx); + std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); + const std::cregex_iterator wordItEnd; + pValue.clear(); + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::regex_match(match.str(), pattern_true); }); + } } void X3DImporter::XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector& pValue) { - std::list tlist; - - XML_ReadNode_GetAttrVal_AsListI32(pAttrIdx, tlist);// read as list - // and copy to array - if(tlist.size() > 0) - { - pValue.reserve(tlist.size()); - for(std::list::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue) -{ - std::string str_fixed; - - // at first check string values like '.xxx'. - ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), str_fixed); - - // and convert all values and place it in list. - const char* pstr = str_fixed.c_str(); - const char* pstr_end = pstr + str_fixed.size(); - - do - { - float tvalf; - - while((pstr < pstr_end) && (whitespace.find_first_of(*pstr) != std::string::npos)) pstr++;// skip spaces between values. - - if(pstr < pstr_end)// additional check, because attribute value can be ended with spaces. - { - pstr = fast_atoreal_move(pstr, tvalf, false); - pValue.push_back(tvalf); - } - } while(pstr < pstr_end); + auto intValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); + if (intValue) { + pValue = intValue->value; + } + else { + const char *val = mReader->getAttributeValue(pAttrIdx); + std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); + const std::cregex_iterator wordItEnd; + pValue.clear(); + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stoi(match.str()); }); + } } void X3DImporter::XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector& pValue) { - std::list tlist; - - XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list - // and copy to array - if(tlist.size() > 0) - { - pValue.reserve(tlist.size()); - for(std::list::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue) -{ - std::string str_fixed; - - // at first check string values like '.xxx'. - ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), str_fixed); - - // and convert all values and place it in list. - const char* pstr = str_fixed.c_str(); - const char* pstr_end = pstr + str_fixed.size(); - - do - { - double tvald; - - while((pstr < pstr_end) && (whitespace.find_first_of(*pstr) != std::string::npos)) pstr++;// skip spaces between values. - - if(pstr < pstr_end)// additional check, because attribute value can be ended with spaces. - { - pstr = fast_atoreal_move(pstr, tvald, false); - pValue.push_back(tvald); - } - } while(pstr < pstr_end); + auto floatValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); + if (floatValue) { + pValue = floatValue->value; + } + else { + const char *val = mReader->getAttributeValue(pAttrIdx); + std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); + const std::cregex_iterator wordItEnd; + pValue.clear(); + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stof(match.str()); }); + } } void X3DImporter::XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector& pValue) { - std::list tlist; - - XML_ReadNode_GetAttrVal_AsListD(pAttrIdx, tlist);// read as list - // and copy to array - if(tlist.size() > 0) - { - pValue.reserve(tlist.size()); - for(std::list::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it); - } + auto doubleValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); + if (doubleValue) { + pValue = doubleValue->value; + } + else { + const char *val = mReader->getAttributeValue(pAttrIdx); + std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); + const std::cregex_iterator wordItEnd; + pValue.clear(); + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stod(match.str()); }); + } } void X3DImporter::XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list& pValue) { - std::list tlist; + std::vector tlist; - XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list + XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list if(tlist.size() % 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx)); // copy data to array - for(std::list::iterator it = tlist.begin(); it != tlist.end();) + for(std::vector::iterator it = tlist.begin(); it != tlist.end();) { aiColor3D tcol; @@ -622,13 +559,13 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::ve void X3DImporter::XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list& pValue) { - std::list tlist; + std::vector tlist; - XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list + XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list if(tlist.size() % 4) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx)); // copy data to array - for(std::list::iterator it = tlist.begin(); it != tlist.end();) + for(std::vector::iterator it = tlist.begin(); it != tlist.end();) { aiColor4D tcol; @@ -658,16 +595,16 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::ve void X3DImporter::XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list& pValue) { - std::list tlist; + std::vector tlist; - XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list + XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list if ( tlist.size() % 2 ) { Throw_ConvertFail_Str2ArrF( mReader->getAttributeValue( pAttrIdx ) ); } // copy data to array - for(std::list::iterator it = tlist.begin(); it != tlist.end();) + for(std::vector::iterator it = tlist.begin(); it != tlist.end();) { aiVector2D tvec; @@ -695,16 +632,16 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::ve void X3DImporter::XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list& pValue) { - std::list tlist; + std::vector tlist; - XML_ReadNode_GetAttrVal_AsListF(pAttrIdx, tlist);// read as list + XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list if ( tlist.size() % 3 ) { Throw_ConvertFail_Str2ArrF( mReader->getAttributeValue( pAttrIdx ) ); } // copy data to array - for(std::list::iterator it = tlist.begin(); it != tlist.end();) + for(std::vector::iterator it = tlist.begin(); it != tlist.end();) { aiVector3D tvec; @@ -894,9 +831,9 @@ void X3DImporter::GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSi #undef MESH_RectParallelepiped_CREATE_VERT -void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::list& pCoordIdx, std::vector& pFaces, unsigned int& pPrimitiveTypes) const +void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::vector& pCoordIdx, std::vector& pFaces, unsigned int& pPrimitiveTypes) const { - std::list f_data(pCoordIdx); + std::vector f_data(pCoordIdx); std::vector inds; unsigned int prim_type = 0; @@ -909,7 +846,7 @@ void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::list& pFaces.reserve(f_data.size() / 3); inds.reserve(4); //PrintVectorSet("build. ci", pCoordIdx); - for(std::list::iterator it = f_data.begin(); it != f_data.end(); it++) + for(std::vector::iterator it = f_data.begin(); it != f_data.end(); it++) { // when face is got count how many indices in it. if(*it == (-1)) @@ -1001,7 +938,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, +void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector& pCoordIdx, const std::vector& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const { std::list tcol; @@ -1016,7 +953,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list& MeshGeometry_AddColor(pMesh, pCoordIdx, pColorIdx, tcol, pColorPerVertex); } -void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, +void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector& pCoordIdx, const std::vector& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const { std::vector col_tgt_arr; @@ -1047,7 +984,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list& } // create list with colors for every vertex. col_tgt_arr.resize(pMesh.mNumVertices); - for(std::list::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++) + for(std::vector::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++) { if ( *colidx_it == ( -1 ) ) { @@ -1095,7 +1032,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list& // create list with colors for every vertex using faces indices. col_tgt_arr.resize(pMesh.mNumFaces); - std::list::const_iterator colidx_it = pColorIdx.begin(); + std::vector::const_iterator colidx_it = pColorIdx.begin(); for(size_t fi = 0; fi < pMesh.mNumFaces; fi++) { if((unsigned int)*colidx_it > pMesh.mNumFaces) throw DeadlyImportError("MeshGeometry_AddColor2. Face idx is out of range."); @@ -1125,7 +1062,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list& MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex); } -void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pNormalIdx, +void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector& pCoordIdx, const std::vector& pNormalIdx, const std::list& pNormals, const bool pNormalPerVertex) const { std::vector tind; @@ -1146,7 +1083,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal."); tind.reserve(pNormalIdx.size()); - for(std::list::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++) + for(std::vector::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++) { if(*it != (-1)) tind.push_back(*it); } @@ -1178,7 +1115,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list { if(pMesh.mNumFaces != pNormalIdx.size()) throw DeadlyImportError("Normals faces count must be equal to mesh faces count."); - std::list::const_iterator normidx_it = pNormalIdx.begin(); + std::vector::const_iterator normidx_it = pNormalIdx.begin(); tind.reserve(pNormalIdx.size()); for(size_t i = 0, i_e = pNormalIdx.size(); i < i_e; i++) tind.push_back(*normidx_it++); @@ -1231,7 +1168,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pTexCoordIdx, +void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector& pCoordIdx, const std::vector& pTexCoordIdx, const std::list& pTexCoords) const { std::vector texcoord_arr_copy; @@ -1304,7 +1241,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pVertices) const +aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::vector& pCoordIdx, const std::list& pVertices) const { std::vector faces; unsigned int prim_type = 0; @@ -1407,9 +1344,12 @@ void X3DImporter::ParseHelper_FixTruncatedFloatString(const char* pInStr, std::s } } +extern FIVocabulary X3D_vocabulary_3_2; +extern FIVocabulary X3D_vocabulary_3_3; + void X3DImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler) { - irr::io::IrrXMLReader* OldReader = mReader;// store current XMLreader. + std::unique_ptr OldReader = std::move(mReader);// store current XMLreader. std::unique_ptr file(pIOHandler->Open(pFile, "rb")); // Check whether we can read from the file @@ -1417,19 +1357,18 @@ void X3DImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler) { throw DeadlyImportError( "Failed to open X3D file " + pFile + "." ); } - // generate a XML reader for it - std::unique_ptr mIOWrapper(new CIrrXML_IOStreamReader(file.get())); - mReader = irr::io::createIrrXMLReader(mIOWrapper.get()); + mReader = FIReader::create(file.get()); if ( !mReader ) { throw DeadlyImportError( "Failed to create XML reader for file" + pFile + "." ); } + mReader->registerVocabulary("urn:web3d:x3d:fi-vocabulary-3.2", &X3D_vocabulary_3_2); + mReader->registerVocabulary("urn:web3d:x3d:fi-vocabulary-3.3", &X3D_vocabulary_3_3); // start reading ParseNode_Root(); - delete mReader; // restore old XMLreader - mReader = OldReader; + mReader = std::move(OldReader); } void X3DImporter::ParseNode_Root() @@ -1643,7 +1582,7 @@ bool X3DImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool p { const std::string extension = GetExtension(pFile); - if(extension == "x3d") return true; + if((extension == "x3d") || (extension == "x3db")) return true; if(!extension.length() || pCheckSig) { @@ -1658,6 +1597,7 @@ bool X3DImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool p void X3DImporter::GetExtensionList(std::set& pExtensionList) { pExtensionList.insert("x3d"); + pExtensionList.insert("x3db"); } const aiImporterDesc* X3DImporter::GetInfo () const diff --git a/code/X3DImporter.hpp b/code/X3DImporter.hpp index e02d1ab61..58faefb49 100644 --- a/code/X3DImporter.hpp +++ b/code/X3DImporter.hpp @@ -56,6 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "BaseImporter.h" #include "irrXMLWrapper.h" +#include "FIReader.hpp" +#include namespace Assimp { @@ -449,33 +451,21 @@ private: /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. - void XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list& pValue); - - /// \overload void XML_ReadNode_GetAttrVal_AsListBool(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector& pValue); /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. - void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue); - - /// \overload void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector& pValue); /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. - void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue); - - /// \overload void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector& pValue); /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. - void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue); - - /// \overload void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector& pValue); /// Read attribute value. @@ -554,7 +544,7 @@ private: /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1". /// \param [in] pFaces - created faces array. /// \param [in] pPrimitiveTypes - type of primitives in faces. - void GeometryHelper_CoordIdxStr2FacesArr(const std::list& pCoordIdx, std::vector& pFaces, unsigned int& pPrimitiveTypes) const; + void GeometryHelper_CoordIdxStr2FacesArr(const std::vector& pCoordIdx, std::vector& pFaces, unsigned int& pPrimitiveTypes) const; /// Add colors to mesh. /// a. If colorPerVertex is FALSE, colours are applied to each face, as follows: @@ -573,11 +563,11 @@ private: /// then pColorIdx contain color indices for every faces and must not contain delimiter "-1". /// \param [in] pColors - defined colors. /// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face. - void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, + void MeshGeometry_AddColor(aiMesh& pMesh, const std::vector& pCoordIdx, const std::vector& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const; /// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const; - void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, + void MeshGeometry_AddColor(aiMesh& pMesh, const std::vector& pCoordIdx, const std::vector& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const; /// Add colors to mesh. @@ -590,14 +580,14 @@ private: void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const; /// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor; - void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pNormalIdx, + void MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector& pCoordIdx, const std::vector& pNormalIdx, const std::list& pNormals, const bool pNormalPerVertex) const; /// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor; void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pNormals, const bool pNormalPerVertex) const; /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor; - void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pTexCoordIdx, + void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector& pCoordIdx, const std::vector& pTexCoordIdx, const std::list& pTexCoords) const; /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor; @@ -607,7 +597,7 @@ private: /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1". /// \param [in] pVertices - vertices of mesh. /// \return created mesh. - aiMesh* GeometryHelper_MakeMesh(const std::list& pCoordIdx, const std::list& pVertices) const; + aiMesh* GeometryHelper_MakeMesh(const std::vector& pCoordIdx, const std::list& pVertices) const; /***********************************************/ /******** Functions: parse set private *********/ @@ -826,13 +816,15 @@ private: /****************** Constants ******************/ /***********************************************/ static const aiImporterDesc Description; - static const std::string whitespace; + static const std::regex pattern_nws; + static const std::regex pattern_true; + /***********************************************/ /****************** Variables ******************/ /***********************************************/ CX3DImporter_NodeElement* NodeElement_Cur;///< Current element. - irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object + std::unique_ptr mReader;///< Pointer to XML-reader object IOSystem *mpIOHandler; };// class X3DImporter diff --git a/code/X3DImporter_Geometry3D.cpp b/code/X3DImporter_Geometry3D.cpp index 10dde6501..721221f5c 100644 --- a/code/X3DImporter_Geometry3D.cpp +++ b/code/X3DImporter_Geometry3D.cpp @@ -285,7 +285,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid() bool ccw = true; bool colorPerVertex = true; float creaseAngle = 0; - std::list height; + std::vector height; bool normalPerVertex = true; bool solid = true; int32_t xDimension = 0; @@ -301,7 +301,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid() MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("height", height, XML_ReadNode_GetAttrVal_AsListF); + MACRO_ATTRREAD_CHECK_REF("height", height, XML_ReadNode_GetAttrVal_AsArrF); MACRO_ATTRREAD_CHECK_RET("xDimension", xDimension, XML_ReadNode_GetAttrVal_AsI32); MACRO_ATTRREAD_CHECK_RET("xSpacing", xSpacing, XML_ReadNode_GetAttrVal_AsFloat); MACRO_ATTRREAD_CHECK_RET("zDimension", zDimension, XML_ReadNode_GetAttrVal_AsI32); @@ -326,7 +326,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid() CX3DImporter_NodeElement_ElevationGrid& grid_alias = *((CX3DImporter_NodeElement_ElevationGrid*)ne);// create alias for conveience {// create grid vertices list - std::list::const_iterator he_it = height.begin(); + std::vector::const_iterator he_it = height.begin(); for(int32_t zi = 0; zi < zDimension; zi++)// rows { @@ -863,29 +863,29 @@ void X3DImporter::ParseNode_Geometry3D_IndexedFaceSet() { std::string use, def; bool ccw = true; - std::list colorIndex; + std::vector colorIndex; bool colorPerVertex = true; bool convex = true; - std::list coordIndex; + std::vector coordIndex; float creaseAngle = 0; - std::list normalIndex; + std::vector normalIndex; bool normalPerVertex = true; bool solid = true; - std::list texCoordIndex; + std::vector texCoordIndex; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("convex", convex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("normalIndex", normalIndex, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("normalIndex", normalIndex, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("texCoordIndex", texCoordIndex, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("texCoordIndex", texCoordIndex, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_LOOPEND; // if "USE" defined then find already defined element. diff --git a/code/X3DImporter_Metadata.cpp b/code/X3DImporter_Metadata.cpp index febc9cc2f..9d7147aea 100644 --- a/code/X3DImporter_Metadata.cpp +++ b/code/X3DImporter_Metadata.cpp @@ -123,14 +123,14 @@ void X3DImporter::ParseNode_MetadataBoolean() { std::string def, use; std::string name, reference; - std::list value; + std::vector value; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListB); + MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrB); MACRO_ATTRREAD_LOOPEND; MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaBoolean, "MetadataBoolean", ENET_MetaBoolean); @@ -147,14 +147,14 @@ void X3DImporter::ParseNode_MetadataDouble() { std::string def, use; std::string name, reference; - std::list value; + std::vector value; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListD); + MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrD); MACRO_ATTRREAD_LOOPEND; MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaDouble, "MetadataDouble", ENET_MetaDouble); @@ -171,14 +171,14 @@ void X3DImporter::ParseNode_MetadataFloat() { std::string def, use; std::string name, reference; - std::list value; + std::vector value; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListF); + MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrF); MACRO_ATTRREAD_LOOPEND; MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaFloat, "MetadataFloat", ENET_MetaFloat); @@ -195,14 +195,14 @@ void X3DImporter::ParseNode_MetadataInteger() { std::string def, use; std::string name, reference; - std::list value; + std::vector value; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_LOOPEND; MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaInteger, "MetadataInteger", ENET_MetaInteger); diff --git a/code/X3DImporter_Node.hpp b/code/X3DImporter_Node.hpp index 7061d06bc..6ed96c2f9 100644 --- a/code/X3DImporter_Node.hpp +++ b/code/X3DImporter_Node.hpp @@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Header files, stdlib. #include +#include #include /// \class CX3DImporter_NodeElement @@ -264,7 +265,7 @@ public: /// This struct describe metavalue of type boolean. struct CX3DImporter_NodeElement_MetaBoolean : public CX3DImporter_NodeElement_Meta { - std::list Value;///< Stored value. + std::vector Value;///< Stored value. /// \fn CX3DImporter_NodeElement_MetaBoolean(CX3DImporter_NodeElement* pParent) /// Constructor @@ -279,7 +280,7 @@ struct CX3DImporter_NodeElement_MetaBoolean : public CX3DImporter_NodeElement_Me /// This struct describe metavalue of type double. struct CX3DImporter_NodeElement_MetaDouble : public CX3DImporter_NodeElement_Meta { - std::list Value;///< Stored value. + std::vector Value;///< Stored value. /// \fn CX3DImporter_NodeElement_MetaDouble(CX3DImporter_NodeElement* pParent) /// Constructor @@ -294,7 +295,7 @@ struct CX3DImporter_NodeElement_MetaDouble : public CX3DImporter_NodeElement_Met /// This struct describe metavalue of type float. struct CX3DImporter_NodeElement_MetaFloat : public CX3DImporter_NodeElement_Meta { - std::list Value;///< Stored value. + std::vector Value;///< Stored value. /// \fn CX3DImporter_NodeElement_MetaFloat(CX3DImporter_NodeElement* pParent) /// Constructor @@ -309,7 +310,7 @@ struct CX3DImporter_NodeElement_MetaFloat : public CX3DImporter_NodeElement_Meta /// This struct describe metavalue of type integer. struct CX3DImporter_NodeElement_MetaInteger : public CX3DImporter_NodeElement_Meta { - std::list Value;///< Stored value. + std::vector Value;///< Stored value. /// \fn CX3DImporter_NodeElement_MetaInteger(CX3DImporter_NodeElement* pParent) /// Constructor @@ -508,7 +509,7 @@ public: /// If the angle between the geometric normals of two adjacent faces is less than the crease angle, normals shall be calculated so that the faces are /// shaded smoothly across the edge; otherwise, normals shall be calculated so that a lighting discontinuity across the edge is produced. float CreaseAngle; - std::list CoordIdx;///< Coordinates list by faces. In X3D format: "-1" - delimiter for faces. + std::vector CoordIdx;///< Coordinates list by faces. In X3D format: "-1" - delimiter for faces. /***********************************************/ /****************** Functions ******************/ @@ -554,21 +555,21 @@ public: /// direction. If normals are not generated but are supplied using a Normal node, and the orientation of the normals does not match the setting of the /// ccw field, results are undefined. bool CCW; - std::list ColorIndex;///< Field to specify the polygonal faces by indexing into the or . + std::vector ColorIndex;///< Field to specify the polygonal faces by indexing into the or . bool ColorPerVertex;///< If true then colors are defined for every vertex, else for every face(line). /// \var Convex /// The convex field indicates whether all polygons in the shape are convex (TRUE). A polygon is convex if it is planar, does not intersect itself, /// and all of the interior angles at its vertices are less than 180 degrees. Non planar and self intersecting polygons may produce undefined results /// even if the convex field is FALSE. bool Convex; - std::list CoordIndex;///< Field to specify the polygonal faces by indexing into the . + std::vector CoordIndex;///< Field to specify the polygonal faces by indexing into the . /// \var CreaseAngle /// If the angle between the geometric normals of two adjacent faces is less than the crease angle, normals shall be calculated so that the faces are /// shaded smoothly across the edge; otherwise, normals shall be calculated so that a lighting discontinuity across the edge is produced. float CreaseAngle; - std::list NormalIndex;///< Field to specify the polygonal faces by indexing into the . + std::vector NormalIndex;///< Field to specify the polygonal faces by indexing into the . bool NormalPerVertex;///< If true then normals are defined for every vertex, else for every face(line). - std::list TexCoordIndex;///< Field to specify the polygonal faces by indexing into the . + std::vector TexCoordIndex;///< Field to specify the polygonal faces by indexing into the . /***********************************************/ /****************** Functions ******************/ @@ -616,10 +617,10 @@ public: bool CCW; bool ColorPerVertex;///< If true then colors are defined for every vertex, else for every face(line). bool NormalPerVertex;///< If true then normals are defined for every vertex, else for every face(line). - std::list CoordIndex;///< Field to specify the polygonal faces by indexing into the . - std::list NormalIndex;///< Field to specify the polygonal faces by indexing into the . - std::list TexCoordIndex;///< Field to specify the polygonal faces by indexing into the . - std::list VertexCount;///< Field describes how many vertices are to be used in each polyline(polygon) from the field. + std::vector CoordIndex;///< Field to specify the polygonal faces by indexing into the . + std::vector NormalIndex;///< Field to specify the polygonal faces by indexing into the . + std::vector TexCoordIndex;///< Field to specify the polygonal faces by indexing into the . + std::vector VertexCount;///< Field describes how many vertices are to be used in each polyline(polygon) from the field. /***********************************************/ /****************** Functions ******************/ diff --git a/code/X3DImporter_Rendering.cpp b/code/X3DImporter_Rendering.cpp index 39a493030..1d4632f32 100644 --- a/code/X3DImporter_Rendering.cpp +++ b/code/X3DImporter_Rendering.cpp @@ -180,16 +180,16 @@ void X3DImporter::ParseNode_Rendering_Coordinate() void X3DImporter::ParseNode_Rendering_IndexedLineSet() { std::string use, def; - std::list colorIndex; + std::vector colorIndex; bool colorPerVertex = true; - std::list coordIndex; + std::vector coordIndex; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_LOOPEND; // if "USE" defined then find already defined element. @@ -256,7 +256,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet() std::string use, def; bool ccw = true; bool colorPerVertex = true; - std::list index; + std::vector index; bool normalPerVertex = true; bool solid = true; CX3DImporter_NodeElement* ne( nullptr ); @@ -265,7 +265,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet() MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_LOOPEND; @@ -294,7 +294,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet() ne_alias.CoordIndex.clear(); int counter = 0; int32_t idx[3]; - for(std::list::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) + for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) { idx[2] = *idx_it; if (idx[2] < 0) @@ -374,7 +374,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet() std::string use, def; bool ccw = true; bool colorPerVertex = true; - std::list index; + std::vector index; bool normalPerVertex = true; bool solid = true; CX3DImporter_NodeElement* ne( nullptr ); @@ -383,7 +383,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet() MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_LOOPEND; @@ -412,7 +412,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet() ne_alias.CoordIndex.clear(); int counter = 0; int32_t idx[3]; - for(std::list::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) + for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) { idx[counter++] = *idx_it; if (counter > 2) @@ -480,7 +480,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet() std::string use, def; bool ccw = true; bool colorPerVertex = true; - std::list index; + std::vector index; bool normalPerVertex = true; bool solid = true; CX3DImporter_NodeElement* ne( nullptr ); @@ -489,7 +489,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet() MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_LOOPEND; @@ -518,7 +518,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet() ne_alias.CoordIndex.clear(); int counter = 0; int32_t idx[3]; - for(std::list::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) + for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) { idx[2] = *idx_it; if (idx[2] < 0) @@ -587,12 +587,12 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet() void X3DImporter::ParseNode_Rendering_LineSet() { std::string use, def; - std::list vertexCount; + std::vector vertexCount; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("vertexCount", vertexCount, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("vertexCount", vertexCount, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_LOOPEND; // if "USE" defined then find already defined element. @@ -616,7 +616,7 @@ void X3DImporter::ParseNode_Rendering_LineSet() size_t coord_num = 0; ne_alias.CoordIndex.clear(); - for(std::list::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) + for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) { if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two."); @@ -722,7 +722,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet() std::string use, def; bool ccw = true; bool colorPerVertex = true; - std::list fanCount; + std::vector fanCount; bool normalPerVertex = true; bool solid = true; CX3DImporter_NodeElement* ne( nullptr ); @@ -731,7 +731,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet() MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("fanCount", fanCount, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("fanCount", fanCount, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_LOOPEND; @@ -764,7 +764,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet() // assign indices for first triangle coord_num_first = 0; coord_num_prev = 1; - for(std::list::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) + for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) { if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three."); @@ -913,7 +913,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet() std::string use, def; bool ccw = true; bool colorPerVertex = true; - std::list stripCount; + std::vector stripCount; bool normalPerVertex = true; bool solid = true; CX3DImporter_NodeElement* ne( nullptr ); @@ -922,7 +922,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet() MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("stripCount", stripCount, XML_ReadNode_GetAttrVal_AsListI32); + MACRO_ATTRREAD_CHECK_REF("stripCount", stripCount, XML_ReadNode_GetAttrVal_AsArrI32); MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); MACRO_ATTRREAD_LOOPEND; @@ -955,7 +955,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet() ne_alias.CoordIndex.clear(); coord_num_sb = 0; - for(std::list::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) + for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) { if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three."); diff --git a/code/X3DVocabulary.cpp b/code/X3DVocabulary.cpp new file mode 100644 index 000000000..780c4ffc2 --- /dev/null +++ b/code/X3DVocabulary.cpp @@ -0,0 +1,1675 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/// \file X3DVocabulary.cpp +/// \brief Vocabulary for Fast Infoset encoded binary X3D files. +/// \date 2017 +/// \author Patrick Daehne + +#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER + +#include "FIReader.hpp" + +namespace Assimp { + +static const char *encodingAlgorithmTable_3_2[] = { + "encoder://web3d.org/QuantizedFloatArrayEncoder", + "encoder://web3d.org/DeltazlibIntArrayEncoder", + "encoder://web3d.org/QuantizedzlibFloatArrayEncoder", + "encoder://web3d.org/zlibFloatArrayEncoder", + "encoder://web3d.org/QuantizedDoubleArrayEncoder", + "encoder://web3d.org/zlibDoubleArrayEncoder", + "encoder://web3d.org/QuantizedzlibDoubleArrayEncoder", + "encoder://web3d.org/RangeIntArrayEncoder" +}; + +static const std::shared_ptr attributeValueTable_3_2[] = { + FIStringValue::create("false"), + FIStringValue::create("true") +}; + +static const FIQName elementNameTable_3_2[] = { + { "Shape", nullptr, nullptr }, + { "Appearance", nullptr, nullptr }, + { "Material", nullptr, nullptr }, + { "IndexedFaceSet", nullptr, nullptr }, + { "ProtoInstance", nullptr, nullptr }, + { "Transform", nullptr, nullptr }, + { "ImageTexture", nullptr, nullptr }, + { "TextureTransform", nullptr, nullptr }, + { "Coordinate", nullptr, nullptr }, + { "Normal", nullptr, nullptr }, + { "Color", nullptr, nullptr }, + { "ColorRGBA", nullptr, nullptr }, + { "TextureCoordinate", nullptr, nullptr }, + { "ROUTE", nullptr, nullptr }, + { "fieldValue", nullptr, nullptr }, + { "Group", nullptr, nullptr }, + { "LOD", nullptr, nullptr }, + { "Switch", nullptr, nullptr }, + { "Script", nullptr, nullptr }, + { "IndexedTriangleFanSet", nullptr, nullptr }, + { "IndexedTriangleSet", nullptr, nullptr }, + { "IndexedTriangleStripSet", nullptr, nullptr }, + { "MultiTexture", nullptr, nullptr }, + { "MultiTextureCoordinate", nullptr, nullptr }, + { "MultiTextureTransform", nullptr, nullptr }, + { "IndexedLineSet", nullptr, nullptr }, + { "PointSet", nullptr, nullptr }, + { "StaticGroup", nullptr, nullptr }, + { "Sphere", nullptr, nullptr }, + { "Box", nullptr, nullptr }, + { "Cone", nullptr, nullptr }, + { "Anchor", nullptr, nullptr }, + { "Arc2D", nullptr, nullptr }, + { "ArcClose2D", nullptr, nullptr }, + { "AudioClip", nullptr, nullptr }, + { "Background", nullptr, nullptr }, + { "Billboard", nullptr, nullptr }, + { "BooleanFilter", nullptr, nullptr }, + { "BooleanSequencer", nullptr, nullptr }, + { "BooleanToggle", nullptr, nullptr }, + { "BooleanTrigger", nullptr, nullptr }, + { "Circle2D", nullptr, nullptr }, + { "Collision", nullptr, nullptr }, + { "ColorInterpolator", nullptr, nullptr }, + { "Contour2D", nullptr, nullptr }, + { "ContourPolyline2D", nullptr, nullptr }, + { "CoordinateDouble", nullptr, nullptr }, + { "CoordinateInterpolator", nullptr, nullptr }, + { "CoordinateInterpolator2D", nullptr, nullptr }, + { "Cylinder", nullptr, nullptr }, + { "CylinderSensor", nullptr, nullptr }, + { "DirectionalLight", nullptr, nullptr }, + { "Disk2D", nullptr, nullptr }, + { "EXPORT", nullptr, nullptr }, + { "ElevationGrid", nullptr, nullptr }, + { "EspduTransform", nullptr, nullptr }, + { "ExternProtoDeclare", nullptr, nullptr }, + { "Extrusion", nullptr, nullptr }, + { "FillProperties", nullptr, nullptr }, + { "Fog", nullptr, nullptr }, + { "FontStyle", nullptr, nullptr }, + { "GeoCoordinate", nullptr, nullptr }, + { "GeoElevationGrid", nullptr, nullptr }, + { "GeoLOD", nullptr, nullptr }, + { "GeoLocation", nullptr, nullptr }, + { "GeoMetadata", nullptr, nullptr }, + { "GeoOrigin", nullptr, nullptr }, + { "GeoPositionInterpolator", nullptr, nullptr }, + { "GeoTouchSensor", nullptr, nullptr }, + { "GeoViewpoint", nullptr, nullptr }, + { "HAnimDisplacer", nullptr, nullptr }, + { "HAnimHumanoid", nullptr, nullptr }, + { "HAnimJoint", nullptr, nullptr }, + { "HAnimSegment", nullptr, nullptr }, + { "HAnimSite", nullptr, nullptr }, + { "IMPORT", nullptr, nullptr }, + { "IS", nullptr, nullptr }, + { "Inline", nullptr, nullptr }, + { "IntegerSequencer", nullptr, nullptr }, + { "IntegerTrigger", nullptr, nullptr }, + { "KeySensor", nullptr, nullptr }, + { "LineProperties", nullptr, nullptr }, + { "LineSet", nullptr, nullptr }, + { "LoadSensor", nullptr, nullptr }, + { "MetadataDouble", nullptr, nullptr }, + { "MetadataFloat", nullptr, nullptr }, + { "MetadataInteger", nullptr, nullptr }, + { "MetadataSet", nullptr, nullptr }, + { "MetadataString", nullptr, nullptr }, + { "MovieTexture", nullptr, nullptr }, + { "NavigationInfo", nullptr, nullptr }, + { "NormalInterpolator", nullptr, nullptr }, + { "NurbsCurve", nullptr, nullptr }, + { "NurbsCurve2D", nullptr, nullptr }, + { "NurbsOrientationInterpolator", nullptr, nullptr }, + { "NurbsPatchSurface", nullptr, nullptr }, + { "NurbsPositionInterpolator", nullptr, nullptr }, + { "NurbsSet", nullptr, nullptr }, + { "NurbsSurfaceInterpolator", nullptr, nullptr }, + { "NurbsSweptSurface", nullptr, nullptr }, + { "NurbsSwungSurface", nullptr, nullptr }, + { "NurbsTextureCoordinate", nullptr, nullptr }, + { "NurbsTrimmedSurface", nullptr, nullptr }, + { "OrientationInterpolator", nullptr, nullptr }, + { "PixelTexture", nullptr, nullptr }, + { "PlaneSensor", nullptr, nullptr }, + { "PointLight", nullptr, nullptr }, + { "Polyline2D", nullptr, nullptr }, + { "Polypoint2D", nullptr, nullptr }, + { "PositionInterpolator", nullptr, nullptr }, + { "PositionInterpolator2D", nullptr, nullptr }, + { "ProtoBody", nullptr, nullptr }, + { "ProtoDeclare", nullptr, nullptr }, + { "ProtoInterface", nullptr, nullptr }, + { "ProximitySensor", nullptr, nullptr }, + { "ReceiverPdu", nullptr, nullptr }, + { "Rectangle2D", nullptr, nullptr }, + { "ScalarInterpolator", nullptr, nullptr }, + { "Scene", nullptr, nullptr }, + { "SignalPdu", nullptr, nullptr }, + { "Sound", nullptr, nullptr }, + { "SphereSensor", nullptr, nullptr }, + { "SpotLight", nullptr, nullptr }, + { "StringSensor", nullptr, nullptr }, + { "Text", nullptr, nullptr }, + { "TextureBackground", nullptr, nullptr }, + { "TextureCoordinateGenerator", nullptr, nullptr }, + { "TimeSensor", nullptr, nullptr }, + { "TimeTrigger", nullptr, nullptr }, + { "TouchSensor", nullptr, nullptr }, + { "TransmitterPdu", nullptr, nullptr }, + { "TriangleFanSet", nullptr, nullptr }, + { "TriangleSet", nullptr, nullptr }, + { "TriangleSet2D", nullptr, nullptr }, + { "TriangleStripSet", nullptr, nullptr }, + { "Viewpoint", nullptr, nullptr }, + { "VisibilitySensor", nullptr, nullptr }, + { "WorldInfo", nullptr, nullptr }, + { "X3D", nullptr, nullptr }, + { "component", nullptr, nullptr }, + { "connect", nullptr, nullptr }, + { "field", nullptr, nullptr }, + { "head", nullptr, nullptr }, + { "humanoidBodyType", nullptr, nullptr }, + { "meta", nullptr, nullptr }, + { "CADAssembly", nullptr, nullptr }, + { "CADFace", nullptr, nullptr }, + { "CADLayer", nullptr, nullptr }, + { "CADPart", nullptr, nullptr }, + { "ComposedCubeMapTexture", nullptr, nullptr }, + { "ComposedShader", nullptr, nullptr }, + { "ComposedTexture3D", nullptr, nullptr }, + { "FloatVertexAttribute", nullptr, nullptr }, + { "FogCoordinate", nullptr, nullptr }, + { "GeneratedCubeMapTexture", nullptr, nullptr }, + { "ImageCubeMapTexture", nullptr, nullptr }, + { "ImageTexture3D", nullptr, nullptr }, + { "IndexedQuadSet", nullptr, nullptr }, + { "LocalFog", nullptr, nullptr }, + { "Matrix3VertexAttribute", nullptr, nullptr }, + { "Matrix4VertexAttribute", nullptr, nullptr }, + { "PackagedShader", nullptr, nullptr }, + { "PixelTexture3D", nullptr, nullptr }, + { "ProgramShader", nullptr, nullptr }, + { "QuadSet", nullptr, nullptr }, + { "ShaderPart", nullptr, nullptr }, + { "ShaderProgram", nullptr, nullptr }, + { "TextureCoordinate3D", nullptr, nullptr }, + { "TextureCoordinate4D", nullptr, nullptr }, + { "TextureTransform3D", nullptr, nullptr }, + { "TextureTransformMatrix3D", nullptr, nullptr }, + { "BallJoint", nullptr, nullptr }, + { "BoundedPhysicsModel", nullptr, nullptr }, + { "ClipPlane", nullptr, nullptr }, + { "CollidableOffset", nullptr, nullptr }, + { "CollidableShape", nullptr, nullptr }, + { "CollisionCollection", nullptr, nullptr }, + { "CollisionSensor", nullptr, nullptr }, + { "CollisionSpace", nullptr, nullptr }, + { "ColorDamper", nullptr, nullptr }, + { "ConeEmitter", nullptr, nullptr }, + { "Contact", nullptr, nullptr }, + { "CoordinateDamper", nullptr, nullptr }, + { "DISEntityManager", nullptr, nullptr }, + { "DISEntityTypeMapping", nullptr, nullptr }, + { "DoubleAxisHingeJoint", nullptr, nullptr }, + { "EaseInEaseOut", nullptr, nullptr }, + { "ExplosionEmitter", nullptr, nullptr }, + { "ForcePhysicsModel", nullptr, nullptr }, + { "GeoProximitySensor", nullptr, nullptr }, + { "GeoTransform", nullptr, nullptr }, + { "Layer", nullptr, nullptr }, + { "LayerSet", nullptr, nullptr }, + { "Layout", nullptr, nullptr }, + { "LayoutGroup", nullptr, nullptr }, + { "LayoutLayer", nullptr, nullptr }, + { "LinePickSensor", nullptr, nullptr }, + { "MotorJoint", nullptr, nullptr }, + { "OrientationChaser", nullptr, nullptr }, + { "OrientationDamper", nullptr, nullptr }, + { "OrthoViewpoint", nullptr, nullptr }, + { "ParticleSystem", nullptr, nullptr }, + { "PickableGroup", nullptr, nullptr }, + { "PointEmitter", nullptr, nullptr }, + { "PointPickSensor", nullptr, nullptr }, + { "PolylineEmitter", nullptr, nullptr }, + { "PositionChaser", nullptr, nullptr }, + { "PositionChaser2D", nullptr, nullptr }, + { "PositionDamper", nullptr, nullptr }, + { "PositionDamper2D", nullptr, nullptr }, + { "PrimitivePickSensor", nullptr, nullptr }, + { "RigidBody", nullptr, nullptr }, + { "RigidBodyCollection", nullptr, nullptr }, + { "ScalarChaser", nullptr, nullptr }, + { "ScreenFontStyle", nullptr, nullptr }, + { "ScreenGroup", nullptr, nullptr }, + { "SingleAxisHingeJoint", nullptr, nullptr }, + { "SliderJoint", nullptr, nullptr }, + { "SplinePositionInterpolator", nullptr, nullptr }, + { "SplinePositionInterpolator2D", nullptr, nullptr }, + { "SplineScalarInterpolator", nullptr, nullptr }, + { "SquadOrientationInterpolator", nullptr, nullptr }, + { "SurfaceEmitter", nullptr, nullptr }, + { "TexCoordDamper", nullptr, nullptr }, + { "TextureProperties", nullptr, nullptr }, + { "TransformSensor", nullptr, nullptr }, + { "TwoSidedMaterial", nullptr, nullptr }, + { "UniversalJoint", nullptr, nullptr }, + { "ViewpointGroup", nullptr, nullptr }, + { "Viewport", nullptr, nullptr }, + { "VolumeEmitter", nullptr, nullptr }, + { "VolumePickSensor", nullptr, nullptr }, + { "WindPhysicsModel", nullptr, nullptr } +}; + +static const FIQName attributeNameTable_3_2[] = { + { "DEF", nullptr, nullptr }, + { "USE", nullptr, nullptr }, + { "containerField", nullptr, nullptr }, + { "fromNode", nullptr, nullptr }, + { "fromField", nullptr, nullptr }, + { "toNode", nullptr, nullptr }, + { "toField", nullptr, nullptr }, + { "name", nullptr, nullptr }, + { "value", nullptr, nullptr }, + { "color", nullptr, nullptr }, + { "colorIndex", nullptr, nullptr }, + { "coordIndex", nullptr, nullptr }, + { "texCoordIndex", nullptr, nullptr }, + { "normalIndex", nullptr, nullptr }, + { "colorPerVertex", nullptr, nullptr }, + { "normalPerVertex", nullptr, nullptr }, + { "rotation", nullptr, nullptr }, + { "scale", nullptr, nullptr }, + { "center", nullptr, nullptr }, + { "scaleOrientation", nullptr, nullptr }, + { "translation", nullptr, nullptr }, + { "url", nullptr, nullptr }, + { "repeatS", nullptr, nullptr }, + { "repeatT", nullptr, nullptr }, + { "point", nullptr, nullptr }, + { "vector", nullptr, nullptr }, + { "range", nullptr, nullptr }, + { "ambientIntensity", nullptr, nullptr }, + { "diffuseColor", nullptr, nullptr }, + { "emissiveColor", nullptr, nullptr }, + { "shininess", nullptr, nullptr }, + { "specularColor", nullptr, nullptr }, + { "transparency", nullptr, nullptr }, + { "whichChoice", nullptr, nullptr }, + { "index", nullptr, nullptr }, + { "mode", nullptr, nullptr }, + { "source", nullptr, nullptr }, + { "function", nullptr, nullptr }, + { "alpha", nullptr, nullptr }, + { "vertexCount", nullptr, nullptr }, + { "radius", nullptr, nullptr }, + { "size", nullptr, nullptr }, + { "height", nullptr, nullptr }, + { "solid", nullptr, nullptr }, + { "ccw", nullptr, nullptr }, + { "key", nullptr, nullptr }, + { "keyValue", nullptr, nullptr }, + { "enabled", nullptr, nullptr }, + { "direction", nullptr, nullptr }, + { "position", nullptr, nullptr }, + { "orientation", nullptr, nullptr }, + { "bboxCenter", nullptr, nullptr }, + { "bboxSize", nullptr, nullptr }, + { "AS", nullptr, nullptr }, + { "InlineDEF", nullptr, nullptr }, + { "accessType", nullptr, nullptr }, + { "actionKeyPress", nullptr, nullptr }, + { "actionKeyRelease", nullptr, nullptr }, + { "address", nullptr, nullptr }, + { "altKey", nullptr, nullptr }, + { "antennaLocation", nullptr, nullptr }, + { "antennaPatternLength", nullptr, nullptr }, + { "antennaPatternType", nullptr, nullptr }, + { "applicationID", nullptr, nullptr }, + { "articulationParameterArray", nullptr, nullptr }, + { "articulationParameterChangeIndicatorArray", nullptr, nullptr }, + { "articulationParameterCount", nullptr, nullptr }, + { "articulationParameterDesignatorArray", nullptr, nullptr }, + { "articulationParameterIdPartAttachedArray", nullptr, nullptr }, + { "articulationParameterTypeArray", nullptr, nullptr }, + { "attenuation", nullptr, nullptr }, + { "autoOffset", nullptr, nullptr }, + { "avatarSize", nullptr, nullptr }, + { "axisOfRotation", nullptr, nullptr }, + { "backUrl", nullptr, nullptr }, + { "beamWidth", nullptr, nullptr }, + { "beginCap", nullptr, nullptr }, + { "bindTime", nullptr, nullptr }, + { "bottom", nullptr, nullptr }, + { "bottomRadius", nullptr, nullptr }, + { "bottomUrl", nullptr, nullptr }, + { "centerOfMass", nullptr, nullptr }, + { "centerOfRotation", nullptr, nullptr }, + { "child1Url", nullptr, nullptr }, + { "child2Url", nullptr, nullptr }, + { "child3Url", nullptr, nullptr }, + { "child4Url", nullptr, nullptr }, + { "class", nullptr, nullptr }, + { "closureType", nullptr, nullptr }, + { "collideTime", nullptr, nullptr }, + { "content", nullptr, nullptr }, + { "controlKey", nullptr, nullptr }, + { "controlPoint", nullptr, nullptr }, + { "convex", nullptr, nullptr }, + { "coordinateSystem", nullptr, nullptr }, + { "copyright", nullptr, nullptr }, + { "creaseAngle", nullptr, nullptr }, + { "crossSection", nullptr, nullptr }, + { "cryptoKeyID", nullptr, nullptr }, + { "cryptoSystem", nullptr, nullptr }, + { "cutOffAngle", nullptr, nullptr }, + { "cycleInterval", nullptr, nullptr }, + { "cycleTime", nullptr, nullptr }, + { "data", nullptr, nullptr }, + { "dataFormat", nullptr, nullptr }, + { "dataLength", nullptr, nullptr }, + { "dataUrl", nullptr, nullptr }, + { "date", nullptr, nullptr }, + { "deadReckoning", nullptr, nullptr }, + { "deletionAllowed", nullptr, nullptr }, + { "description", nullptr, nullptr }, + { "detonateTime", nullptr, nullptr }, + { "dir", nullptr, nullptr }, + { "directOutput", nullptr, nullptr }, + { "diskAngle", nullptr, nullptr }, + { "displacements", nullptr, nullptr }, + { "documentation", nullptr, nullptr }, + { "elapsedTime", nullptr, nullptr }, + { "ellipsoid", nullptr, nullptr }, + { "encodingScheme", nullptr, nullptr }, + { "endAngle", nullptr, nullptr }, + { "endCap", nullptr, nullptr }, + { "enterTime", nullptr, nullptr }, + { "enteredText", nullptr, nullptr }, + { "entityCategory", nullptr, nullptr }, + { "entityCountry", nullptr, nullptr }, + { "entityDomain", nullptr, nullptr }, + { "entityExtra", nullptr, nullptr }, + { "entityID", nullptr, nullptr }, + { "entityKind", nullptr, nullptr }, + { "entitySpecific", nullptr, nullptr }, + { "entitySubCategory", nullptr, nullptr }, + { "exitTime", nullptr, nullptr }, + { "extent", nullptr, nullptr }, + { "family", nullptr, nullptr }, + { "fanCount", nullptr, nullptr }, + { "fieldOfView", nullptr, nullptr }, + { "filled", nullptr, nullptr }, + { "finalText", nullptr, nullptr }, + { "fireMissionIndex", nullptr, nullptr }, + { "fired1", nullptr, nullptr }, + { "fired2", nullptr, nullptr }, + { "firedTime", nullptr, nullptr }, + { "firingRange", nullptr, nullptr }, + { "firingRate", nullptr, nullptr }, + { "fogType", nullptr, nullptr }, + { "forceID", nullptr, nullptr }, + { "frequency", nullptr, nullptr }, + { "frontUrl", nullptr, nullptr }, + { "fuse", nullptr, nullptr }, + { "geoCoords", nullptr, nullptr }, + { "geoGridOrigin", nullptr, nullptr }, + { "geoSystem", nullptr, nullptr }, + { "groundAngle", nullptr, nullptr }, + { "groundColor", nullptr, nullptr }, + { "hatchColor", nullptr, nullptr }, + { "hatchStyle", nullptr, nullptr }, + { "hatched", nullptr, nullptr }, + { "headlight", nullptr, nullptr }, + { "horizontal", nullptr, nullptr }, + { "horizontalDatum", nullptr, nullptr }, + { "http-equiv", nullptr, nullptr }, + { "image", nullptr, nullptr }, + { "importedDEF", nullptr, nullptr }, + { "info", nullptr, nullptr }, + { "innerRadius", nullptr, nullptr }, + { "inputFalse", nullptr, nullptr }, + { "inputNegate", nullptr, nullptr }, + { "inputSource", nullptr, nullptr }, + { "inputTrue", nullptr, nullptr }, + { "integerKey", nullptr, nullptr }, + { "intensity", nullptr, nullptr }, + { "jump", nullptr, nullptr }, + { "justify", nullptr, nullptr }, + { "keyPress", nullptr, nullptr }, + { "keyRelease", nullptr, nullptr }, + { "knot", nullptr, nullptr }, + { "lang", nullptr, nullptr }, + { "language", nullptr, nullptr }, + { "leftToRight", nullptr, nullptr }, + { "leftUrl", nullptr, nullptr }, + { "length", nullptr, nullptr }, + { "lengthOfModulationParameters", nullptr, nullptr }, + { "level", nullptr, nullptr }, + { "limitOrientation", nullptr, nullptr }, + { "lineSegments", nullptr, nullptr }, + { "linearAcceleration", nullptr, nullptr }, + { "linearVelocity", nullptr, nullptr }, + { "linetype", nullptr, nullptr }, + { "linewidthScaleFactor", nullptr, nullptr }, + { "llimit", nullptr, nullptr }, + { "load", nullptr, nullptr }, + { "loadTime", nullptr, nullptr }, + { "localDEF", nullptr, nullptr }, + { "location", nullptr, nullptr }, + { "loop", nullptr, nullptr }, + { "marking", nullptr, nullptr }, + { "mass", nullptr, nullptr }, + { "maxAngle", nullptr, nullptr }, + { "maxBack", nullptr, nullptr }, + { "maxExtent", nullptr, nullptr }, + { "maxFront", nullptr, nullptr }, + { "maxPosition", nullptr, nullptr }, + { "metadataFormat", nullptr, nullptr }, + { "minAngle", nullptr, nullptr }, + { "minBack", nullptr, nullptr }, + { "minFront", nullptr, nullptr }, + { "minPosition", nullptr, nullptr }, + { "modulationTypeDetail", nullptr, nullptr }, + { "modulationTypeMajor", nullptr, nullptr }, + { "modulationTypeSpreadSpectrum", nullptr, nullptr }, + { "modulationTypeSystem", nullptr, nullptr }, + { "momentsOfInertia", nullptr, nullptr }, + { "multicastRelayHost", nullptr, nullptr }, + { "multicastRelayPort", nullptr, nullptr }, + { "munitionApplicationID", nullptr, nullptr }, + { "munitionEndPoint", nullptr, nullptr }, + { "munitionEntityID", nullptr, nullptr }, + { "munitionQuantity", nullptr, nullptr }, + { "munitionSiteID", nullptr, nullptr }, + { "munitionStartPoint", nullptr, nullptr }, + { "mustEvaluate", nullptr, nullptr }, + { "navType", nullptr, nullptr }, + { "networkMode", nullptr, nullptr }, + { "next", nullptr, nullptr }, + { "nodeField", nullptr, nullptr }, + { "offset", nullptr, nullptr }, + { "on", nullptr, nullptr }, + { "order", nullptr, nullptr }, + { "originator", nullptr, nullptr }, + { "outerRadius", nullptr, nullptr }, + { "parameter", nullptr, nullptr }, + { "pauseTime", nullptr, nullptr }, + { "pitch", nullptr, nullptr }, + { "points", nullptr, nullptr }, + { "port", nullptr, nullptr }, + { "power", nullptr, nullptr }, + { "previous", nullptr, nullptr }, + { "priority", nullptr, nullptr }, + { "profile", nullptr, nullptr }, + { "progress", nullptr, nullptr }, + { "protoField", nullptr, nullptr }, + { "radioEntityTypeCategory", nullptr, nullptr }, + { "radioEntityTypeCountry", nullptr, nullptr }, + { "radioEntityTypeDomain", nullptr, nullptr }, + { "radioEntityTypeKind", nullptr, nullptr }, + { "radioEntityTypeNomenclature", nullptr, nullptr }, + { "radioEntityTypeNomenclatureVersion", nullptr, nullptr }, + { "radioID", nullptr, nullptr }, + { "readInterval", nullptr, nullptr }, + { "receivedPower", nullptr, nullptr }, + { "receiverState", nullptr, nullptr }, + { "reference", nullptr, nullptr }, + { "relativeAntennaLocation", nullptr, nullptr }, + { "resolution", nullptr, nullptr }, + { "resumeTime", nullptr, nullptr }, + { "rightUrl", nullptr, nullptr }, + { "rootUrl", nullptr, nullptr }, + { "rotateYUp", nullptr, nullptr }, + { "rtpHeaderExpected", nullptr, nullptr }, + { "sampleRate", nullptr, nullptr }, + { "samples", nullptr, nullptr }, + { "shiftKey", nullptr, nullptr }, + { "side", nullptr, nullptr }, + { "siteID", nullptr, nullptr }, + { "skinCoordIndex", nullptr, nullptr }, + { "skinCoordWeight", nullptr, nullptr }, + { "skyAngle", nullptr, nullptr }, + { "skyColor", nullptr, nullptr }, + { "spacing", nullptr, nullptr }, + { "spatialize", nullptr, nullptr }, + { "speed", nullptr, nullptr }, + { "speedFactor", nullptr, nullptr }, + { "spine", nullptr, nullptr }, + { "startAngle", nullptr, nullptr }, + { "startTime", nullptr, nullptr }, + { "stiffness", nullptr, nullptr }, + { "stopTime", nullptr, nullptr }, + { "string", nullptr, nullptr }, + { "stripCount", nullptr, nullptr }, + { "style", nullptr, nullptr }, + { "summary", nullptr, nullptr }, + { "tdlType", nullptr, nullptr }, + { "tessellation", nullptr, nullptr }, + { "tessellationScale", nullptr, nullptr }, + { "time", nullptr, nullptr }, + { "timeOut", nullptr, nullptr }, + { "timestamp", nullptr, nullptr }, + { "title", nullptr, nullptr }, + { "toggle", nullptr, nullptr }, + { "top", nullptr, nullptr }, + { "topToBottom", nullptr, nullptr }, + { "topUrl", nullptr, nullptr }, + { "touchTime", nullptr, nullptr }, + { "transmitFrequencyBandwidth", nullptr, nullptr }, + { "transmitState", nullptr, nullptr }, + { "transmitterApplicationID", nullptr, nullptr }, + { "transmitterEntityID", nullptr, nullptr }, + { "transmitterRadioID", nullptr, nullptr }, + { "transmitterSiteID", nullptr, nullptr }, + { "transparent", nullptr, nullptr }, + { "triggerTime", nullptr, nullptr }, + { "triggerTrue", nullptr, nullptr }, + { "triggerValue", nullptr, nullptr }, + { "type", nullptr, nullptr }, + { "uDimension", nullptr, nullptr }, + { "uKnot", nullptr, nullptr }, + { "uOrder", nullptr, nullptr }, + { "uTessellation", nullptr, nullptr }, + { "ulimit", nullptr, nullptr }, + { "vDimension", nullptr, nullptr }, + { "vKnot", nullptr, nullptr }, + { "vOrder", nullptr, nullptr }, + { "vTessellation", nullptr, nullptr }, + { "version", nullptr, nullptr }, + { "verticalDatum", nullptr, nullptr }, + { "vertices", nullptr, nullptr }, + { "visibilityLimit", nullptr, nullptr }, + { "visibilityRange", nullptr, nullptr }, + { "warhead", nullptr, nullptr }, + { "weight", nullptr, nullptr }, + { "whichGeometry", nullptr, nullptr }, + { "writeInterval", nullptr, nullptr }, + { "xDimension", nullptr, nullptr }, + { "xSpacing", nullptr, nullptr }, + { "yScale", nullptr, nullptr }, + { "zDimension", nullptr, nullptr }, + { "zSpacing", nullptr, nullptr }, + { "visible", nullptr, nullptr }, + { "repeatR", nullptr, nullptr }, + { "texture", nullptr, nullptr }, + { "back", nullptr, nullptr }, + { "front", nullptr, nullptr }, + { "left", nullptr, nullptr }, + { "right", nullptr, nullptr }, + { "parts", nullptr, nullptr }, + { "isSelected", nullptr, nullptr }, + { "isValid", nullptr, nullptr }, + { "numComponents", nullptr, nullptr }, + { "depth", nullptr, nullptr }, + { "update", nullptr, nullptr }, + { "fogCoord", nullptr, nullptr }, + { "texCoord", nullptr, nullptr }, + { "activate", nullptr, nullptr }, + { "programs", nullptr, nullptr }, + { "matrix", nullptr, nullptr }, + { "anchorPoint", nullptr, nullptr }, + { "body1", nullptr, nullptr }, + { "body2", nullptr, nullptr }, + { "mustOutput", nullptr, nullptr }, + { "body1AnchorPoint", nullptr, nullptr }, + { "body2AnchorPoint", nullptr, nullptr }, + { "plane", nullptr, nullptr }, + { "appliedParameters", nullptr, nullptr }, + { "bounce", nullptr, nullptr }, + { "frictionCoefficients", nullptr, nullptr }, + { "minBounceSpeed", nullptr, nullptr }, + { "slipFactors", nullptr, nullptr }, + { "softnessConstantForceMix", nullptr, nullptr }, + { "softnessErrorCorrection", nullptr, nullptr }, + { "surfaceSpeed", nullptr, nullptr }, + { "isActive", nullptr, nullptr }, + { "useGeometry", nullptr, nullptr }, + { "set_destination", nullptr, nullptr }, + { "set_value", nullptr, nullptr }, + { "tau", nullptr, nullptr }, + { "tolerance", nullptr, nullptr }, + { "value_changed", nullptr, nullptr }, + { "initialDestination", nullptr, nullptr }, + { "initialValue", nullptr, nullptr }, + { "angle", nullptr, nullptr }, + { "variation", nullptr, nullptr }, + { "surfaceArea", nullptr, nullptr }, + { "frictionDirection", nullptr, nullptr }, + { "slipCoefficients", nullptr, nullptr }, + { "category", nullptr, nullptr }, + { "country", nullptr, nullptr }, + { "domain", nullptr, nullptr }, + { "extra", nullptr, nullptr }, + { "kind", nullptr, nullptr }, + { "specific", nullptr, nullptr }, + { "subcategory", nullptr, nullptr }, + { "axis1", nullptr, nullptr }, + { "axis2", nullptr, nullptr }, + { "desiredAngularVelocity1", nullptr, nullptr }, + { "desiredAngularVelocity2", nullptr, nullptr }, + { "maxAngle1", nullptr, nullptr }, + { "maxTorque1", nullptr, nullptr }, + { "maxTorque2", nullptr, nullptr }, + { "minAngle1", nullptr, nullptr }, + { "stopBounce1", nullptr, nullptr }, + { "stopConstantForceMix1", nullptr, nullptr }, + { "stopErrorCorrection1", nullptr, nullptr }, + { "suspensionErrorCorrection", nullptr, nullptr }, + { "suspensionForce", nullptr, nullptr }, + { "body1Axis", nullptr, nullptr }, + { "body2Axis", nullptr, nullptr }, + { "hinge1Angle", nullptr, nullptr }, + { "hinge1AngleRate", nullptr, nullptr }, + { "hinge2Angle", nullptr, nullptr }, + { "hinge2AngleRate", nullptr, nullptr }, + { "set_fraction", nullptr, nullptr }, + { "easeInEaseOut", nullptr, nullptr }, + { "modifiedFraction_changed", nullptr, nullptr }, + { "force", nullptr, nullptr }, + { "geoCenter", nullptr, nullptr }, + { "centerOfRotation_changed", nullptr, nullptr }, + { "geoCoord_changed", nullptr, nullptr }, + { "orientation_changed", nullptr, nullptr }, + { "position_changed", nullptr, nullptr }, + { "isPickable", nullptr, nullptr }, + { "viewport", nullptr, nullptr }, + { "activeLayer", nullptr, nullptr }, + { "align", nullptr, nullptr }, + { "offsetUnits", nullptr, nullptr }, + { "scaleMode", nullptr, nullptr }, + { "sizeUnits", nullptr, nullptr }, + { "layout", nullptr, nullptr }, + { "objectType", nullptr, nullptr }, + { "pickedNormal", nullptr, nullptr }, + { "pickedPoint", nullptr, nullptr }, + { "pickedTextureCoordinate", nullptr, nullptr }, + { "intersectionType", nullptr, nullptr }, + { "sortOrder", nullptr, nullptr }, + { "axis1Angle", nullptr, nullptr }, + { "axis1Torque", nullptr, nullptr }, + { "axis2Angle", nullptr, nullptr }, + { "axis2Torque", nullptr, nullptr }, + { "axis3Angle", nullptr, nullptr }, + { "axis3Torque", nullptr, nullptr }, + { "enabledAxies", nullptr, nullptr }, + { "motor1Axis", nullptr, nullptr }, + { "motor2Axis", nullptr, nullptr }, + { "motor3Axis", nullptr, nullptr }, + { "stop1Bounce", nullptr, nullptr }, + { "stop1ErrorCorrection", nullptr, nullptr }, + { "stop2Bounce", nullptr, nullptr }, + { "stop2ErrorCorrection", nullptr, nullptr }, + { "stop3Bounce", nullptr, nullptr }, + { "stop3ErrorCorrection", nullptr, nullptr }, + { "motor1Angle", nullptr, nullptr }, + { "motor1AngleRate", nullptr, nullptr }, + { "motor2Angle", nullptr, nullptr }, + { "motor2AngleRate", nullptr, nullptr }, + { "motor3Angle", nullptr, nullptr }, + { "motor3AngleRate", nullptr, nullptr }, + { "autoCalc", nullptr, nullptr }, + { "duration", nullptr, nullptr }, + { "retainUserOffsets", nullptr, nullptr }, + { "isBound", nullptr, nullptr }, + { "appearance", nullptr, nullptr }, + { "createParticles", nullptr, nullptr }, + { "lifetimeVariation", nullptr, nullptr }, + { "maxParticles", nullptr, nullptr }, + { "particleLifetime", nullptr, nullptr }, + { "particleSize", nullptr, nullptr }, + { "colorKey", nullptr, nullptr }, + { "geometryType", nullptr, nullptr }, + { "texCoordKey", nullptr, nullptr }, + { "pickable", nullptr, nullptr }, + { "angularDampingFactor", nullptr, nullptr }, + { "angularVelocity", nullptr, nullptr }, + { "autoDamp", nullptr, nullptr }, + { "autoDisable", nullptr, nullptr }, + { "disableAngularSpeed", nullptr, nullptr }, + { "disableLinearSpeed", nullptr, nullptr }, + { "disableTime", nullptr, nullptr }, + { "finiteRotationAxis", nullptr, nullptr }, + { "fixed", nullptr, nullptr }, + { "forces", nullptr, nullptr }, + { "inertia", nullptr, nullptr }, + { "linearDampingFactor", nullptr, nullptr }, + { "torques", nullptr, nullptr }, + { "useFiniteRotation", nullptr, nullptr }, + { "useGlobalForce", nullptr, nullptr }, + { "constantForceMix", nullptr, nullptr }, + { "constantSurfaceThickness", nullptr, nullptr }, + { "errorCorrection", nullptr, nullptr }, + { "iterations", nullptr, nullptr }, + { "maxCorrectionSpeed", nullptr, nullptr }, + { "preferAccuracy", nullptr, nullptr }, + { "pointSize", nullptr, nullptr }, + { "stopBounce", nullptr, nullptr }, + { "stopErrorCorrection", nullptr, nullptr }, + { "angleRate", nullptr, nullptr }, + { "maxSeparation", nullptr, nullptr }, + { "minSeparation", nullptr, nullptr }, + { "separation", nullptr, nullptr }, + { "separationRate", nullptr, nullptr }, + { "closed", nullptr, nullptr }, + { "keyVelocity", nullptr, nullptr }, + { "normalizeVelocity", nullptr, nullptr }, + { "surface", nullptr, nullptr }, + { "anisotropicDegree", nullptr, nullptr }, + { "borderColor", nullptr, nullptr }, + { "borderWidth", nullptr, nullptr }, + { "boundaryModeS", nullptr, nullptr }, + { "boundaryModeT", nullptr, nullptr }, + { "boundaryModeR", nullptr, nullptr }, + { "magnificationFilter", nullptr, nullptr }, + { "minificationFilter", nullptr, nullptr }, + { "textureCompression", nullptr, nullptr }, + { "texturePriority", nullptr, nullptr }, + { "generateMipMaps", nullptr, nullptr }, + { "targetObject", nullptr, nullptr }, + { "backAmbientIntensity", nullptr, nullptr }, + { "backDiffuseColor", nullptr, nullptr }, + { "backEmissiveColor", nullptr, nullptr }, + { "backShininess", nullptr, nullptr }, + { "backSpecularColor", nullptr, nullptr }, + { "separateBackColor", nullptr, nullptr }, + { "displayed", nullptr, nullptr }, + { "clipBoundary", nullptr, nullptr }, + { "internal", nullptr, nullptr }, + { "gustiness", nullptr, nullptr }, + { "turbulence", nullptr, nullptr } +}; + +FIVocabulary X3D_vocabulary_3_2 = { + nullptr, 0, + encodingAlgorithmTable_3_2, 8, + nullptr, 0, + nullptr, 0, + nullptr, 0, + nullptr, 0, + nullptr, 0, + attributeValueTable_3_2, 2, + nullptr, 0, + nullptr, 0, + elementNameTable_3_2, 233, + attributeNameTable_3_2, 516 +}; + +static const char *encodingAlgorithmTable_3_3[] = { + "encoder://web3d.org/QuantizedFloatArrayEncoder", + "encoder://web3d.org/DeltazlibIntArrayEncoder", + "encoder://web3d.org/QuantizedzlibFloatArrayEncoder", + "encoder://web3d.org/zlibFloatArrayEncoder", + "encoder://web3d.org/QuantizedDoubleArrayEncoder", + "encoder://web3d.org/zlibDoubleArrayEncoder", + "encoder://web3d.org/QuantizedzlibDoubleArrayEncoder", + "encoder://web3d.org/RangeIntArrayEncoder" +}; + +static const std::shared_ptr attributeValueTable_3_3[] = { + FIStringValue::create("false"), + FIStringValue::create("true") +}; + +static const FIQName elementNameTable_3_3[] = { + { "Shape", nullptr, nullptr }, + { "Appearance", nullptr, nullptr }, + { "Material", nullptr, nullptr }, + { "IndexedFaceSet", nullptr, nullptr }, + { "ProtoInstance", nullptr, nullptr }, + { "Transform", nullptr, nullptr }, + { "ImageTexture", nullptr, nullptr }, + { "TextureTransform", nullptr, nullptr }, + { "Coordinate", nullptr, nullptr }, + { "Normal", nullptr, nullptr }, + { "Color", nullptr, nullptr }, + { "ColorRGBA", nullptr, nullptr }, + { "TextureCoordinate", nullptr, nullptr }, + { "ROUTE", nullptr, nullptr }, + { "fieldValue", nullptr, nullptr }, + { "Group", nullptr, nullptr }, + { "LOD", nullptr, nullptr }, + { "Switch", nullptr, nullptr }, + { "Script", nullptr, nullptr }, + { "IndexedTriangleFanSet", nullptr, nullptr }, + { "IndexedTriangleSet", nullptr, nullptr }, + { "IndexedTriangleStripSet", nullptr, nullptr }, + { "MultiTexture", nullptr, nullptr }, + { "MultiTextureCoordinate", nullptr, nullptr }, + { "MultiTextureTransform", nullptr, nullptr }, + { "IndexedLineSet", nullptr, nullptr }, + { "PointSet", nullptr, nullptr }, + { "StaticGroup", nullptr, nullptr }, + { "Sphere", nullptr, nullptr }, + { "Box", nullptr, nullptr }, + { "Cone", nullptr, nullptr }, + { "Anchor", nullptr, nullptr }, + { "Arc2D", nullptr, nullptr }, + { "ArcClose2D", nullptr, nullptr }, + { "AudioClip", nullptr, nullptr }, + { "Background", nullptr, nullptr }, + { "Billboard", nullptr, nullptr }, + { "BooleanFilter", nullptr, nullptr }, + { "BooleanSequencer", nullptr, nullptr }, + { "BooleanToggle", nullptr, nullptr }, + { "BooleanTrigger", nullptr, nullptr }, + { "Circle2D", nullptr, nullptr }, + { "Collision", nullptr, nullptr }, + { "ColorInterpolator", nullptr, nullptr }, + { "Contour2D", nullptr, nullptr }, + { "ContourPolyline2D", nullptr, nullptr }, + { "CoordinateDouble", nullptr, nullptr }, + { "CoordinateInterpolator", nullptr, nullptr }, + { "CoordinateInterpolator2D", nullptr, nullptr }, + { "Cylinder", nullptr, nullptr }, + { "CylinderSensor", nullptr, nullptr }, + { "DirectionalLight", nullptr, nullptr }, + { "Disk2D", nullptr, nullptr }, + { "EXPORT", nullptr, nullptr }, + { "ElevationGrid", nullptr, nullptr }, + { "EspduTransform", nullptr, nullptr }, + { "ExternProtoDeclare", nullptr, nullptr }, + { "Extrusion", nullptr, nullptr }, + { "FillProperties", nullptr, nullptr }, + { "Fog", nullptr, nullptr }, + { "FontStyle", nullptr, nullptr }, + { "GeoCoordinate", nullptr, nullptr }, + { "GeoElevationGrid", nullptr, nullptr }, + { "GeoLOD", nullptr, nullptr }, + { "GeoLocation", nullptr, nullptr }, + { "GeoMetadata", nullptr, nullptr }, + { "GeoOrigin", nullptr, nullptr }, + { "GeoPositionInterpolator", nullptr, nullptr }, + { "GeoTouchSensor", nullptr, nullptr }, + { "GeoViewpoint", nullptr, nullptr }, + { "HAnimDisplacer", nullptr, nullptr }, + { "HAnimHumanoid", nullptr, nullptr }, + { "HAnimJoint", nullptr, nullptr }, + { "HAnimSegment", nullptr, nullptr }, + { "HAnimSite", nullptr, nullptr }, + { "IMPORT", nullptr, nullptr }, + { "IS", nullptr, nullptr }, + { "Inline", nullptr, nullptr }, + { "IntegerSequencer", nullptr, nullptr }, + { "IntegerTrigger", nullptr, nullptr }, + { "KeySensor", nullptr, nullptr }, + { "LineProperties", nullptr, nullptr }, + { "LineSet", nullptr, nullptr }, + { "LoadSensor", nullptr, nullptr }, + { "MetadataDouble", nullptr, nullptr }, + { "MetadataFloat", nullptr, nullptr }, + { "MetadataInteger", nullptr, nullptr }, + { "MetadataSet", nullptr, nullptr }, + { "MetadataString", nullptr, nullptr }, + { "MovieTexture", nullptr, nullptr }, + { "NavigationInfo", nullptr, nullptr }, + { "NormalInterpolator", nullptr, nullptr }, + { "NurbsCurve", nullptr, nullptr }, + { "NurbsCurve2D", nullptr, nullptr }, + { "NurbsOrientationInterpolator", nullptr, nullptr }, + { "NurbsPatchSurface", nullptr, nullptr }, + { "NurbsPositionInterpolator", nullptr, nullptr }, + { "NurbsSet", nullptr, nullptr }, + { "NurbsSurfaceInterpolator", nullptr, nullptr }, + { "NurbsSweptSurface", nullptr, nullptr }, + { "NurbsSwungSurface", nullptr, nullptr }, + { "NurbsTextureCoordinate", nullptr, nullptr }, + { "NurbsTrimmedSurface", nullptr, nullptr }, + { "OrientationInterpolator", nullptr, nullptr }, + { "PixelTexture", nullptr, nullptr }, + { "PlaneSensor", nullptr, nullptr }, + { "PointLight", nullptr, nullptr }, + { "Polyline2D", nullptr, nullptr }, + { "Polypoint2D", nullptr, nullptr }, + { "PositionInterpolator", nullptr, nullptr }, + { "PositionInterpolator2D", nullptr, nullptr }, + { "ProtoBody", nullptr, nullptr }, + { "ProtoDeclare", nullptr, nullptr }, + { "ProtoInterface", nullptr, nullptr }, + { "ProximitySensor", nullptr, nullptr }, + { "ReceiverPdu", nullptr, nullptr }, + { "Rectangle2D", nullptr, nullptr }, + { "ScalarInterpolator", nullptr, nullptr }, + { "Scene", nullptr, nullptr }, + { "SignalPdu", nullptr, nullptr }, + { "Sound", nullptr, nullptr }, + { "SphereSensor", nullptr, nullptr }, + { "SpotLight", nullptr, nullptr }, + { "StringSensor", nullptr, nullptr }, + { "Text", nullptr, nullptr }, + { "TextureBackground", nullptr, nullptr }, + { "TextureCoordinateGenerator", nullptr, nullptr }, + { "TimeSensor", nullptr, nullptr }, + { "TimeTrigger", nullptr, nullptr }, + { "TouchSensor", nullptr, nullptr }, + { "TransmitterPdu", nullptr, nullptr }, + { "TriangleFanSet", nullptr, nullptr }, + { "TriangleSet", nullptr, nullptr }, + { "TriangleSet2D", nullptr, nullptr }, + { "TriangleStripSet", nullptr, nullptr }, + { "Viewpoint", nullptr, nullptr }, + { "VisibilitySensor", nullptr, nullptr }, + { "WorldInfo", nullptr, nullptr }, + { "X3D", nullptr, nullptr }, + { "component", nullptr, nullptr }, + { "connect", nullptr, nullptr }, + { "field", nullptr, nullptr }, + { "head", nullptr, nullptr }, + { "humanoidBodyType", nullptr, nullptr }, + { "meta", nullptr, nullptr }, + { "CADAssembly", nullptr, nullptr }, + { "CADFace", nullptr, nullptr }, + { "CADLayer", nullptr, nullptr }, + { "CADPart", nullptr, nullptr }, + { "ComposedCubeMapTexture", nullptr, nullptr }, + { "ComposedShader", nullptr, nullptr }, + { "ComposedTexture3D", nullptr, nullptr }, + { "FloatVertexAttribute", nullptr, nullptr }, + { "FogCoordinate", nullptr, nullptr }, + { "GeneratedCubeMapTexture", nullptr, nullptr }, + { "ImageCubeMapTexture", nullptr, nullptr }, + { "ImageTexture3D", nullptr, nullptr }, + { "IndexedQuadSet", nullptr, nullptr }, + { "LocalFog", nullptr, nullptr }, + { "Matrix3VertexAttribute", nullptr, nullptr }, + { "Matrix4VertexAttribute", nullptr, nullptr }, + { "PackagedShader", nullptr, nullptr }, + { "PixelTexture3D", nullptr, nullptr }, + { "ProgramShader", nullptr, nullptr }, + { "QuadSet", nullptr, nullptr }, + { "ShaderPart", nullptr, nullptr }, + { "ShaderProgram", nullptr, nullptr }, + { "TextureCoordinate3D", nullptr, nullptr }, + { "TextureCoordinate4D", nullptr, nullptr }, + { "TextureTransform3D", nullptr, nullptr }, + { "TextureTransformMatrix3D", nullptr, nullptr }, + { "BallJoint", nullptr, nullptr }, + { "BoundedPhysicsModel", nullptr, nullptr }, + { "ClipPlane", nullptr, nullptr }, + { "CollidableOffset", nullptr, nullptr }, + { "CollidableShape", nullptr, nullptr }, + { "CollisionCollection", nullptr, nullptr }, + { "CollisionSensor", nullptr, nullptr }, + { "CollisionSpace", nullptr, nullptr }, + { "ColorDamper", nullptr, nullptr }, + { "ConeEmitter", nullptr, nullptr }, + { "Contact", nullptr, nullptr }, + { "CoordinateDamper", nullptr, nullptr }, + { "DISEntityManager", nullptr, nullptr }, + { "DISEntityTypeMapping", nullptr, nullptr }, + { "DoubleAxisHingeJoint", nullptr, nullptr }, + { "EaseInEaseOut", nullptr, nullptr }, + { "ExplosionEmitter", nullptr, nullptr }, + { "ForcePhysicsModel", nullptr, nullptr }, + { "GeoProximitySensor", nullptr, nullptr }, + { "GeoTransform", nullptr, nullptr }, + { "Layer", nullptr, nullptr }, + { "LayerSet", nullptr, nullptr }, + { "Layout", nullptr, nullptr }, + { "LayoutGroup", nullptr, nullptr }, + { "LayoutLayer", nullptr, nullptr }, + { "LinePickSensor", nullptr, nullptr }, + { "MotorJoint", nullptr, nullptr }, + { "OrientationChaser", nullptr, nullptr }, + { "OrientationDamper", nullptr, nullptr }, + { "OrthoViewpoint", nullptr, nullptr }, + { "ParticleSystem", nullptr, nullptr }, + { "PickableGroup", nullptr, nullptr }, + { "PointEmitter", nullptr, nullptr }, + { "PointPickSensor", nullptr, nullptr }, + { "PolylineEmitter", nullptr, nullptr }, + { "PositionChaser", nullptr, nullptr }, + { "PositionChaser2D", nullptr, nullptr }, + { "PositionDamper", nullptr, nullptr }, + { "PositionDamper2D", nullptr, nullptr }, + { "PrimitivePickSensor", nullptr, nullptr }, + { "RigidBody", nullptr, nullptr }, + { "RigidBodyCollection", nullptr, nullptr }, + { "ScalarChaser", nullptr, nullptr }, + { "ScreenFontStyle", nullptr, nullptr }, + { "ScreenGroup", nullptr, nullptr }, + { "SingleAxisHingeJoint", nullptr, nullptr }, + { "SliderJoint", nullptr, nullptr }, + { "SplinePositionInterpolator", nullptr, nullptr }, + { "SplinePositionInterpolator2D", nullptr, nullptr }, + { "SplineScalarInterpolator", nullptr, nullptr }, + { "SquadOrientationInterpolator", nullptr, nullptr }, + { "SurfaceEmitter", nullptr, nullptr }, + { "TexCoordDamper2D", nullptr, nullptr }, + { "TextureProperties", nullptr, nullptr }, + { "TransformSensor", nullptr, nullptr }, + { "TwoSidedMaterial", nullptr, nullptr }, + { "UniversalJoint", nullptr, nullptr }, + { "ViewpointGroup", nullptr, nullptr }, + { "Viewport", nullptr, nullptr }, + { "VolumeEmitter", nullptr, nullptr }, + { "VolumePickSensor", nullptr, nullptr }, + { "WindPhysicsModel", nullptr, nullptr }, + { "BlendedVolumeStyle", nullptr, nullptr }, + { "BoundaryEnhancementVolumeStyle", nullptr, nullptr }, + { "CartoonVolumeStyle", nullptr, nullptr }, + { "ComposedVolumeStyle", nullptr, nullptr }, + { "EdgeEnhancementVolumeStyle", nullptr, nullptr }, + { "IsoSurfaceVolumeData", nullptr, nullptr }, + { "MetadataBoolean", nullptr, nullptr }, + { "OpacityMapVolumeStyle", nullptr, nullptr }, + { "ProjectionVolumeStyle", nullptr, nullptr }, + { "SegmentedVolumeData", nullptr, nullptr }, + { "ShadedVolumeStyle", nullptr, nullptr }, + { "SilhouetteEnhancementVolumeStyle", nullptr, nullptr }, + { "ToneMappedVolumeStyle", nullptr, nullptr }, + { "VolumeData", nullptr, nullptr }, + { "ColorChaser", nullptr, nullptr }, + { "CoordinateChaser", nullptr, nullptr }, + { "ScalarDamper", nullptr, nullptr }, + { "TexCoordChaser2D", nullptr, nullptr }, + { "unit", nullptr, nullptr } +}; + +static const FIQName attributeNameTable_3_3[] = { + { "DEF", nullptr, nullptr }, + { "USE", nullptr, nullptr }, + { "containerField", nullptr, nullptr }, + { "fromNode", nullptr, nullptr }, + { "fromField", nullptr, nullptr }, + { "toNode", nullptr, nullptr }, + { "toField", nullptr, nullptr }, + { "name", nullptr, nullptr }, + { "value", nullptr, nullptr }, + { "color", nullptr, nullptr }, + { "colorIndex", nullptr, nullptr }, + { "coordIndex", nullptr, nullptr }, + { "texCoordIndex", nullptr, nullptr }, + { "normalIndex", nullptr, nullptr }, + { "colorPerVertex", nullptr, nullptr }, + { "normalPerVertex", nullptr, nullptr }, + { "rotation", nullptr, nullptr }, + { "scale", nullptr, nullptr }, + { "center", nullptr, nullptr }, + { "scaleOrientation", nullptr, nullptr }, + { "translation", nullptr, nullptr }, + { "url", nullptr, nullptr }, + { "repeatS", nullptr, nullptr }, + { "repeatT", nullptr, nullptr }, + { "point", nullptr, nullptr }, + { "vector", nullptr, nullptr }, + { "range", nullptr, nullptr }, + { "ambientIntensity", nullptr, nullptr }, + { "diffuseColor", nullptr, nullptr }, + { "emissiveColor", nullptr, nullptr }, + { "shininess", nullptr, nullptr }, + { "specularColor", nullptr, nullptr }, + { "transparency", nullptr, nullptr }, + { "whichChoice", nullptr, nullptr }, + { "index", nullptr, nullptr }, + { "mode", nullptr, nullptr }, + { "source", nullptr, nullptr }, + { "function", nullptr, nullptr }, + { "alpha", nullptr, nullptr }, + { "vertexCount", nullptr, nullptr }, + { "radius", nullptr, nullptr }, + { "size", nullptr, nullptr }, + { "height", nullptr, nullptr }, + { "solid", nullptr, nullptr }, + { "ccw", nullptr, nullptr }, + { "key", nullptr, nullptr }, + { "keyValue", nullptr, nullptr }, + { "enabled", nullptr, nullptr }, + { "direction", nullptr, nullptr }, + { "position", nullptr, nullptr }, + { "orientation", nullptr, nullptr }, + { "bboxCenter", nullptr, nullptr }, + { "bboxSize", nullptr, nullptr }, + { "AS", nullptr, nullptr }, + { "InlineDEF", nullptr, nullptr }, + { "accessType", nullptr, nullptr }, + { "actionKeyPress", nullptr, nullptr }, + { "actionKeyRelease", nullptr, nullptr }, + { "address", nullptr, nullptr }, + { "altKey", nullptr, nullptr }, + { "antennaLocation", nullptr, nullptr }, + { "antennaPatternLength", nullptr, nullptr }, + { "antennaPatternType", nullptr, nullptr }, + { "applicationID", nullptr, nullptr }, + { "articulationParameterArray", nullptr, nullptr }, + { "articulationParameterChangeIndicatorArray", nullptr, nullptr }, + { "articulationParameterCount", nullptr, nullptr }, + { "articulationParameterDesignatorArray", nullptr, nullptr }, + { "articulationParameterIdPartAttachedArray", nullptr, nullptr }, + { "articulationParameterTypeArray", nullptr, nullptr }, + { "attenuation", nullptr, nullptr }, + { "autoOffset", nullptr, nullptr }, + { "avatarSize", nullptr, nullptr }, + { "axisOfRotation", nullptr, nullptr }, + { "backUrl", nullptr, nullptr }, + { "beamWidth", nullptr, nullptr }, + { "beginCap", nullptr, nullptr }, + { "bindTime", nullptr, nullptr }, + { "bottom", nullptr, nullptr }, + { "bottomRadius", nullptr, nullptr }, + { "bottomUrl", nullptr, nullptr }, + { "centerOfMass", nullptr, nullptr }, + { "centerOfRotation", nullptr, nullptr }, + { "child1Url", nullptr, nullptr }, + { "child2Url", nullptr, nullptr }, + { "child3Url", nullptr, nullptr }, + { "child4Url", nullptr, nullptr }, + { "class", nullptr, nullptr }, + { "closureType", nullptr, nullptr }, + { "collideTime", nullptr, nullptr }, + { "content", nullptr, nullptr }, + { "controlKey", nullptr, nullptr }, + { "controlPoint", nullptr, nullptr }, + { "convex", nullptr, nullptr }, + { "coordinateSystem", nullptr, nullptr }, + { "copyright", nullptr, nullptr }, + { "creaseAngle", nullptr, nullptr }, + { "crossSection", nullptr, nullptr }, + { "cryptoKeyID", nullptr, nullptr }, + { "cryptoSystem", nullptr, nullptr }, + { "cutOffAngle", nullptr, nullptr }, + { "cycleInterval", nullptr, nullptr }, + { "cycleTime", nullptr, nullptr }, + { "data", nullptr, nullptr }, + { "dataFormat", nullptr, nullptr }, + { "dataLength", nullptr, nullptr }, + { "dataUrl", nullptr, nullptr }, + { "date", nullptr, nullptr }, + { "deadReckoning", nullptr, nullptr }, + { "deletionAllowed", nullptr, nullptr }, + { "description", nullptr, nullptr }, + { "detonateTime", nullptr, nullptr }, + { "dir", nullptr, nullptr }, + { "directOutput", nullptr, nullptr }, + { "diskAngle", nullptr, nullptr }, + { "displacements", nullptr, nullptr }, + { "documentation", nullptr, nullptr }, + { "elapsedTime", nullptr, nullptr }, + { "ellipsoid", nullptr, nullptr }, + { "encodingScheme", nullptr, nullptr }, + { "endAngle", nullptr, nullptr }, + { "endCap", nullptr, nullptr }, + { "enterTime", nullptr, nullptr }, + { "enteredText", nullptr, nullptr }, + { "entityCategory", nullptr, nullptr }, + { "entityCountry", nullptr, nullptr }, + { "entityDomain", nullptr, nullptr }, + { "entityExtra", nullptr, nullptr }, + { "entityID", nullptr, nullptr }, + { "entityKind", nullptr, nullptr }, + { "entitySpecific", nullptr, nullptr }, + { "entitySubCategory", nullptr, nullptr }, + { "exitTime", nullptr, nullptr }, + { "extent", nullptr, nullptr }, + { "family", nullptr, nullptr }, + { "fanCount", nullptr, nullptr }, + { "fieldOfView", nullptr, nullptr }, + { "filled", nullptr, nullptr }, + { "finalText", nullptr, nullptr }, + { "fireMissionIndex", nullptr, nullptr }, + { "fired1", nullptr, nullptr }, + { "fired2", nullptr, nullptr }, + { "firedTime", nullptr, nullptr }, + { "firingRange", nullptr, nullptr }, + { "firingRate", nullptr, nullptr }, + { "fogType", nullptr, nullptr }, + { "forceID", nullptr, nullptr }, + { "frequency", nullptr, nullptr }, + { "frontUrl", nullptr, nullptr }, + { "fuse", nullptr, nullptr }, + { "geoCoords", nullptr, nullptr }, + { "geoGridOrigin", nullptr, nullptr }, + { "geoSystem", nullptr, nullptr }, + { "groundAngle", nullptr, nullptr }, + { "groundColor", nullptr, nullptr }, + { "hatchColor", nullptr, nullptr }, + { "hatchStyle", nullptr, nullptr }, + { "hatched", nullptr, nullptr }, + { "headlight", nullptr, nullptr }, + { "horizontal", nullptr, nullptr }, + { "horizontalDatum", nullptr, nullptr }, + { "http-equiv", nullptr, nullptr }, + { "image", nullptr, nullptr }, + { "importedDEF", nullptr, nullptr }, + { "info", nullptr, nullptr }, + { "innerRadius", nullptr, nullptr }, + { "inputFalse", nullptr, nullptr }, + { "inputNegate", nullptr, nullptr }, + { "inputSource", nullptr, nullptr }, + { "inputTrue", nullptr, nullptr }, + { "integerKey", nullptr, nullptr }, + { "intensity", nullptr, nullptr }, + { "jump", nullptr, nullptr }, + { "justify", nullptr, nullptr }, + { "keyPress", nullptr, nullptr }, + { "keyRelease", nullptr, nullptr }, + { "knot", nullptr, nullptr }, + { "lang", nullptr, nullptr }, + { "language", nullptr, nullptr }, + { "leftToRight", nullptr, nullptr }, + { "leftUrl", nullptr, nullptr }, + { "length", nullptr, nullptr }, + { "lengthOfModulationParameters", nullptr, nullptr }, + { "level", nullptr, nullptr }, + { "limitOrientation", nullptr, nullptr }, + { "lineSegments", nullptr, nullptr }, + { "linearAcceleration", nullptr, nullptr }, + { "linearVelocity", nullptr, nullptr }, + { "linetype", nullptr, nullptr }, + { "linewidthScaleFactor", nullptr, nullptr }, + { "llimit", nullptr, nullptr }, + { "load", nullptr, nullptr }, + { "loadTime", nullptr, nullptr }, + { "localDEF", nullptr, nullptr }, + { "location", nullptr, nullptr }, + { "loop", nullptr, nullptr }, + { "marking", nullptr, nullptr }, + { "mass", nullptr, nullptr }, + { "maxAngle", nullptr, nullptr }, + { "maxBack", nullptr, nullptr }, + { "maxExtent", nullptr, nullptr }, + { "maxFront", nullptr, nullptr }, + { "maxPosition", nullptr, nullptr }, + { "metadataFormat", nullptr, nullptr }, + { "minAngle", nullptr, nullptr }, + { "minBack", nullptr, nullptr }, + { "minFront", nullptr, nullptr }, + { "minPosition", nullptr, nullptr }, + { "modulationTypeDetail", nullptr, nullptr }, + { "modulationTypeMajor", nullptr, nullptr }, + { "modulationTypeSpreadSpectrum", nullptr, nullptr }, + { "modulationTypeSystem", nullptr, nullptr }, + { "momentsOfInertia", nullptr, nullptr }, + { "multicastRelayHost", nullptr, nullptr }, + { "multicastRelayPort", nullptr, nullptr }, + { "munitionApplicationID", nullptr, nullptr }, + { "munitionEndPoint", nullptr, nullptr }, + { "munitionEntityID", nullptr, nullptr }, + { "munitionQuantity", nullptr, nullptr }, + { "munitionSiteID", nullptr, nullptr }, + { "munitionStartPoint", nullptr, nullptr }, + { "mustEvaluate", nullptr, nullptr }, + { "navType", nullptr, nullptr }, + { "networkMode", nullptr, nullptr }, + { "next", nullptr, nullptr }, + { "nodeField", nullptr, nullptr }, + { "offset", nullptr, nullptr }, + { "on", nullptr, nullptr }, + { "order", nullptr, nullptr }, + { "originator", nullptr, nullptr }, + { "outerRadius", nullptr, nullptr }, + { "parameter", nullptr, nullptr }, + { "pauseTime", nullptr, nullptr }, + { "pitch", nullptr, nullptr }, + { "points", nullptr, nullptr }, + { "port", nullptr, nullptr }, + { "power", nullptr, nullptr }, + { "previous", nullptr, nullptr }, + { "priority", nullptr, nullptr }, + { "profile", nullptr, nullptr }, + { "progress", nullptr, nullptr }, + { "protoField", nullptr, nullptr }, + { "radioEntityTypeCategory", nullptr, nullptr }, + { "radioEntityTypeCountry", nullptr, nullptr }, + { "radioEntityTypeDomain", nullptr, nullptr }, + { "radioEntityTypeKind", nullptr, nullptr }, + { "radioEntityTypeNomenclature", nullptr, nullptr }, + { "radioEntityTypeNomenclatureVersion", nullptr, nullptr }, + { "radioID", nullptr, nullptr }, + { "readInterval", nullptr, nullptr }, + { "receivedPower", nullptr, nullptr }, + { "receiverState", nullptr, nullptr }, + { "reference", nullptr, nullptr }, + { "relativeAntennaLocation", nullptr, nullptr }, + { "resolution", nullptr, nullptr }, + { "resumeTime", nullptr, nullptr }, + { "rightUrl", nullptr, nullptr }, + { "rootUrl", nullptr, nullptr }, + { "rotateYUp", nullptr, nullptr }, + { "rtpHeaderExpected", nullptr, nullptr }, + { "sampleRate", nullptr, nullptr }, + { "samples", nullptr, nullptr }, + { "shiftKey", nullptr, nullptr }, + { "side", nullptr, nullptr }, + { "siteID", nullptr, nullptr }, + { "skinCoordIndex", nullptr, nullptr }, + { "skinCoordWeight", nullptr, nullptr }, + { "skyAngle", nullptr, nullptr }, + { "skyColor", nullptr, nullptr }, + { "spacing", nullptr, nullptr }, + { "spatialize", nullptr, nullptr }, + { "speed", nullptr, nullptr }, + { "speedFactor", nullptr, nullptr }, + { "spine", nullptr, nullptr }, + { "startAngle", nullptr, nullptr }, + { "startTime", nullptr, nullptr }, + { "stiffness", nullptr, nullptr }, + { "stopTime", nullptr, nullptr }, + { "string", nullptr, nullptr }, + { "stripCount", nullptr, nullptr }, + { "style", nullptr, nullptr }, + { "summary", nullptr, nullptr }, + { "tdlType", nullptr, nullptr }, + { "tessellation", nullptr, nullptr }, + { "tessellationScale", nullptr, nullptr }, + { "time", nullptr, nullptr }, + { "timeOut", nullptr, nullptr }, + { "timestamp", nullptr, nullptr }, + { "title", nullptr, nullptr }, + { "toggle", nullptr, nullptr }, + { "top", nullptr, nullptr }, + { "topToBottom", nullptr, nullptr }, + { "topUrl", nullptr, nullptr }, + { "touchTime", nullptr, nullptr }, + { "transmitFrequencyBandwidth", nullptr, nullptr }, + { "transmitState", nullptr, nullptr }, + { "transmitterApplicationID", nullptr, nullptr }, + { "transmitterEntityID", nullptr, nullptr }, + { "transmitterRadioID", nullptr, nullptr }, + { "transmitterSiteID", nullptr, nullptr }, + { "transparent", nullptr, nullptr }, + { "triggerTime", nullptr, nullptr }, + { "triggerTrue", nullptr, nullptr }, + { "triggerValue", nullptr, nullptr }, + { "type", nullptr, nullptr }, + { "uDimension", nullptr, nullptr }, + { "uKnot", nullptr, nullptr }, + { "uOrder", nullptr, nullptr }, + { "uTessellation", nullptr, nullptr }, + { "ulimit", nullptr, nullptr }, + { "vDimension", nullptr, nullptr }, + { "vKnot", nullptr, nullptr }, + { "vOrder", nullptr, nullptr }, + { "vTessellation", nullptr, nullptr }, + { "version", nullptr, nullptr }, + { "verticalDatum", nullptr, nullptr }, + { "vertices", nullptr, nullptr }, + { "visibilityLimit", nullptr, nullptr }, + { "visibilityRange", nullptr, nullptr }, + { "warhead", nullptr, nullptr }, + { "weight", nullptr, nullptr }, + { "whichGeometry", nullptr, nullptr }, + { "writeInterval", nullptr, nullptr }, + { "xDimension", nullptr, nullptr }, + { "xSpacing", nullptr, nullptr }, + { "yScale", nullptr, nullptr }, + { "zDimension", nullptr, nullptr }, + { "zSpacing", nullptr, nullptr }, + { "visible", nullptr, nullptr }, + { "repeatR", nullptr, nullptr }, + { "texture", nullptr, nullptr }, + { "back", nullptr, nullptr }, + { "front", nullptr, nullptr }, + { "left", nullptr, nullptr }, + { "right", nullptr, nullptr }, + { "parts", nullptr, nullptr }, + { "isSelected", nullptr, nullptr }, + { "isValid", nullptr, nullptr }, + { "numComponents", nullptr, nullptr }, + { "depth", nullptr, nullptr }, + { "update", nullptr, nullptr }, + { "fogCoord", nullptr, nullptr }, + { "texCoord", nullptr, nullptr }, + { "activate", nullptr, nullptr }, + { "programs", nullptr, nullptr }, + { "matrix", nullptr, nullptr }, + { "anchorPoint", nullptr, nullptr }, + { "body1", nullptr, nullptr }, + { "body2", nullptr, nullptr }, + { "forceOutput", nullptr, nullptr }, + { "body1AnchorPoint", nullptr, nullptr }, + { "body2AnchorPoint", nullptr, nullptr }, + { "plane", nullptr, nullptr }, + { "appliedParameters", nullptr, nullptr }, + { "bounce", nullptr, nullptr }, + { "frictionCoefficients", nullptr, nullptr }, + { "minBounceSpeed", nullptr, nullptr }, + { "slipFactors", nullptr, nullptr }, + { "softnessConstantForceMix", nullptr, nullptr }, + { "softnessErrorCorrection", nullptr, nullptr }, + { "surfaceSpeed", nullptr, nullptr }, + { "isActive", nullptr, nullptr }, + { "useGeometry", nullptr, nullptr }, + { "set_destination", nullptr, nullptr }, + { "set_value", nullptr, nullptr }, + { "tau", nullptr, nullptr }, + { "tolerance", nullptr, nullptr }, + { "value_changed", nullptr, nullptr }, + { "initialDestination", nullptr, nullptr }, + { "initialValue", nullptr, nullptr }, + { "angle", nullptr, nullptr }, + { "variation", nullptr, nullptr }, + { "surfaceArea", nullptr, nullptr }, + { "frictionDirection", nullptr, nullptr }, + { "slipCoefficients", nullptr, nullptr }, + { "category", nullptr, nullptr }, + { "country", nullptr, nullptr }, + { "domain", nullptr, nullptr }, + { "extra", nullptr, nullptr }, + { "kind", nullptr, nullptr }, + { "specific", nullptr, nullptr }, + { "subcategory", nullptr, nullptr }, + { "axis1", nullptr, nullptr }, + { "axis2", nullptr, nullptr }, + { "desiredAngularVelocity1", nullptr, nullptr }, + { "desiredAngularVelocity2", nullptr, nullptr }, + { "maxAngle1", nullptr, nullptr }, + { "maxTorque1", nullptr, nullptr }, + { "maxTorque2", nullptr, nullptr }, + { "minAngle1", nullptr, nullptr }, + { "stopBounce1", nullptr, nullptr }, + { "stopConstantForceMix1", nullptr, nullptr }, + { "stopErrorCorrection1", nullptr, nullptr }, + { "suspensionErrorCorrection", nullptr, nullptr }, + { "suspensionForce", nullptr, nullptr }, + { "body1Axis", nullptr, nullptr }, + { "body2Axis", nullptr, nullptr }, + { "hinge1Angle", nullptr, nullptr }, + { "hinge1AngleRate", nullptr, nullptr }, + { "hinge2Angle", nullptr, nullptr }, + { "hinge2AngleRate", nullptr, nullptr }, + { "set_fraction", nullptr, nullptr }, + { "easeInEaseOut", nullptr, nullptr }, + { "modifiedFraction_changed", nullptr, nullptr }, + { "force", nullptr, nullptr }, + { "geoCenter", nullptr, nullptr }, + { "centerOfRotation_changed", nullptr, nullptr }, + { "geoCoord_changed", nullptr, nullptr }, + { "orientation_changed", nullptr, nullptr }, + { "position_changed", nullptr, nullptr }, + { "isPickable", nullptr, nullptr }, + { "viewport", nullptr, nullptr }, + { "activeLayer", nullptr, nullptr }, + { "align", nullptr, nullptr }, + { "offsetUnits", nullptr, nullptr }, + { "scaleMode", nullptr, nullptr }, + { "sizeUnits", nullptr, nullptr }, + { "layout", nullptr, nullptr }, + { "objectType", nullptr, nullptr }, + { "pickedNormal", nullptr, nullptr }, + { "pickedPoint", nullptr, nullptr }, + { "pickedTextureCoordinate", nullptr, nullptr }, + { "intersectionType", nullptr, nullptr }, + { "sortOrder", nullptr, nullptr }, + { "axis1Angle", nullptr, nullptr }, + { "axis1Torque", nullptr, nullptr }, + { "axis2Angle", nullptr, nullptr }, + { "axis2Torque", nullptr, nullptr }, + { "axis3Angle", nullptr, nullptr }, + { "axis3Torque", nullptr, nullptr }, + { "enabledAxies", nullptr, nullptr }, + { "motor1Axis", nullptr, nullptr }, + { "motor2Axis", nullptr, nullptr }, + { "motor3Axis", nullptr, nullptr }, + { "stop1Bounce", nullptr, nullptr }, + { "stop1ErrorCorrection", nullptr, nullptr }, + { "stop2Bounce", nullptr, nullptr }, + { "stop2ErrorCorrection", nullptr, nullptr }, + { "stop3Bounce", nullptr, nullptr }, + { "stop3ErrorCorrection", nullptr, nullptr }, + { "motor1Angle", nullptr, nullptr }, + { "motor1AngleRate", nullptr, nullptr }, + { "motor2Angle", nullptr, nullptr }, + { "motor2AngleRate", nullptr, nullptr }, + { "motor3Angle", nullptr, nullptr }, + { "motor3AngleRate", nullptr, nullptr }, + { "autoCalc", nullptr, nullptr }, + { "duration", nullptr, nullptr }, + { "retainUserOffsets", nullptr, nullptr }, + { "isBound", nullptr, nullptr }, + { "appearance", nullptr, nullptr }, + { "createParticles", nullptr, nullptr }, + { "lifetimeVariation", nullptr, nullptr }, + { "maxParticles", nullptr, nullptr }, + { "particleLifetime", nullptr, nullptr }, + { "particleSize", nullptr, nullptr }, + { "colorKey", nullptr, nullptr }, + { "geometryType", nullptr, nullptr }, + { "texCoordKey", nullptr, nullptr }, + { "pickable", nullptr, nullptr }, + { "angularDampingFactor", nullptr, nullptr }, + { "angularVelocity", nullptr, nullptr }, + { "autoDamp", nullptr, nullptr }, + { "autoDisable", nullptr, nullptr }, + { "disableAngularSpeed", nullptr, nullptr }, + { "disableLinearSpeed", nullptr, nullptr }, + { "disableTime", nullptr, nullptr }, + { "finiteRotationAxis", nullptr, nullptr }, + { "fixed", nullptr, nullptr }, + { "forces", nullptr, nullptr }, + { "inertia", nullptr, nullptr }, + { "linearDampingFactor", nullptr, nullptr }, + { "torques", nullptr, nullptr }, + { "useFiniteRotation", nullptr, nullptr }, + { "useGlobalForce", nullptr, nullptr }, + { "constantForceMix", nullptr, nullptr }, + { "constantSurfaceThickness", nullptr, nullptr }, + { "errorCorrection", nullptr, nullptr }, + { "iterations", nullptr, nullptr }, + { "maxCorrectionSpeed", nullptr, nullptr }, + { "preferAccuracy", nullptr, nullptr }, + { "pointSize", nullptr, nullptr }, + { "stopBounce", nullptr, nullptr }, + { "stopErrorCorrection", nullptr, nullptr }, + { "angleRate", nullptr, nullptr }, + { "maxSeparation", nullptr, nullptr }, + { "minSeparation", nullptr, nullptr }, + { "separation", nullptr, nullptr }, + { "separationRate", nullptr, nullptr }, + { "closed", nullptr, nullptr }, + { "keyVelocity", nullptr, nullptr }, + { "normalizeVelocity", nullptr, nullptr }, + { "surface", nullptr, nullptr }, + { "anisotropicDegree", nullptr, nullptr }, + { "borderColor", nullptr, nullptr }, + { "borderWidth", nullptr, nullptr }, + { "boundaryModeS", nullptr, nullptr }, + { "boundaryModeT", nullptr, nullptr }, + { "boundaryModeR", nullptr, nullptr }, + { "magnificationFilter", nullptr, nullptr }, + { "minificationFilter", nullptr, nullptr }, + { "textureCompression", nullptr, nullptr }, + { "texturePriority", nullptr, nullptr }, + { "generateMipMaps", nullptr, nullptr }, + { "targetObject", nullptr, nullptr }, + { "backAmbientIntensity", nullptr, nullptr }, + { "backDiffuseColor", nullptr, nullptr }, + { "backEmissiveColor", nullptr, nullptr }, + { "backShininess", nullptr, nullptr }, + { "backSpecularColor", nullptr, nullptr }, + { "separateBackColor", nullptr, nullptr }, + { "displayed", nullptr, nullptr }, + { "clipBoundary", nullptr, nullptr }, + { "internal", nullptr, nullptr }, + { "gustiness", nullptr, nullptr }, + { "turbulence", nullptr, nullptr }, + { "unitCategory", nullptr, nullptr }, + { "unitName", nullptr, nullptr }, + { "unitConversionFactor", nullptr, nullptr }, + { "weightConstant1", nullptr, nullptr }, + { "weightConstant2", nullptr, nullptr }, + { "weightFunction1", nullptr, nullptr }, + { "weightFunction2", nullptr, nullptr }, + { "boundaryOpacity", nullptr, nullptr }, + { "opacityFactor", nullptr, nullptr }, + { "retainedOpacity", nullptr, nullptr }, + { "colorSteps", nullptr, nullptr }, + { "orthogonalColor", nullptr, nullptr }, + { "parallelColor", nullptr, nullptr }, + { "ordered", nullptr, nullptr }, + { "edgeColor", nullptr, nullptr }, + { "gradientThreshold", nullptr, nullptr }, + { "contourStepSize", nullptr, nullptr }, + { "dimensions", nullptr, nullptr }, + { "surfaceTolerance", nullptr, nullptr }, + { "surfaceValues", nullptr, nullptr }, + { "intensityThreshold", nullptr, nullptr }, + { "segmentEnabled", nullptr, nullptr }, + { "lighting", nullptr, nullptr }, + { "shadows", nullptr, nullptr }, + { "phaseFunction", nullptr, nullptr }, + { "silhouetteBoundaryOpacity", nullptr, nullptr }, + { "silhouetteRetainedOpacity", nullptr, nullptr }, + { "silhouetteSharpness", nullptr, nullptr }, + { "coolColor", nullptr, nullptr }, + { "warmColor", nullptr, nullptr } +}; + +FIVocabulary X3D_vocabulary_3_3 = { + nullptr, 0, + encodingAlgorithmTable_3_3, 8, + nullptr, 0, + nullptr, 0, + nullptr, 0, + nullptr, 0, + nullptr, 0, + attributeValueTable_3_3, 2, + nullptr, 0, + nullptr, 0, + elementNameTable_3_3, 252, + attributeNameTable_3_3, 546 +}; + +}// namespace Assimp + +#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER From 8959bcb847cc0ff1fe91e807b591c6a86e32c201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20D=C3=A4hne?= Date: Tue, 11 Jul 2017 19:41:24 +0200 Subject: [PATCH 2/6] X3D importer: Fixed path handling --- code/X3DImporter.cpp | 4 +++- code/X3DImporter_Networking.cpp | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) mode change 100755 => 100644 code/X3DImporter.cpp diff --git a/code/X3DImporter.cpp b/code/X3DImporter.cpp old mode 100755 new mode 100644 index c71453211..feaa0ca37 --- a/code/X3DImporter.cpp +++ b/code/X3DImporter.cpp @@ -1610,8 +1610,10 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy mpIOHandler = pIOHandler; Clear();// delete old graph. - pIOHandler->PushDirectory(DefaultIOSystem::absolutePath(pFile)); + std::string::size_type slashPos = pFile.find_last_of("\\/"); + pIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : pFile.substr(0, slashPos + 1)); ParseFile(pFile, pIOHandler); + pIOHandler->PopDirectory(); // // Assimp use static arrays of objects for fast speed of rendering. That's good, but need some additional operations/ // We know that geometry objects(meshes) are stored in , also in -> materials(in Assimp logical view) diff --git a/code/X3DImporter_Networking.cpp b/code/X3DImporter_Networking.cpp index 9d55900cb..744d805ba 100644 --- a/code/X3DImporter_Networking.cpp +++ b/code/X3DImporter_Networking.cpp @@ -51,9 +51,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Header files, Assimp. #include +#include + namespace Assimp { +static std::regex pattern_parentDir(R"((^|/)[^/]+/../)"); + // CurrentDirectory() + "/" + url.front(); + full_path = std::regex_replace(mpIOHandler->CurrentDirectory() + url.front(), pattern_parentDir, "$1"); // Attribute "url" can contain list of strings. But we need only one - first. - mpIOHandler->PushDirectory(DefaultIOSystem::absolutePath(full_path)); + std::string::size_type slashPos = full_path.find_last_of("\\/"); + mpIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : full_path.substr(0, slashPos + 1)); ParseFile(full_path, mpIOHandler); mpIOHandler->PopDirectory(); } From e97ba7aec284df6a637d594346b397c737c1b93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20D=C3=A4hne?= Date: Tue, 11 Jul 2017 21:32:47 +0200 Subject: [PATCH 3/6] X3D importer: Fixed missing header file --- code/FIReader.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/FIReader.hpp b/code/FIReader.hpp index 05f13ecac..ebc12ae31 100644 --- a/code/FIReader.hpp +++ b/code/FIReader.hpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define INCLUDED_AI_FI_READER_H #include +#include #include #include #include From c1442c63cf1522a84e64bd19a9865bcb9aebecf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20D=C3=A4hne?= Date: Wed, 12 Jul 2017 19:57:10 +0200 Subject: [PATCH 4/6] X3D importer: Fixed problems with auto, override and regex on older compilers --- code/FIReader.cpp | 134 ++++++++++++++++---------------- code/X3DImporter.cpp | 73 +++++++++++++---- code/X3DImporter.hpp | 6 +- code/X3DImporter_Networking.cpp | 25 +++++- 4 files changed, 150 insertions(+), 88 deletions(-) diff --git a/code/FIReader.cpp b/code/FIReader.cpp index 617c87be6..19d94ed94 100755 --- a/code/FIReader.cpp +++ b/code/FIReader.cpp @@ -84,8 +84,8 @@ static size_t parseMagic(const uint8_t *data, const uint8_t *dataEnd) { return 4; case 0x3c3f786d: // "= xmlDeclarationLength) && (memcmp(xmlDeclaration, data, xmlDeclarationLength) == 0)) { @@ -127,7 +127,7 @@ static std::string parseUTF16String(const uint8_t *data, size_t len) { struct FIStringValueImpl: public FIStringValue { inline FIStringValueImpl(std::string &&value_) { value = std::move(value_); } - virtual const std::string &toString() const override { return value; } + virtual const std::string &toString() const /*override*/ { return value; } }; std::shared_ptr FIStringValue::create(std::string &&value) { @@ -138,7 +138,7 @@ struct FIHexValueImpl: public FIHexValue { mutable std::string strValue; mutable bool strValueValid; inline FIHexValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; @@ -158,14 +158,14 @@ struct FIBase64ValueImpl: public FIBase64Value { mutable std::string strValue; mutable bool strValueValid; inline FIBase64ValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; uint8_t c1, c2; int imod3 = 0; - auto valueSize = value.size(); - for (auto i = 0; i < valueSize; ++i) { + std::vector::size_type valueSize = value.size(); + for (std::vector::size_type i = 0; i < valueSize; ++i) { c2 = value[i]; switch (imod3) { case 0: @@ -208,7 +208,7 @@ struct FIShortValueImpl: public FIShortValue { mutable std::string strValue; mutable bool strValueValid; inline FIShortValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; @@ -228,7 +228,7 @@ struct FIIntValueImpl: public FIIntValue { mutable std::string strValue; mutable bool strValueValid; inline FIIntValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; @@ -248,7 +248,7 @@ struct FILongValueImpl: public FILongValue { mutable std::string strValue; mutable bool strValueValid; inline FILongValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; @@ -268,7 +268,7 @@ struct FIBoolValueImpl: public FIBoolValue { mutable std::string strValue; mutable bool strValueValid; inline FIBoolValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; @@ -289,7 +289,7 @@ struct FIFloatValueImpl: public FIFloatValue { mutable std::string strValue; mutable bool strValueValid; inline FIFloatValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; @@ -309,7 +309,7 @@ struct FIDoubleValueImpl: public FIDoubleValue { mutable std::string strValue; mutable bool strValueValid; inline FIDoubleValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; @@ -329,13 +329,13 @@ struct FIUUIDValueImpl: public FIUUIDValue { mutable std::string strValue; mutable bool strValueValid; inline FIUUIDValueImpl(std::vector &&value_): strValueValid(false) { value = std::move(value_); } - virtual const std::string &toString() const override { + virtual const std::string &toString() const /*override*/ { if (!strValueValid) { strValueValid = true; std::ostringstream os; os << std::hex << std::uppercase << std::setfill('0'); - auto valueSize = value.size(); - for (auto i = 0; i < valueSize; ++i) { + std::vector::size_type valueSize = value.size(); + for (std::vector::size_type i = 0; i < valueSize; ++i) { switch (i & 15) { case 0: if (i > 0) { @@ -376,7 +376,7 @@ std::shared_ptr FIUUIDValue::create(std::vector &&value) { struct FICDATAValueImpl: public FICDATAValue { inline FICDATAValueImpl(std::string &&value_) { value = std::move(value_); } - virtual const std::string &toString() const override { return value; } + virtual const std::string &toString() const /*override*/ { return value; } }; std::shared_ptr FICDATAValue::create(std::string &&value) { @@ -384,19 +384,19 @@ std::shared_ptr FICDATAValue::create(std::string &&value) { } struct FIHexDecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { return FIHexValue::create(std::vector(data, data + len)); } }; struct FIBase64Decoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { return FIBase64Value::create(std::vector(data, data + len)); } }; struct FIShortDecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { if (len & 1) { throw DeadlyImportError(parseErrorMessage); } @@ -413,7 +413,7 @@ struct FIShortDecoder: public FIDecoder { }; struct FIIntDecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { if (len & 3) { throw DeadlyImportError(parseErrorMessage); } @@ -430,7 +430,7 @@ struct FIIntDecoder: public FIDecoder { }; struct FILongDecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { if (len & 7) { throw DeadlyImportError(parseErrorMessage); } @@ -448,7 +448,7 @@ struct FILongDecoder: public FIDecoder { }; struct FIBoolDecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { if (len < 1) { throw DeadlyImportError(parseErrorMessage); } @@ -470,7 +470,7 @@ struct FIBoolDecoder: public FIDecoder { }; struct FIFloatDecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { if (len & 3) { throw DeadlyImportError(parseErrorMessage); } @@ -487,7 +487,7 @@ struct FIFloatDecoder: public FIDecoder { }; struct FIDoubleDecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { if (len & 7) { throw DeadlyImportError(parseErrorMessage); } @@ -505,7 +505,7 @@ struct FIDoubleDecoder: public FIDecoder { }; struct FIUUIDDecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { if (len & 15) { throw DeadlyImportError(parseErrorMessage); } @@ -514,7 +514,7 @@ struct FIUUIDDecoder: public FIDecoder { }; struct FICDATADecoder: public FIDecoder { - virtual std::shared_ptr decode(const uint8_t *data, size_t len) override { + virtual std::shared_ptr decode(const uint8_t *data, size_t len) /*override*/ { return FICDATAValue::create(parseUTF8String(data, len)); } }; @@ -529,7 +529,7 @@ public: virtual ~CFIReaderImpl() {} - virtual bool read() override { + virtual bool read() /*override*/ { if (headerPending) { headerPending = false; parseHeader(); @@ -632,29 +632,29 @@ public: throw DeadlyImportError(parseErrorMessage); } - virtual irr::io::EXML_NODE getNodeType() const override { + virtual irr::io::EXML_NODE getNodeType() const /*override*/ { return currentNodeType; } - virtual int getAttributeCount() const override { + virtual int getAttributeCount() const /*override*/ { return static_cast(attributes.size()); } - virtual const char* getAttributeName(int idx) const override { + virtual const char* getAttributeName(int idx) const /*override*/ { if (idx < 0 || idx >= (int)attributes.size()) { return nullptr; } return attributes[idx].name.c_str(); } - virtual const char* getAttributeValue(int idx) const override { + virtual const char* getAttributeValue(int idx) const /*override*/ { if (idx < 0 || idx >= (int)attributes.size()) { return nullptr; } return attributes[idx].value->toString().c_str(); } - virtual const char* getAttributeValue(const char* name) const override { + virtual const char* getAttributeValue(const char* name) const /*override*/ { const Attribute* attr = getAttributeByName(name); if (!attr) { return nullptr; @@ -662,7 +662,7 @@ public: return attr->value->toString().c_str(); } - virtual const char* getAttributeValueSafe(const char* name) const override { + virtual const char* getAttributeValueSafe(const char* name) const /*override*/ { const Attribute* attr = getAttributeByName(name); if (!attr) { return EmptyString.c_str(); @@ -670,7 +670,7 @@ public: return attr->value->toString().c_str(); } - virtual int getAttributeValueAsInt(const char* name) const override { + virtual int getAttributeValueAsInt(const char* name) const /*override*/ { const Attribute* attr = getAttributeByName(name); if (!attr) { return 0; @@ -682,7 +682,7 @@ public: return stoi(attr->value->toString()); } - virtual int getAttributeValueAsInt(int idx) const override { + virtual int getAttributeValueAsInt(int idx) const /*override*/ { if (idx < 0 || idx >= (int)attributes.size()) { return 0; } @@ -693,7 +693,7 @@ public: return stoi(attributes[idx].value->toString()); } - virtual float getAttributeValueAsFloat(const char* name) const override { + virtual float getAttributeValueAsFloat(const char* name) const /*override*/ { const Attribute* attr = getAttributeByName(name); if (!attr) { return 0; @@ -705,7 +705,7 @@ public: return stof(attr->value->toString()); } - virtual float getAttributeValueAsFloat(int idx) const override { + virtual float getAttributeValueAsFloat(int idx) const /*override*/ { if (idx < 0 || idx >= (int)attributes.size()) { return 0; } @@ -716,34 +716,34 @@ public: return stof(attributes[idx].value->toString()); } - virtual const char* getNodeName() const override { + virtual const char* getNodeName() const /*override*/ { return nodeName.c_str(); } - virtual const char* getNodeData() const override { + virtual const char* getNodeData() const /*override*/ { return nodeName.c_str(); } - virtual bool isEmptyElement() const override { + virtual bool isEmptyElement() const /*override*/ { return emptyElement; } - virtual irr::io::ETEXT_FORMAT getSourceFormat() const override { + virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ { return irr::io::ETF_UTF8; } - virtual irr::io::ETEXT_FORMAT getParserFormat() const override { + virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ { return irr::io::ETF_UTF8; } - virtual std::shared_ptr getAttributeEncodedValue(int idx) const override { + virtual std::shared_ptr getAttributeEncodedValue(int idx) const /*override*/ { if (idx < 0 || idx >= (int)attributes.size()) { return nullptr; } return attributes[idx].value; } - virtual std::shared_ptr getAttributeEncodedValue(const char* name) const override { + virtual std::shared_ptr getAttributeEncodedValue(const char* name) const /*override*/ { const Attribute* attr = getAttributeByName(name); if (!attr) { return nullptr; @@ -751,11 +751,11 @@ public: return attr->value; } - virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr decoder) override { + virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr decoder) /*override*/ { decoderMap[algorithmUri] = std::move(decoder); } - virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) override { + virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) /*override*/ { vocabularyMap[vocabularyUri] = vocabulary; } @@ -1706,81 +1706,81 @@ public: virtual ~CXMLReaderImpl() {} - virtual bool read() override { + virtual bool read() /*override*/ { return reader->read(); } - virtual irr::io::EXML_NODE getNodeType() const override { + virtual irr::io::EXML_NODE getNodeType() const /*override*/ { return reader->getNodeType(); } - virtual int getAttributeCount() const override { + virtual int getAttributeCount() const /*override*/ { return reader->getAttributeCount(); } - virtual const char* getAttributeName(int idx) const override { + virtual const char* getAttributeName(int idx) const /*override*/ { return reader->getAttributeName(idx); } - virtual const char* getAttributeValue(int idx) const override { + virtual const char* getAttributeValue(int idx) const /*override*/ { return reader->getAttributeValue(idx); } - virtual const char* getAttributeValue(const char* name) const override { + virtual const char* getAttributeValue(const char* name) const /*override*/ { return reader->getAttributeValue(name); } - virtual const char* getAttributeValueSafe(const char* name) const override { + virtual const char* getAttributeValueSafe(const char* name) const /*override*/ { return reader->getAttributeValueSafe(name); } - virtual int getAttributeValueAsInt(const char* name) const override { + virtual int getAttributeValueAsInt(const char* name) const /*override*/ { return reader->getAttributeValueAsInt(name); } - virtual int getAttributeValueAsInt(int idx) const override { + virtual int getAttributeValueAsInt(int idx) const /*override*/ { return reader->getAttributeValueAsInt(idx); } - virtual float getAttributeValueAsFloat(const char* name) const override { + virtual float getAttributeValueAsFloat(const char* name) const /*override*/ { return reader->getAttributeValueAsFloat(name); } - virtual float getAttributeValueAsFloat(int idx) const override { + virtual float getAttributeValueAsFloat(int idx) const /*override*/ { return reader->getAttributeValueAsFloat(idx); } - virtual const char* getNodeName() const override { + virtual const char* getNodeName() const /*override*/ { return reader->getNodeName(); } - virtual const char* getNodeData() const override { + virtual const char* getNodeData() const /*override*/ { return reader->getNodeData(); } - virtual bool isEmptyElement() const override { + virtual bool isEmptyElement() const /*override*/ { return reader->isEmptyElement(); } - virtual irr::io::ETEXT_FORMAT getSourceFormat() const override { + virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ { return reader->getSourceFormat(); } - virtual irr::io::ETEXT_FORMAT getParserFormat() const override { + virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ { return reader->getParserFormat(); } - virtual std::shared_ptr getAttributeEncodedValue(int idx) const override { + virtual std::shared_ptr getAttributeEncodedValue(int idx) const /*override*/ { return nullptr; } - virtual std::shared_ptr getAttributeEncodedValue(const char* name) const override { + virtual std::shared_ptr getAttributeEncodedValue(const char* name) const /*override*/ { return nullptr; } - virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr decoder) override {} + virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr decoder) /*override*/ {} - virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) override {} + virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) /*override*/ {} private: diff --git a/code/X3DImporter.cpp b/code/X3DImporter.cpp index feaa0ca37..b60c68ae6 100644 --- a/code/X3DImporter.cpp +++ b/code/X3DImporter.cpp @@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Header files, stdlib. #include #include +#include namespace Assimp { @@ -75,8 +76,32 @@ const aiImporterDesc X3DImporter::Description = { "x3d x3db" }; -const std::regex X3DImporter::pattern_nws(R"([^, \t\r\n]+)"); -const std::regex X3DImporter::pattern_true(R"(^\s*(?:true|1)\s*$)", std::regex::icase); +//const std::regex X3DImporter::pattern_nws(R"([^, \t\r\n]+)"); +//const std::regex X3DImporter::pattern_true(R"(^\s*(?:true|1)\s*$)", std::regex::icase); + +struct WordIterator { + static const char *whitespace; + const char *start_, *end_; + WordIterator(const char *start, const char *end): start_(start), end_(end) { + start_ = start + strspn(start, whitespace); + if (start_ >= end_) { + start_ = 0; + } + } + WordIterator(): start_(0), end_(0) {} + bool operator!=(WordIterator &other) const { return start_ != other.start_; } + WordIterator &operator++() { + start_ += strcspn(start_, whitespace); + start_ += strspn(start_, whitespace); + if (start_ >= end_) { + start_ = 0; + } + return *this; + } + const char *operator*() const { return start_; } +}; + +const char *WordIterator::whitespace = ", \t\r\n"; X3DImporter::X3DImporter() : NodeElement_Cur( nullptr ) @@ -473,10 +498,15 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector } else { const char *val = mReader->getAttributeValue(pAttrIdx); - std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); - const std::cregex_iterator wordItEnd; pValue.clear(); - std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::regex_match(match.str(), pattern_true); }); + + //std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); + //const std::cregex_iterator wordItEnd; + //std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::regex_match(match.str(), pattern_true); }); + + WordIterator wordItBegin(val, val + strlen(val)); + WordIterator wordItEnd; + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return (::tolower(match[0]) == 't') || (match[0] == '1'); }); } } @@ -488,10 +518,15 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vect } else { const char *val = mReader->getAttributeValue(pAttrIdx); - std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); - const std::cregex_iterator wordItEnd; pValue.clear(); - std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stoi(match.str()); }); + + //std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); + //const std::cregex_iterator wordItEnd; + //std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stoi(match.str()); }); + + WordIterator wordItBegin(val, val + strlen(val)); + WordIterator wordItEnd; + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atoi(match); }); } } @@ -503,10 +538,15 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector } else { const char *val = mReader->getAttributeValue(pAttrIdx); - std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); - const std::cregex_iterator wordItEnd; pValue.clear(); - std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stof(match.str()); }); + + //std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); + //const std::cregex_iterator wordItEnd; + //std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stof(match.str()); }); + + WordIterator wordItBegin(val, val + strlen(val)); + WordIterator wordItEnd; + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atof(match); }); } } @@ -518,10 +558,15 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector } else { const char *val = mReader->getAttributeValue(pAttrIdx); - std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); - const std::cregex_iterator wordItEnd; pValue.clear(); - std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stod(match.str()); }); + + //std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws); + //const std::cregex_iterator wordItEnd; + //std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stod(match.str()); }); + + WordIterator wordItBegin(val, val + strlen(val)); + WordIterator wordItEnd; + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atof(match); }); } } diff --git a/code/X3DImporter.hpp b/code/X3DImporter.hpp index 58faefb49..2d2d41fdb 100644 --- a/code/X3DImporter.hpp +++ b/code/X3DImporter.hpp @@ -57,7 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BaseImporter.h" #include "irrXMLWrapper.h" #include "FIReader.hpp" -#include +//#include namespace Assimp { @@ -816,8 +816,8 @@ private: /****************** Constants ******************/ /***********************************************/ static const aiImporterDesc Description; - static const std::regex pattern_nws; - static const std::regex pattern_true; + //static const std::regex pattern_nws; + //static const std::regex pattern_true; /***********************************************/ diff --git a/code/X3DImporter_Networking.cpp b/code/X3DImporter_Networking.cpp index 744d805ba..269c58ba3 100644 --- a/code/X3DImporter_Networking.cpp +++ b/code/X3DImporter_Networking.cpp @@ -51,12 +51,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Header files, Assimp. #include -#include +//#include namespace Assimp { -static std::regex pattern_parentDir(R"((^|/)[^/]+/../)"); +//static std::regex pattern_parentDir(R"((^|/)[^/]+/../)"); +static std::string parentDir("/../"); // 0)) { - std::string full_path; + std::string full_path = mpIOHandler->CurrentDirectory() + url.front(); - full_path = std::regex_replace(mpIOHandler->CurrentDirectory() + url.front(), pattern_parentDir, "$1"); + //full_path = std::regex_replace(full_path, pattern_parentDir, "$1"); + for (std::string::size_type pos = full_path.find(parentDir); pos != std::string::npos; pos = full_path.find(parentDir, pos)) { + if (pos > 0) { + std::string::size_type pos2 = full_path.rfind('/', pos - 1); + if (pos2 != std::string::npos) { + full_path.erase(pos2, pos - pos2 + 3); + pos = pos2; + } + else { + full_path.erase(0, pos + 4); + pos = 0; + } + } + else { + pos += 3; + } + } // Attribute "url" can contain list of strings. But we need only one - first. std::string::size_type slashPos = full_path.find_last_of("\\/"); mpIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : full_path.substr(0, slashPos + 1)); From 0a1a4a0b96db1653ea1980cc477b34f38c3596c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20D=C3=A4hne?= Date: Wed, 12 Jul 2017 20:48:49 +0200 Subject: [PATCH 5/6] X3D importer: Fixed iterator on MSVC 2015 --- code/X3DImporter.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/code/X3DImporter.cpp b/code/X3DImporter.cpp index b60c68ae6..111773563 100644 --- a/code/X3DImporter.cpp +++ b/code/X3DImporter.cpp @@ -79,7 +79,7 @@ const aiImporterDesc X3DImporter::Description = { //const std::regex X3DImporter::pattern_nws(R"([^, \t\r\n]+)"); //const std::regex X3DImporter::pattern_true(R"(^\s*(?:true|1)\s*$)", std::regex::icase); -struct WordIterator { +struct WordIterator: public std::iterator { static const char *whitespace; const char *start_, *end_; WordIterator(const char *start, const char *end): start_(start), end_(end) { @@ -89,6 +89,13 @@ struct WordIterator { } } WordIterator(): start_(0), end_(0) {} + WordIterator(const WordIterator &other): start_(other.start_), end_(other.end_) {} + WordIterator &operator=(const WordIterator &other) { + start_ = other.start_; + end_ = other.end_; + return *this; + } + bool operator==(WordIterator &other) const { return start_ == other.start_; } bool operator!=(WordIterator &other) const { return start_ != other.start_; } WordIterator &operator++() { start_ += strcspn(start_, whitespace); @@ -98,6 +105,11 @@ struct WordIterator { } return *this; } + WordIterator operator++(int) { + WordIterator result(*this); + ++(*this); + return result; + } const char *operator*() const { return start_; } }; From 727cffdfb47c8372d51d321a242c94f6439d6588 Mon Sep 17 00:00:00 2001 From: jamesgk Date: Fri, 14 Jul 2017 11:42:55 -0700 Subject: [PATCH 6/6] Use unique node names when loading Collada files --- code/ColladaLoader.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index e82bf1560..c68eb27c9 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -1903,14 +1903,13 @@ const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, c } // ------------------------------------------------------------------------------------------------ -// Finds a proper name for a node derived from the collada-node's properties +// Finds a proper unique name for a node derived from the collada-node's properties. +// The name must be unique for proper node-bone association. std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode) { - // now setup the name of the node. We take the name if not empty, otherwise the collada ID - // FIX: Workaround for XSI calling the instanced visual scene 'untitled' by default. - if (!pNode->mName.empty() && pNode->mName != "untitled") - return pNode->mName; - else if (!pNode->mID.empty()) + // Now setup the name of the assimp node. The collada name might not be + // unique, so we use the collada ID. + if (!pNode->mID.empty()) return pNode->mID; else if (!pNode->mSID.empty()) return pNode->mSID;