diff --git a/code/AssetLib/3MF/3MFXmlTags.h b/code/AssetLib/3MF/3MFXmlTags.h index 3f1fc01ed..0c6b5d1eb 100644 --- a/code/AssetLib/3MF/3MFXmlTags.h +++ b/code/AssetLib/3MF/3MFXmlTags.h @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, diff --git a/code/AssetLib/3MF/D3MFExporter.cpp b/code/AssetLib/3MF/D3MFExporter.cpp index 5b85d275b..8fb9009d1 100644 --- a/code/AssetLib/3MF/D3MFExporter.cpp +++ b/code/AssetLib/3MF/D3MFExporter.cpp @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, diff --git a/code/AssetLib/3MF/D3MFExporter.h b/code/AssetLib/3MF/D3MFExporter.h index 6a447236b..24ddc9bba 100644 --- a/code/AssetLib/3MF/D3MFExporter.h +++ b/code/AssetLib/3MF/D3MFExporter.h @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, diff --git a/code/AssetLib/3MF/D3MFImporter.cpp b/code/AssetLib/3MF/D3MFImporter.cpp index 2093e5e9a..cbb2d4a27 100644 --- a/code/AssetLib/3MF/D3MFImporter.cpp +++ b/code/AssetLib/3MF/D3MFImporter.cpp @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -46,12 +45,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include #include #include #include - #include #include #include @@ -61,7 +60,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "3MFXmlTags.h" #include "D3MFOpcPackage.h" #include -#include #include @@ -73,12 +71,12 @@ public: using MatArray = std::vector; using MatId2MatArray = std::map>; - XmlSerializer(XmlReader *xmlReader) : + XmlSerializer(XmlParser *xmlParser) : mMeshes(), mMatArray(), mActiveMatGroup(99999999), mMatId2MatArray(), - xmlReader(xmlReader) { + mXmlParser(xmlParser) { // empty } @@ -95,16 +93,17 @@ public: std::vector children; std::string nodeName; - while (ReadToEndElement(D3MF::XmlTag::model)) { - nodeName = xmlReader->getNodeName(); - if (nodeName == D3MF::XmlTag::object) { - children.push_back(ReadObject(scene)); - } else if (nodeName == D3MF::XmlTag::build) { + XmlNode *root = mXmlParser->getRootNode(); + for (XmlNode ¤tNode : root->children()) { + const std::string ¤tNodeName = currentNode.name(); + if (currentNodeName == D3MF::XmlTag::object) { + children.push_back(ReadObject(currentNode, scene)); + } else if (currentNodeName == D3MF::XmlTag::build) { // - } else if (nodeName == D3MF::XmlTag::basematerials) { - ReadBaseMaterials(); - } else if (nodeName == D3MF::XmlTag::meta) { - ReadMetadata(); + } else if (currentNodeName == D3MF::XmlTag::basematerials) { + ReadBaseMaterials(currentNode); + } else if (currentNodeName == D3MF::XmlTag::meta) { + ReadMetadata(currentNode); } } @@ -141,31 +140,30 @@ public: } private: - aiNode *ReadObject(aiScene *scene) { - std::unique_ptr node(new aiNode()); + aiNode *ReadObject(XmlNode &node, aiScene *scene) { + std::unique_ptr nodePtr(new aiNode()); std::vector meshIds; - const char *attrib(nullptr); std::string name, type; - attrib = xmlReader->getAttributeValue(D3MF::XmlTag::id.c_str()); - if (nullptr != attrib) { - name = attrib; + pugi::xml_attribute attr = node.attribute(D3MF::XmlTag::id.c_str()); + if (!attr.empty()) { + name = attr.as_string(); } - attrib = xmlReader->getAttributeValue(D3MF::XmlTag::type.c_str()); - if (nullptr != attrib) { - type = attrib; + attr = node.attribute(D3MF::XmlTag::id.c_str()); + if (!attr.empty()) { + type = attr.as_string(); } - node->mParent = scene->mRootNode; - node->mName.Set(name); + nodePtr->mParent = scene->mRootNode; + nodePtr->mName.Set(name); size_t meshIdx = mMeshes.size(); - while (ReadToEndElement(D3MF::XmlTag::object)) { - if (xmlReader->getNodeName() == D3MF::XmlTag::mesh) { - auto mesh = ReadMesh(); - + for (pugi::xml_node ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == D3MF::XmlTag::mesh) { + auto mesh = ReadMesh(currentNode); mesh->mName.Set(name); mMeshes.push_back(mesh); meshIds.push_back(static_cast(meshIdx)); @@ -173,33 +171,34 @@ private: } } - node->mNumMeshes = static_cast(meshIds.size()); + nodePtr->mNumMeshes = static_cast(meshIds.size()); - node->mMeshes = new unsigned int[node->mNumMeshes]; + nodePtr->mMeshes = new unsigned int[nodePtr->mNumMeshes]; - std::copy(meshIds.begin(), meshIds.end(), node->mMeshes); + std::copy(meshIds.begin(), meshIds.end(), nodePtr->mMeshes); - return node.release(); + return nodePtr.release(); } - aiMesh *ReadMesh() { + aiMesh *ReadMesh(XmlNode &node) { aiMesh *mesh = new aiMesh(); - while (ReadToEndElement(D3MF::XmlTag::mesh)) { - if (xmlReader->getNodeName() == D3MF::XmlTag::vertices) { - ImportVertices(mesh); - } else if (xmlReader->getNodeName() == D3MF::XmlTag::triangles) { - ImportTriangles(mesh); + for (pugi::xml_node ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == D3MF::XmlTag::vertices) { + ImportVertices(currentNode, mesh); + } else if (currentName == D3MF::XmlTag::triangles) { + ImportTriangles(currentNode, mesh); } + } return mesh; } - void ReadMetadata() { - const std::string name = xmlReader->getAttributeValue(D3MF::XmlTag::meta_name.c_str()); - xmlReader->read(); - const std::string value = xmlReader->getNodeData(); - + void ReadMetadata(XmlNode &node) { + pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name.c_str()); + const std::string name = attribute.as_string(); + const std::string value = node.value(); if (name.empty()) { return; } @@ -210,37 +209,36 @@ private: mMetaData.push_back(entry); } - void ImportVertices(aiMesh *mesh) { + void ImportVertices(XmlNode &node, aiMesh *mesh) { std::vector vertices; - while (ReadToEndElement(D3MF::XmlTag::vertices)) { - if (xmlReader->getNodeName() == D3MF::XmlTag::vertex) { - vertices.push_back(ReadVertex()); + for (pugi::xml_node ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == D3MF::XmlTag::vertex) { + vertices.push_back(ReadVertex(currentNode)); } } + mesh->mNumVertices = static_cast(vertices.size()); mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - std::copy(vertices.begin(), vertices.end(), mesh->mVertices); } - aiVector3D ReadVertex() { + aiVector3D ReadVertex(XmlNode &node) { aiVector3D vertex; - - vertex.x = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::x.c_str()), nullptr); - vertex.y = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::y.c_str()), nullptr); - vertex.z = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::z.c_str()), nullptr); + vertex.x = ai_strtof(node.attribute(D3MF::XmlTag::x.c_str()).as_string(), nullptr); + vertex.x = ai_strtof(node.attribute(D3MF::XmlTag::y.c_str()).as_string(), nullptr); + vertex.z = ai_strtof(node.attribute(D3MF::XmlTag::z.c_str()).as_string(), nullptr); return vertex; } - void ImportTriangles(aiMesh *mesh) { + void ImportTriangles(XmlNode &node, aiMesh *mesh) { std::vector faces; - - while (ReadToEndElement(D3MF::XmlTag::triangles)) { - const std::string nodeName(xmlReader->getNodeName()); - if (xmlReader->getNodeName() == D3MF::XmlTag::triangle) { - faces.push_back(ReadTriangle()); - const char *pidToken(xmlReader->getAttributeValue(D3MF::XmlTag::p1.c_str())); + for (pugi::xml_node ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == D3MF::XmlTag::triangle) { + faces.push_back(ReadTriangle(currentNode)); + const char *pidToken = currentNode.attribute(D3MF::XmlTag::p1.c_str()).as_string(); if (nullptr != pidToken) { int matIdx(std::atoi(pidToken)); mesh->mMaterialIndex = matIdx; @@ -255,21 +253,21 @@ private: std::copy(faces.begin(), faces.end(), mesh->mFaces); } - aiFace ReadTriangle() { + aiFace ReadTriangle(XmlNode &node) { aiFace face; face.mNumIndices = 3; face.mIndices = new unsigned int[face.mNumIndices]; - face.mIndices[0] = static_cast(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v1.c_str()))); - face.mIndices[1] = static_cast(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v2.c_str()))); - face.mIndices[2] = static_cast(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v3.c_str()))); + face.mIndices[0] = static_cast(std::atoi(node.attribute(D3MF::XmlTag::v1.c_str()).as_string())); + face.mIndices[1] = static_cast(std::atoi(node.attribute(D3MF::XmlTag::v2.c_str()).as_string())); + face.mIndices[2] = static_cast(std::atoi(node.attribute(D3MF::XmlTag::v3.c_str()).as_string())); return face; } - void ReadBaseMaterials() { + void ReadBaseMaterials(XmlNode &node) { std::vector MatIdArray; - const char *baseMaterialId(xmlReader->getAttributeValue(D3MF::XmlTag::basematerials_id.c_str())); + const char *baseMaterialId = node.attribute(D3MF::XmlTag::basematerials_id.c_str()).as_string(); if (nullptr != baseMaterialId) { unsigned int id = std::atoi(baseMaterialId); const size_t newMatIdx(mMatArray.size()); @@ -287,9 +285,7 @@ private: mMatId2MatArray[mActiveMatGroup] = MatIdArray; } - while (ReadToEndElement(D3MF::XmlTag::basematerials)) { - mMatArray.push_back(readMaterialDef()); - } + mMatArray.push_back(readMaterialDef(node)); } bool parseColor(const char *color, aiColor4D &diffuse) { @@ -339,19 +335,23 @@ private: return true; } - void assignDiffuseColor(aiMaterial *mat) { - const char *color = xmlReader->getAttributeValue(D3MF::XmlTag::basematerials_displaycolor.c_str()); + void assignDiffuseColor(XmlNode &node, aiMaterial *mat) { + const char *color = node.attribute(D3MF::XmlTag::basematerials_displaycolor.c_str()).as_string(); + //const char *color = xmlReader->getAttributeValue(D3MF::XmlTag::basematerials_displaycolor.c_str()); aiColor4D diffuse; if (parseColor(color, diffuse)) { mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); } } - aiMaterial *readMaterialDef() { + + aiMaterial *readMaterialDef(XmlNode &node) { aiMaterial *mat(nullptr); const char *name(nullptr); - const std::string nodeName(xmlReader->getNodeName()); + const std::string nodeName = node.name(); + //const std::string nodeName(xmlReader->getNodeName()); if (nodeName == D3MF::XmlTag::basematerials_base) { - name = xmlReader->getAttributeValue(D3MF::XmlTag::basematerials_name.c_str()); + name = node.attribute(D3MF::XmlTag::basematerials_name.c_str()).as_string(); + //name = xmlReader->getAttributeValue(D3MF::XmlTag::basematerials_name.c_str()); std::string stdMatName; aiString matName; std::string strId(to_string(mActiveMatGroup)); @@ -368,40 +368,12 @@ private: mat = new aiMaterial; mat->AddProperty(&matName, AI_MATKEY_NAME); - assignDiffuseColor(mat); + assignDiffuseColor(node, mat); } return mat; } -private: - bool ReadToStartElement(const std::string &startTag) { - while (xmlReader->read()) { - const std::string &nodeName(xmlReader->getNodeName()); - if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && nodeName == startTag) { - return true; - } else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END && nodeName == startTag) { - return false; - } - } - - return false; - } - - bool ReadToEndElement(const std::string &closeTag) { - while (xmlReader->read()) { - const std::string &nodeName(xmlReader->getNodeName()); - if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT) { - return true; - } else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END && nodeName == closeTag) { - return false; - } - } - ASSIMP_LOG_ERROR("unexpected EOF, expected closing <" + closeTag + "> tag"); - - return false; - } - private: struct MetaEntry { std::string name; @@ -412,7 +384,7 @@ private: MatArray mMatArray; unsigned int mActiveMatGroup; MatId2MatArray mMatId2MatArray; - XmlReader *xmlReader; + XmlParser *mXmlParser; }; } //namespace D3MF @@ -468,12 +440,14 @@ const aiImporterDesc *D3MFImporter::GetInfo() const { void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) { D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename); - std::unique_ptr xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream())); - std::unique_ptr xmlReader(irr::io::createIrrXMLReader(xmlStream.get())); + //std::unique_ptr xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream())); + //std::unique_ptr xmlReader(irr::io::createIrrXMLReader(xmlStream.get())); - D3MF::XmlSerializer xmlSerializer(xmlReader.get()); - - xmlSerializer.ImportXml(pScene); + XmlParser xmlParser; + if (xmlParser.parse(opcPackage.RootStream())) { + D3MF::XmlSerializer xmlSerializer(&xmlParser); + xmlSerializer.ImportXml(pScene); + } } } // Namespace Assimp diff --git a/code/AssetLib/3MF/D3MFOpcPackage.cpp b/code/AssetLib/3MF/D3MFOpcPackage.cpp index e8e1e2f5e..d9508603e 100644 --- a/code/AssetLib/3MF/D3MFOpcPackage.cpp +++ b/code/AssetLib/3MF/D3MFOpcPackage.cpp @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -45,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "D3MFOpcPackage.h" #include +#include #include #include #include @@ -68,27 +68,23 @@ typedef std::shared_ptr OpcPackageRelationshipPtr; class OpcPackageRelationshipReader { public: - OpcPackageRelationshipReader(XmlReader *xmlReader) { - while (xmlReader->read()) { - if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && - xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER) { - ParseRootNode(xmlReader); - } + OpcPackageRelationshipReader(XmlParser &parser) { + XmlNode *root = parser.getRootNode(); + if (nullptr != root) { + ParseRootNode(*root); } } - void ParseRootNode(XmlReader *xmlReader) { - ParseAttributes(xmlReader); + void ParseRootNode(XmlNode &node) { + ParseAttributes(node); + + for (XmlNode currentNode : node.children()) { + ParseChildNode(currentNode); - while (xmlReader->read()) { - if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && - xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE) { - ParseChildNode(xmlReader); - } } } - void ParseAttributes(XmlReader *) { + void ParseAttributes(XmlNode &/*node*/) { // empty } @@ -99,12 +95,12 @@ public: return true; } - void ParseChildNode(XmlReader *xmlReader) { + void ParseChildNode(XmlNode &node) { OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship()); - relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str()); - relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str()); - relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str()); + relPtr->id = node.attribute(XmlTag::RELS_ATTRIB_ID.c_str()).as_string(); + relPtr->type = node.attribute(XmlTag::RELS_ATTRIB_TYPE.c_str()).as_string(); + relPtr->target = node.attribute(XmlTag::RELS_ATTRIB_TARGET.c_str()).as_string(); if (validateRels(relPtr)) { m_relationShips.push_back(relPtr); } @@ -115,7 +111,8 @@ public: // ------------------------------------------------------------------------------------------------ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) : - mRootStream(nullptr), mZipArchive() { + mRootStream(nullptr), + mZipArchive() { mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile)); if (!mZipArchive->isOpen()) { throw DeadlyImportError("Failed to open file " + rFile + "."); @@ -182,10 +179,12 @@ bool D3MFOpcPackage::validate() { } std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) { - std::unique_ptr xmlStream(new CIrrXML_IOStreamReader(stream)); - std::unique_ptr xml(irr::io::createIrrXMLReader(xmlStream.get())); + XmlParser xmlParser; + if (!xmlParser.parse(stream)) { + return ""; + } - OpcPackageRelationshipReader reader(xml.get()); + OpcPackageRelationshipReader reader(xmlParser); auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr &rel) { return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; diff --git a/code/AssetLib/3MF/D3MFOpcPackage.h b/code/AssetLib/3MF/D3MFOpcPackage.h index 291f8ad53..10a86f0a5 100644 --- a/code/AssetLib/3MF/D3MFOpcPackage.h +++ b/code/AssetLib/3MF/D3MFOpcPackage.h @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -44,18 +43,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define D3MFOPCPACKAGE_H #include - +#include #include -#include +//#include namespace Assimp { class ZipArchiveIOSystem; namespace D3MF { -using XmlReader = irr::io::IrrXMLReader ; -using XmlReaderPtr = std::shared_ptr ; - struct OpcPackageRelationship { std::string id; std::string type; @@ -64,7 +60,7 @@ struct OpcPackageRelationship { class D3MFOpcPackage { public: - D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile ); + D3MFOpcPackage( IOSystem* pIOHandler, const std::string& file ); ~D3MFOpcPackage(); IOStream* RootStream() const; bool validate(); diff --git a/code/AssetLib/X3D/FIReader.cpp b/code/AssetLib/X3D/FIReader.cpp deleted file mode 100644 index 6361399ce..000000000 --- a/code/AssetLib/X3D/FIReader.cpp +++ /dev/null @@ -1,1864 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 - -// Workaround for issue #1361 -// https://github.com/assimp/assimp/issues/1361 -#ifdef __ANDROID__ -#define _GLIBCXX_USE_C99 1 -#endif - -#include -#include -#include -#include -#ifdef ASSIMP_USE_HUNTER -#include -#else -#include "../contrib/utf8cpp/source/utf8.h" -#endif -#include -#include -#include -#include -#include -#include - -namespace Assimp { - -static const char *parseErrorMessage = "Fast Infoset parse error"; - -static const char *xmlDeclarations[] = { - "", - "", - "", - "", - "", - "", - "", - "", - "" -}; - -static size_t parseMagic(const uint8_t *data, const uint8_t *dataEnd) { - ai_assert(nullptr != data); - ai_assert(nullptr != 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 { - FIStringValueImpl(std::string &&value_) { - value = std::move(value_); - } - - 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; - - FIHexValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - 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; - - FIBase64ValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - const std::string &toString() const override { - if (!strValueValid) { - strValueValid = true; - std::ostringstream os; - uint8_t c1 = 0, c2; - int imod3 = 0; - std::vector::size_type valueSize = value.size(); - for (std::vector::size_type 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; - - FIShortValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - 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; - - FIIntValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - 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; - - FILongValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - 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; - - FIBoolValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - 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; - - FIFloatValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - 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; - - FIDoubleValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - 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; - - FIUUIDValueImpl(std::vector &&value_) : - strValueValid(false) { - value = std::move(value_); - } - - const std::string &toString() const override { - if (!strValueValid) { - strValueValid = true; - std::ostringstream os; - os << std::hex << std::uppercase << std::setfill('0'); - 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) { - 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 { - FICDATAValueImpl(std::string &&value_) { - value = std::move(value_); - } - - 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 { - std::shared_ptr decode(const uint8_t *data, size_t len) override { - return FIHexValue::create(std::vector(data, data + len)); - } -}; - -struct FIBase64Decoder : public FIDecoder { - std::shared_ptr decode(const uint8_t *data, size_t len) override { - return FIBase64Value::create(std::vector(data, data + len)); - } -}; - -struct FIShortDecoder : public FIDecoder { - 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 { - 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 { - 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]; - float f; - memcpy(&f, &v, 4); - value.push_back(f); - 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; - double f; - memcpy(&f, &v, 8); - value.push_back(f); - 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) { - // empty - } - - ~CFIReaderImpl() override { - // override - } - - virtual bool read() { - if (headerPending) { - headerPending = false; - parseHeader(); - } - if (terminatorPending) { - terminatorPending = false; - if (elementStack.empty()) { - return false; - } - 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 atoi(attr->value->toString().c_str()); - } - - 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 atoi(attributes[idx].value->toString().c_str()); - } - - 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 fast_atof(attr->value->toString().c_str()); - } - - 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 fast_atof(attributes[idx].value->toString().c_str()); - } - - 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 " + to_string(index)); - } - return decoder->decode(dataP, len); - } else { - if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) { - throw DeadlyImportError("Invalid encoding algorithm index " + 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 " + to_string(index)); - } - } else { - if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) { - throw DeadlyImportError("Invalid restricted alphabet index " + 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 " + 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; - const size_t charIndex = (bits >> bitsAvail) & mask; - if (charIndex < alphabetLength) { - s += (char)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/AssetLib/X3D/FIReader.hpp b/code/AssetLib/X3D/FIReader.hpp deleted file mode 100644 index bc7bbb03e..000000000 --- a/code/AssetLib/X3D/FIReader.hpp +++ /dev/null @@ -1,186 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include -#include -#include -#include -#include - -#include - -namespace Assimp { - -struct FIValue { - virtual const std::string &toString() const = 0; - virtual ~FIValue() {} -}; - -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; - virtual ~FIDecoder() {} -}; - -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: - virtual ~FIReader(); - - 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; - - virtual bool read() = 0; - - static std::unique_ptr create(IOStream *stream); - -}; // class IFIReader - -inline FIReader::~FIReader() { - // empty -} - -} // namespace Assimp - -#endif // #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#endif // INCLUDED_AI_FI_READER_H diff --git a/code/AssetLib/X3D/X3DImporter.cpp b/code/AssetLib/X3D/X3DImporter.cpp index fd61fc62c..ea4525f6b 100644 --- a/code/AssetLib/X3D/X3DImporter.cpp +++ b/code/AssetLib/X3D/X3DImporter.cpp @@ -46,11 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER #include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" #include // Header files, Assimp. -//#include "FIReader.hpp" #include #include @@ -75,14 +73,6 @@ 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); - -namespace { - - -} // namespace - struct WordIterator { using iterator_category = std::input_iterator_tag; using value_type = const char *; @@ -133,10 +123,11 @@ struct WordIterator { const char *operator*() const { return mStart; } }; -static const char *WordIterator::whitespace = ", \t\r\n"; +//static const char *WordIterator::whitespace = ", \t\r\n"; X3DImporter::X3DImporter() : - mNodeElementCur(nullptr), mReader(nullptr) { + mNodeElementCur(nullptr), + mXmlParser(nullptr) { // empty } @@ -160,1255 +151,6 @@ void X3DImporter::Clear() { /************************************************************ Functions: find set ************************************************************/ /*********************************************************************************************************************************************/ -bool X3DImporter::FindNodeElement_FromRoot(const std::string &pID, const X3DNodeElementBase::EType pType, X3DNodeElementBase **pElement) { - for (std::list::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it) { - if (((*it)->Type == pType) && ((*it)->ID == pID)) { - if (pElement != nullptr) *pElement = *it; - - return true; - } - } // for(std::list::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++) - - return false; -} - -bool X3DImporter::FindNodeElement_FromNode(X3DNodeElementBase *pStartNode, const std::string &pID, - const X3DNodeElementBase::EType pType, X3DNodeElementBase **pElement) { - bool found = false; // flag: true - if requested element is found. - - // Check if pStartNode - this is the element, we are looking for. - if ((pStartNode->Type == pType) && (pStartNode->ID == pID)) { - found = true; - if (pElement != nullptr) { - *pElement = pStartNode; - } - - goto fne_fn_end; - } // if((pStartNode->Type() == pType) && (pStartNode->ID() == pID)) - - // Check children of pStartNode. - for (std::list::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ++ch_it) { - found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement); - if (found) { - break; - } - } // for(std::list::iterator ch_it = it->Child.begin(); ch_it != it->Child.end(); ch_it++) - -fne_fn_end: - - return found; -} - -bool X3DImporter::FindNodeElement(const std::string &pID, const X3DNodeElementBase::EType pType, X3DNodeElementBase **pElement) { - X3DNodeElementBase *tnd = mNodeElementCur; // temporary pointer to node. - bool static_search = false; // flag: true if searching in static node. - - // At first check if we have deal with static node. Go up through parent nodes and check flag. - while (tnd != nullptr) { - if (tnd->Type == X3DNodeElementBase::ENET_Group) { - if (((X3DGroup *)tnd)->Static) { - static_search = true; // Flag found, stop walking up. Node with static flag will holded in tnd variable. - break; - } - } - - tnd = tnd->Parent; // go up in graph. - } // while(tnd != nullptr) - - // at now call appropriate search function. - if (static_search) { - return FindNodeElement_FromNode(tnd, pID, pType, pElement); - } else { - return FindNodeElement_FromRoot(pID, pType, pElement); - } -} - -/*********************************************************************************************************************************************/ -/************************************************************ Functions: throw set ***********************************************************/ -/*********************************************************************************************************************************************/ - -/*********************************************************************************************************************************************/ -/************************************************************* Functions: XML set ************************************************************/ -/*********************************************************************************************************************************************/ - -void X3DImporter::XML_CheckNode_MustBeEmpty() { - if (!mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must be empty."); -} - -void X3DImporter::XML_CheckNode_SkipUnsupported(const std::string &pParentNodeName) { - static const size_t Uns_Skip_Len = 192; - const char *Uns_Skip[Uns_Skip_Len] = { - // CAD geometry component - "CADAssembly", "CADFace", "CADLayer", "CADPart", "IndexedQuadSet", "QuadSet", - // Core - "ROUTE", "ExternProtoDeclare", "ProtoDeclare", "ProtoInstance", "ProtoInterface", "WorldInfo", - // Distributed interactive simulation (DIS) component - "DISEntityManager", "DISEntityTypeMapping", "EspduTransform", "ReceiverPdu", "SignalPdu", "TransmitterPdu", - // Cube map environmental texturing component - "ComposedCubeMapTexture", "GeneratedCubeMapTexture", "ImageCubeMapTexture", - // Environmental effects component - "Background", "Fog", "FogCoordinate", "LocalFog", "TextureBackground", - // Environmental sensor component - "ProximitySensor", "TransformSensor", "VisibilitySensor", - // Followers component - "ColorChaser", "ColorDamper", "CoordinateChaser", "CoordinateDamper", "OrientationChaser", "OrientationDamper", "PositionChaser", "PositionChaser2D", - "PositionDamper", "PositionDamper2D", "ScalarChaser", "ScalarDamper", "TexCoordChaser2D", "TexCoordDamper2D", - // Geospatial component - "GeoCoordinate", "GeoElevationGrid", "GeoLocation", "GeoLOD", "GeoMetadata", "GeoOrigin", "GeoPositionInterpolator", "GeoProximitySensor", - "GeoTouchSensor", "GeoTransform", "GeoViewpoint", - // Humanoid Animation (H-Anim) component - "HAnimDisplacer", "HAnimHumanoid", "HAnimJoint", "HAnimSegment", "HAnimSite", - // Interpolation component - "ColorInterpolator", "CoordinateInterpolator", "CoordinateInterpolator2D", "EaseInEaseOut", "NormalInterpolator", "OrientationInterpolator", - "PositionInterpolator", "PositionInterpolator2D", "ScalarInterpolator", "SplinePositionInterpolator", "SplinePositionInterpolator2D", - "SplineScalarInterpolator", "SquadOrientationInterpolator", - // Key device sensor component - "KeySensor", "StringSensor", - // Layering component - "Layer", "LayerSet", "Viewport", - // Layout component - "Layout", "LayoutGroup", "LayoutLayer", "ScreenFontStyle", "ScreenGroup", - // Navigation component - "Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup", - // Networking component - "EXPORT", "IMPORT", "Anchor", "LoadSensor", - // NURBS component - "Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface", - "NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate", - "NurbsTrimmedSurface", - // Particle systems component - "BoundedPhysicsModel", "ConeEmitter", "ExplosionEmitter", "ForcePhysicsModel", "ParticleSystem", "PointEmitter", "PolylineEmitter", "SurfaceEmitter", - "VolumeEmitter", "WindPhysicsModel", - // Picking component - "LinePickSensor", "PickableGroup", "PointPickSensor", "PrimitivePickSensor", "VolumePickSensor", - // Pointing device sensor component - "CylinderSensor", "PlaneSensor", "SphereSensor", "TouchSensor", - // Rendering component - "ClipPlane", - // Rigid body physics - "BallJoint", "CollidableOffset", "CollidableShape", "CollisionCollection", "CollisionSensor", "CollisionSpace", "Contact", "DoubleAxisHingeJoint", - "MotorJoint", "RigidBody", "RigidBodyCollection", "SingleAxisHingeJoint", "SliderJoint", "UniversalJoint", - // Scripting component - "Script", - // Programmable shaders component - "ComposedShader", "FloatVertexAttribute", "Matrix3VertexAttribute", "Matrix4VertexAttribute", "PackagedShader", "ProgramShader", "ShaderPart", - "ShaderProgram", - // Shape component - "FillProperties", "LineProperties", "TwoSidedMaterial", - // Sound component - "AudioClip", "Sound", - // Text component - "FontStyle", "Text", - // Texturing3D Component - "ComposedTexture3D", "ImageTexture3D", "PixelTexture3D", "TextureCoordinate3D", "TextureCoordinate4D", "TextureTransformMatrix3D", "TextureTransform3D", - // Texturing component - "MovieTexture", "MultiTexture", "MultiTextureCoordinate", "MultiTextureTransform", "PixelTexture", "TextureCoordinateGenerator", "TextureProperties", - // Time component - "TimeSensor", - // Event Utilities component - "BooleanFilter", "BooleanSequencer", "BooleanToggle", "BooleanTrigger", "IntegerSequencer", "IntegerTrigger", "TimeTrigger", - // Volume rendering component - "BlendedVolumeStyle", "BoundaryEnhancementVolumeStyle", "CartoonVolumeStyle", "ComposedVolumeStyle", "EdgeEnhancementVolumeStyle", "IsoSurfaceVolumeData", - "OpacityMapVolumeStyle", "ProjectionVolumeStyle", "SegmentedVolumeData", "ShadedVolumeStyle", "SilhouetteEnhancementVolumeStyle", "ToneMappedVolumeStyle", - "VolumeData" - }; - - const std::string nn(mReader->getNodeName()); - bool found = false; - bool close_found = false; - - for (size_t i = 0; i < Uns_Skip_Len; i++) { - if (nn == Uns_Skip[i]) { - found = true; - if (mReader->isEmptyElement()) { - close_found = true; - - goto casu_cres; - } - - while (mReader->read()) { - if ((mReader->getNodeType() == irr::io::EXN_ELEMENT_END) && (nn == mReader->getNodeName())) { - close_found = true; - - goto casu_cres; - } - } - } - } - -casu_cres: - - if (!found) throw DeadlyImportError("Unknown node \"" + nn + "\" in " + pParentNodeName + "."); - - if (close_found) - LogInfo("Skipping node \"" + nn + "\" in " + pParentNodeName + "."); - else - Throw_CloseNotFound(nn); -} - -bool X3DImporter::XML_SearchNode(const std::string &pNodeName) { - while (mReader->read()) { - if ((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true; - } - - return false; -} - -bool X3DImporter::XML_ReadNode_GetAttrVal_AsBool(const int 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 + "\""); - } -} - -float X3DImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx) { - 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); - - return tvalf; - } -} - -int32_t X3DImporter::XML_ReadNode_GetAttrVal_AsI32(const int 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::vector tlist; - std::vector::iterator it; - - XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist); - if (tlist.size() != 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx)); - - it = tlist.begin(); - pValue.r = *it++; - pValue.g = *it++; - pValue.b = *it; -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D &pValue) { - std::vector tlist; - std::vector::iterator it; - - XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist); - if (tlist.size() != 2) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx)); - - it = tlist.begin(); - pValue.x = *it++; - pValue.y = *it; -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D &pValue) { - std::vector tlist; - std::vector::iterator it; - - XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist); - if (tlist.size() != 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx)); - - it = tlist.begin(); - pValue.x = *it++; - pValue.y = *it++; - pValue.z = *it; -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector &pValue) { - auto boolValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); - if (boolValue) { - pValue = boolValue->value; - } else { - const char *val = mReader->getAttributeValue(pAttrIdx); - pValue.clear(); - - //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'); }); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector &pValue) { - auto intValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); - if (intValue) { - pValue = intValue->value; - } else { - const char *val = mReader->getAttributeValue(pAttrIdx); - pValue.clear(); - - //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); }); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector &pValue) { - auto floatValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); - if (floatValue) { - pValue = floatValue->value; - } else { - const char *val = mReader->getAttributeValue(pAttrIdx); - pValue.clear(); - - //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 static_cast(atof(match)); }); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector &pValue) { - auto doubleValue = std::dynamic_pointer_cast(mReader->getAttributeEncodedValue(pAttrIdx)); - if (doubleValue) { - pValue = doubleValue->value; - } else { - const char *val = mReader->getAttributeValue(pAttrIdx); - pValue.clear(); - - //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); }); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list &pValue) { - std::vector tlist; - - 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::vector::iterator it = tlist.begin(); it != tlist.end();) { - aiColor3D tcol; - - tcol.r = *it++; - tcol.g = *it++; - tcol.b = *it++; - pValue.push_back(tcol); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::vector &pValue) { - std::list tlist; - - XML_ReadNode_GetAttrVal_AsListCol3f(pAttrIdx, tlist); // read as list - // and copy to array - if (!tlist.empty()) { - pValue.reserve(tlist.size()); - for (std::list::iterator it = tlist.begin(); it != tlist.end(); ++it) - pValue.push_back(*it); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list &pValue) { - std::vector tlist; - - 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::vector::iterator it = tlist.begin(); it != tlist.end();) { - aiColor4D tcol; - - tcol.r = *it++; - tcol.g = *it++; - tcol.b = *it++; - tcol.a = *it++; - pValue.push_back(tcol); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::vector &pValue) { - std::list tlist; - - XML_ReadNode_GetAttrVal_AsListCol4f(pAttrIdx, tlist); // read as list - // and copy to array - if (!tlist.empty()) { - pValue.reserve(tlist.size()); - for (std::list::iterator it = tlist.begin(); it != tlist.end(); ++it) { - pValue.push_back(*it); - } - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list &pValue) { - std::vector tlist; - - 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::vector::iterator it = tlist.begin(); it != tlist.end();) { - aiVector2D tvec; - - tvec.x = *it++; - tvec.y = *it++; - pValue.push_back(tvec); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::vector &pValue) { - std::list tlist; - - XML_ReadNode_GetAttrVal_AsListVec2f(pAttrIdx, tlist); // read as list - // and copy to array - if (!tlist.empty()) { - pValue.reserve(tlist.size()); - for (std::list::iterator it = tlist.begin(); it != tlist.end(); ++it) { - pValue.push_back(*it); - } - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list &pValue) { - std::vector tlist; - - 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::vector::iterator it = tlist.begin(); it != tlist.end();) { - aiVector3D tvec; - - tvec.x = *it++; - tvec.y = *it++; - tvec.z = *it++; - pValue.push_back(tvec); - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::vector &pValue) { - std::list tlist; - - XML_ReadNode_GetAttrVal_AsListVec3f(pAttrIdx, tlist); // read as list - // and copy to array - if (!tlist.empty()) { - pValue.reserve(tlist.size()); - for (std::list::iterator it = tlist.begin(); it != tlist.end(); ++it) { - pValue.push_back(*it); - } - } -} - -void X3DImporter::XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list &pValue) { - // make copy of attribute value - strings list. - const size_t tok_str_len = strlen(mReader->getAttributeValue(pAttrIdx)); - if (0 == tok_str_len) { - Throw_IncorrectAttrValue(mReader->getAttributeName(pAttrIdx)); - } - - // get pointer to begin of value. - char *tok_str = const_cast(mReader->getAttributeValue(pAttrIdx)); - char *tok_str_end = tok_str + tok_str_len; - // string list has following format: attr_name='"s1" "s2" "sn"'. - do { - char *tbeg; - char *tend; - size_t tlen; - std::string tstr; - - // find begin of string(element of string list): "sn". - tbeg = strstr(tok_str, "\""); - if (tbeg == nullptr) Throw_IncorrectAttrValue(mReader->getAttributeName(pAttrIdx)); - - tbeg++; // forward pointer from '\"' symbol to next after it. - tok_str = tbeg; - // find end of string(element of string list): "sn". - tend = strstr(tok_str, "\""); - if (tend == nullptr) Throw_IncorrectAttrValue(mReader->getAttributeName(pAttrIdx)); - - tok_str = tend + 1; - // create storage for new string - tlen = tend - tbeg; - tstr.resize(tlen); // reserve enough space and copy data - memcpy((void *)tstr.data(), tbeg, tlen); // not strcpy because end of copied string from tok_str has no terminator. - // and store string in output list. - pValue.push_back(tstr); - } while (tok_str < tok_str_end); -} - -/*********************************************************************************************************************************************/ -/****************************************************** Functions: geometry helper set ******************************************************/ -/*********************************************************************************************************************************************/ - -aiVector3D X3DImporter::GeometryHelper_Make_Point2D(const float pAngle, const float pRadius) { - return aiVector3D(pRadius * std::cos(pAngle), pRadius * std::sin(pAngle), 0); -} - -void X3DImporter::GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, - std::list &pVertices) { - // check argument values ranges. - if ((pStartAngle < -AI_MATH_TWO_PI_F) || (pStartAngle > AI_MATH_TWO_PI_F)) { - Throw_ArgOutOfRange("GeometryHelper_Make_Arc2D.pStartAngle"); - } - if ((pEndAngle < -AI_MATH_TWO_PI_F) || (pEndAngle > AI_MATH_TWO_PI_F)) { - Throw_ArgOutOfRange("GeometryHelper_Make_Arc2D.pEndAngle"); - } - if (pRadius <= 0) { - Throw_ArgOutOfRange("GeometryHelper_Make_Arc2D.pRadius"); - } - - // calculate arc angle and check type of arc - float angle_full = std::fabs(pEndAngle - pStartAngle); - if ((angle_full > AI_MATH_TWO_PI_F) || (angle_full == 0.0f)) { - angle_full = AI_MATH_TWO_PI_F; - } - - // calculate angle for one step - angle to next point of line. - float angle_step = angle_full / (float)pNumSegments; - // make points - for (size_t pi = 0; pi <= pNumSegments; pi++) { - float tangle = pStartAngle + pi * angle_step; - pVertices.push_back(GeometryHelper_Make_Point2D(tangle, pRadius)); - } // for(size_t pi = 0; pi <= pNumSegments; pi++) - - // if we making full circle then add last vertex equal to first vertex - if (angle_full == AI_MATH_TWO_PI_F) pVertices.push_back(*pVertices.begin()); -} - -void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list &pPoint, std::list &pLine) { - std::list::const_iterator pit = pPoint.begin(); - std::list::const_iterator pit_last = pPoint.end(); - - --pit_last; - - if (pPoint.size() < 2) { - Throw_ArgOutOfRange("GeometryHelper_Extend_PointToLine.pPoint.size() can not be less than 2."); - } - - // add first point of first line. - pLine.push_back(*pit++); - // add internal points - while (pit != pit_last) { - pLine.push_back(*pit); // second point of previous line - pLine.push_back(*pit); // first point of next line - ++pit; - } - // add last point of last line - pLine.push_back(*pit); -} - -void X3DImporter::GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list &pPolylineCoordIdx, std::list &pLineCoordIdx) { - std::list::const_iterator plit = pPolylineCoordIdx.begin(); - - while (plit != pPolylineCoordIdx.end()) { - // add first point of polyline - pLineCoordIdx.push_back(*plit++); - while ((*plit != (-1)) && (plit != pPolylineCoordIdx.end())) { - std::list::const_iterator plit_next; - - plit_next = plit, ++plit_next; - pLineCoordIdx.push_back(*plit); // second point of previous line. - pLineCoordIdx.push_back(-1); // delimiter - if ((*plit_next == (-1)) || (plit_next == pPolylineCoordIdx.end())) break; // current polyline is finished - - pLineCoordIdx.push_back(*plit); // first point of next line. - plit = plit_next; - } // while((*plit != (-1)) && (plit != pPolylineCoordIdx.end())) - } // while(plit != pPolylineCoordIdx.end()) -} - -#define MESH_RectParallelepiped_CREATE_VERT \ - aiVector3D vert_set[8]; \ - float x1, x2, y1, y2, z1, z2, hs; \ - \ - hs = pSize.x / 2, x1 = -hs, x2 = hs; \ - hs = pSize.y / 2, y1 = -hs, y2 = hs; \ - hs = pSize.z / 2, z1 = -hs, z2 = hs; \ - vert_set[0].Set(x2, y1, z2); \ - vert_set[1].Set(x2, y2, z2); \ - vert_set[2].Set(x2, y2, z1); \ - vert_set[3].Set(x2, y1, z1); \ - vert_set[4].Set(x1, y1, z2); \ - vert_set[5].Set(x1, y2, z2); \ - vert_set[6].Set(x1, y2, z1); \ - vert_set[7].Set(x1, y1, z1) - -void X3DImporter::GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D &pSize, std::list &pVertices) { - MESH_RectParallelepiped_CREATE_VERT; - MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 3, 2, 1, 0); // front - MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 6, 7, 4, 5); // back - MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 7, 3, 0, 4); // left - MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 2, 6, 5, 1); // right - MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 0, 1, 5, 4); // top - MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 7, 6, 2, 3); // bottom -} - -#undef MESH_RectParallelepiped_CREATE_VERT - -void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::vector &pCoordIdx, std::vector &pFaces, unsigned int &pPrimitiveTypes) const { - std::vector f_data(pCoordIdx); - std::vector inds; - unsigned int prim_type = 0; - - if (f_data.back() != (-1)) { - f_data.push_back(-1); - } - - // reserve average size. - pFaces.reserve(f_data.size() / 3); - inds.reserve(4); - //PrintVectorSet("build. ci", pCoordIdx); - 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)) { - aiFace tface; - size_t ts; - - ts = inds.size(); - switch (ts) { - case 0: goto mg_m_err; - case 1: prim_type |= aiPrimitiveType_POINT; break; - case 2: prim_type |= aiPrimitiveType_LINE; break; - case 3: prim_type |= aiPrimitiveType_TRIANGLE; break; - default: prim_type |= aiPrimitiveType_POLYGON; break; - } - - tface.mNumIndices = static_cast(ts); - tface.mIndices = new unsigned int[ts]; - memcpy(tface.mIndices, inds.data(), ts * sizeof(unsigned int)); - pFaces.push_back(tface); - inds.clear(); - } // if(*it == (-1)) - else { - inds.push_back(*it); - } // if(*it == (-1)) else - } // for(std::list::iterator it = f_data.begin(); it != f_data.end(); it++) - //PrintVectorSet("build. faces", pCoordIdx); - - pPrimitiveTypes = prim_type; - - return; - -mg_m_err: - - for (size_t i = 0, i_e = pFaces.size(); i < i_e; i++) - delete[] pFaces.at(i).mIndices; - - pFaces.clear(); -} - -void X3DImporter::MeshGeometry_AddColor(aiMesh &pMesh, const std::list &pColors, const bool pColorPerVertex) const { - std::list tcol; - - // create RGBA array from RGB. - for (std::list::const_iterator it = pColors.begin(); it != pColors.end(); ++it) - tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1)); - - // call existing function for adding RGBA colors - MeshGeometry_AddColor(pMesh, tcol, pColorPerVertex); -} - -void X3DImporter::MeshGeometry_AddColor(aiMesh &pMesh, const std::list &pColors, const bool pColorPerVertex) const { - std::list::const_iterator col_it = pColors.begin(); - - if (pColorPerVertex) { - if (pColors.size() < pMesh.mNumVertices) { - throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + to_string(pColors.size()) + ") can not be less than Vertices count(" + - to_string(pMesh.mNumVertices) + ")."); - } - - // copy colors to mesh - pMesh.mColors[0] = new aiColor4D[pMesh.mNumVertices]; - for (size_t i = 0; i < pMesh.mNumVertices; i++) - pMesh.mColors[0][i] = *col_it++; - } // if(pColorPerVertex) - else { - if (pColors.size() < pMesh.mNumFaces) { - throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + to_string(pColors.size()) + ") can not be less than Faces count(" + - to_string(pMesh.mNumFaces) + ")."); - } - - // copy colors to mesh - pMesh.mColors[0] = new aiColor4D[pMesh.mNumVertices]; - for (size_t fi = 0; fi < pMesh.mNumFaces; fi++) { - // apply color to all vertices of face - for (size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) { - pMesh.mColors[0][pMesh.mFaces[fi].mIndices[vi]] = *col_it; - } - - ++col_it; - } - } // if(pColorPerVertex) else -} - -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; - - // create RGBA array from RGB. - for (std::list::const_iterator it = pColors.begin(); it != pColors.end(); ++it) { - tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1)); - } - - // call existing function for adding RGBA colors - MeshGeometry_AddColor(pMesh, pCoordIdx, pColorIdx, tcol, pColorPerVertex); -} - -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; - std::list col_tgt_list; - std::vector col_arr_copy; - - if (pCoordIdx.size() == 0) { - throw DeadlyImportError("MeshGeometry_AddColor2. pCoordIdx can not be empty."); - } - - // copy list to array because we are need indexed access to colors. - col_arr_copy.reserve(pColors.size()); - for (std::list::const_iterator it = pColors.begin(); it != pColors.end(); ++it) { - col_arr_copy.push_back(*it); - } - - if (pColorPerVertex) { - if (pColorIdx.size() > 0) { - // check indices array count. - if (pColorIdx.size() < pCoordIdx.size()) { - throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + to_string(pColorIdx.size()) + - ") can not be less than Coords inidces count(" + to_string(pCoordIdx.size()) + ")."); - } - // create list with colors for every vertex. - col_tgt_arr.resize(pMesh.mNumVertices); - 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)) { - continue; // skip faces delimiter - } - if ((unsigned int)(*coordidx_it) > pMesh.mNumVertices) { - throw DeadlyImportError("MeshGeometry_AddColor2. Coordinate idx is out of range."); - } - if ((unsigned int)*colidx_it > pMesh.mNumVertices) { - throw DeadlyImportError("MeshGeometry_AddColor2. Color idx is out of range."); - } - - col_tgt_arr[*coordidx_it] = col_arr_copy[*colidx_it]; - } - } // if(pColorIdx.size() > 0) - else { - // when color indices list is absent use CoordIdx. - // check indices array count. - if (pColors.size() < pMesh.mNumVertices) { - throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + to_string(pColors.size()) + ") can not be less than Vertices count(" + - to_string(pMesh.mNumVertices) + ")."); - } - // create list with colors for every vertex. - col_tgt_arr.resize(pMesh.mNumVertices); - for (size_t i = 0; i < pMesh.mNumVertices; i++) { - col_tgt_arr[i] = col_arr_copy[i]; - } - } // if(pColorIdx.size() > 0) else - } // if(pColorPerVertex) - else { - if (pColorIdx.size() > 0) { - // check indices array count. - if (pColorIdx.size() < pMesh.mNumFaces) { - throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + to_string(pColorIdx.size()) + - ") can not be less than Faces count(" + to_string(pMesh.mNumFaces) + ")."); - } - // create list with colors for every vertex using faces indices. - col_tgt_arr.resize(pMesh.mNumFaces); - - 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."); - - col_tgt_arr[fi] = col_arr_copy[*colidx_it++]; - } - } // if(pColorIdx.size() > 0) - else { - // when color indices list is absent use CoordIdx. - // check indices array count. - if (pColors.size() < pMesh.mNumFaces) { - throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + to_string(pColors.size()) + ") can not be less than Faces count(" + - to_string(pMesh.mNumFaces) + ")."); - } - // create list with colors for every vertex using faces indices. - col_tgt_arr.resize(pMesh.mNumFaces); - for (size_t fi = 0; fi < pMesh.mNumFaces; fi++) - col_tgt_arr[fi] = col_arr_copy[fi]; - - } // if(pColorIdx.size() > 0) else - } // if(pColorPerVertex) else - - // copy array to list for calling function that add colors. - for (std::vector::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); ++it) - col_tgt_list.push_back(*it); - // add prepared colors list to mesh. - MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex); -} - -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; - std::vector norm_arr_copy; - - // copy list to array because we are need indexed access to normals. - norm_arr_copy.reserve(pNormals.size()); - for (std::list::const_iterator it = pNormals.begin(); it != pNormals.end(); ++it) { - norm_arr_copy.push_back(*it); - } - - if (pNormalPerVertex) { - if (pNormalIdx.size() > 0) { - // check indices array count. - if (pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal."); - - tind.reserve(pNormalIdx.size()); - for (std::vector::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); ++it) { - if (*it != (-1)) tind.push_back(*it); - } - - // copy normals to mesh - pMesh.mNormals = new aiVector3D[pMesh.mNumVertices]; - for (size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++) { - if (tind[i] >= norm_arr_copy.size()) - throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + to_string(tind[i]) + - ") is out of range. Normals count: " + to_string(norm_arr_copy.size()) + "."); - - pMesh.mNormals[i] = norm_arr_copy[tind[i]]; - } - } else { - if (pNormals.size() != pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddNormal. Normals and vertices count must be equal."); - - // copy normals to mesh - pMesh.mNormals = new aiVector3D[pMesh.mNumVertices]; - std::list::const_iterator norm_it = pNormals.begin(); - for (size_t i = 0; i < pMesh.mNumVertices; i++) - pMesh.mNormals[i] = *norm_it++; - } - } // if(pNormalPerVertex) - else { - if (pNormalIdx.size() > 0) { - if (pMesh.mNumFaces != pNormalIdx.size()) throw DeadlyImportError("Normals faces count must be equal to mesh faces count."); - - 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++); - - } else { - tind.reserve(pMesh.mNumFaces); - for (size_t i = 0; i < pMesh.mNumFaces; i++) - tind.push_back(i); - } - - // copy normals to mesh - pMesh.mNormals = new aiVector3D[pMesh.mNumVertices]; - for (size_t fi = 0; fi < pMesh.mNumFaces; fi++) { - aiVector3D tnorm; - - tnorm = norm_arr_copy[tind[fi]]; - for (size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) - pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = tnorm; - } - } // if(pNormalPerVertex) else -} - -void X3DImporter::MeshGeometry_AddNormal(aiMesh &pMesh, const std::list &pNormals, const bool pNormalPerVertex) const { - std::list::const_iterator norm_it = pNormals.begin(); - - if (pNormalPerVertex) { - if (pNormals.size() != pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddNormal. Normals and vertices count must be equal."); - - // copy normals to mesh - pMesh.mNormals = new aiVector3D[pMesh.mNumVertices]; - for (size_t i = 0; i < pMesh.mNumVertices; i++) - pMesh.mNormals[i] = *norm_it++; - } // if(pNormalPerVertex) - else { - if (pNormals.size() != pMesh.mNumFaces) throw DeadlyImportError("MeshGeometry_AddNormal. Normals and faces count must be equal."); - - // copy normals to mesh - pMesh.mNormals = new aiVector3D[pMesh.mNumVertices]; - for (size_t fi = 0; fi < pMesh.mNumFaces; fi++) { - // apply color to all vertices of face - for (size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) - pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = *norm_it; - - ++norm_it; - } - } // if(pNormalPerVertex) else -} - -void X3DImporter::MeshGeometry_AddTexCoord(aiMesh &pMesh, const std::vector &pCoordIdx, const std::vector &pTexCoordIdx, - const std::list &pTexCoords) const { - std::vector texcoord_arr_copy; - std::vector faces; - unsigned int prim_type; - - // copy list to array because we are need indexed access to normals. - texcoord_arr_copy.reserve(pTexCoords.size()); - for (std::list::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it) { - texcoord_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0)); - } - - if (pTexCoordIdx.size() > 0) { - GeometryHelper_CoordIdxStr2FacesArr(pTexCoordIdx, faces, prim_type); - if (faces.empty()) { - throw DeadlyImportError("Failed to add texture coordinates to mesh, faces list is empty."); - } - if (faces.size() != pMesh.mNumFaces) { - throw DeadlyImportError("Texture coordinates faces count must be equal to mesh faces count."); - } - } else { - GeometryHelper_CoordIdxStr2FacesArr(pCoordIdx, faces, prim_type); - } - - pMesh.mTextureCoords[0] = new aiVector3D[pMesh.mNumVertices]; - pMesh.mNumUVComponents[0] = 2; - for (size_t fi = 0, fi_e = faces.size(); fi < fi_e; fi++) { - if (pMesh.mFaces[fi].mNumIndices != faces.at(fi).mNumIndices) - throw DeadlyImportError("Number of indices in texture face and mesh face must be equal. Invalid face index: " + to_string(fi) + "."); - - for (size_t ii = 0; ii < pMesh.mFaces[fi].mNumIndices; ii++) { - size_t vert_idx = pMesh.mFaces[fi].mIndices[ii]; - size_t tc_idx = faces.at(fi).mIndices[ii]; - - pMesh.mTextureCoords[0][vert_idx] = texcoord_arr_copy.at(tc_idx); - } - } // for(size_t fi = 0, fi_e = faces.size(); fi < fi_e; fi++) -} - -void X3DImporter::MeshGeometry_AddTexCoord(aiMesh &pMesh, const std::list &pTexCoords) const { - std::vector tc_arr_copy; - - if (pTexCoords.size() != pMesh.mNumVertices) { - throw DeadlyImportError("MeshGeometry_AddTexCoord. Texture coordinates and vertices count must be equal."); - } - - // copy list to array because we are need convert aiVector2D to aiVector3D and also get indexed access as a bonus. - tc_arr_copy.reserve(pTexCoords.size()); - for (std::list::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it) { - tc_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0)); - } - - // copy texture coordinates to mesh - pMesh.mTextureCoords[0] = new aiVector3D[pMesh.mNumVertices]; - pMesh.mNumUVComponents[0] = 2; - for (size_t i = 0; i < pMesh.mNumVertices; i++) { - pMesh.mTextureCoords[0][i] = tc_arr_copy[i]; - } -} - -aiMesh *X3DImporter::GeometryHelper_MakeMesh(const std::vector &pCoordIdx, const std::list &pVertices) const { - std::vector faces; - unsigned int prim_type = 0; - - // create faces array from input string with vertices indices. - GeometryHelper_CoordIdxStr2FacesArr(pCoordIdx, faces, prim_type); - if (!faces.size()) { - throw DeadlyImportError("Failed to create mesh, faces list is empty."); - } - - // - // Create new mesh and copy geometry data. - // - aiMesh *tmesh = new aiMesh; - size_t ts = faces.size(); - // faces - tmesh->mFaces = new aiFace[ts]; - tmesh->mNumFaces = static_cast(ts); - for (size_t i = 0; i < ts; i++) - tmesh->mFaces[i] = faces.at(i); - - // vertices - std::list::const_iterator vit = pVertices.begin(); - - ts = pVertices.size(); - tmesh->mVertices = new aiVector3D[ts]; - tmesh->mNumVertices = static_cast(ts); - for (size_t i = 0; i < ts; i++) { - tmesh->mVertices[i] = *vit++; - } - - // set primitives type and return result. - tmesh->mPrimitiveTypes = prim_type; - - return tmesh; -} - -/*********************************************************************************************************************************************/ -/************************************************************ Functions: parse set ***********************************************************/ -/*********************************************************************************************************************************************/ - -void X3DImporter::ParseHelper_Group_Begin(const bool pStatic) { - X3DGroup *new_group = new X3DGroup(mNodeElementCur, pStatic); // create new node with current node as parent. - - // if we are adding not the root element then add new element to current element child list. - if (mNodeElementCur != nullptr) { - mNodeElementCur->Child.push_back(new_group); - } - - NodeElement_List.push_back(new_group); // it's a new element - add it to list. - mNodeElementCur = new_group; // switch current element to new one. -} - -void X3DImporter::ParseHelper_Node_Enter(X3DNodeElementBase *pNode) { - mNodeElementCur->Child.push_back(pNode); // add new element to current element child list. - mNodeElementCur = pNode; // switch current element to new one. -} - -void X3DImporter::ParseHelper_Node_Exit() { - // check if we can walk up. - if (mNodeElementCur != nullptr) { - mNodeElementCur = mNodeElementCur->Parent; - } -} - -void X3DImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString) { - pOutString.clear(); - const size_t instr_len = strlen(pInStr); - if (0 == instr_len) { - return; - } - - pOutString.reserve(instr_len * 3 / 2); - // check and correct floats in format ".x". Must be "x.y". - if (pInStr[0] == '.') { - pOutString.push_back('0'); - } - - pOutString.push_back(pInStr[0]); - for (size_t ci = 1; ci < instr_len; ci++) { - if ((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t'))) { - pOutString.push_back('0'); - pOutString.push_back('.'); - } else { - pOutString.push_back(pInStr[ci]); - } - } -} - -extern FIVocabulary X3D_vocabulary_3_2; -extern FIVocabulary X3D_vocabulary_3_3; - -void X3DImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { - //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 - if (file.get() == nullptr) { - throw DeadlyImportError("Failed to open X3D file " + pFile + "."); - } - 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(); - - // restore old XMLreader - mReader = std::move(OldReader); -} - -void X3DImporter::ParseNode_Root() { - // search for root tag - if (!XML_SearchNode("X3D")) { - throw DeadlyImportError("Root node \"X3D\" not found."); - } - - ParseHelper_Group_Begin(); // create root node element. - // parse other contents - while (mReader->read()) { - if (mReader->getNodeType() != irr::io::EXN_ELEMENT) { - continue; - } - - if (XML_CheckNode_NameEqual("head")) - ParseNode_Head(); - else if (XML_CheckNode_NameEqual("Scene")) - ParseNode_Scene(); - else - XML_CheckNode_SkipUnsupported("Root"); - } - - // exit from root node element. - ParseHelper_Node_Exit(); -} - -void X3DImporter::ParseNode_Head() { - bool close_found = false; // flag: true if close tag of node are found. - - while (mReader->read()) { - if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (XML_CheckNode_NameEqual("meta")) { - XML_CheckNode_MustBeEmpty(); - - // adding metadata from as MetaString from - bool added(false); - X3DMetaString *ms = new X3DMetaString(mNodeElementCur); - - ms->Name = mReader->getAttributeValueSafe("name"); - // name must not be empty - if (!ms->Name.empty()) { - ms->Value.push_back(mReader->getAttributeValueSafe("content")); - NodeElement_List.push_back(ms); - if (mNodeElementCur != nullptr) { - mNodeElementCur->Child.push_back(ms); - added = true; - } - } - // if an error has occurred, release instance - if (!added) { - delete ms; - } - } // if(XML_CheckNode_NameEqual("meta")) - } // if(mReader->getNodeType() == irr::io::EXN_ELEMENT) - else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if (XML_CheckNode_NameEqual("head")) { - close_found = true; - break; - } - } // if(mReader->getNodeType() == irr::io::EXN_ELEMENT) else - } // while(mReader->read()) - - if (!close_found) { - Throw_CloseNotFound("head"); - } -} - -void X3DImporter::ParseNode_Scene() { - auto GroupCounter_Increase = [](size_t &pCounter, const char *pGroupName) -> void { - pCounter++; - if (pCounter == 0) throw DeadlyImportError("Group counter overflow. Too much groups with type: " + std::string(pGroupName) + "."); - }; - - auto GroupCounter_Decrease = [&](size_t &pCounter, const char *pGroupName) -> void { - if (pCounter == 0) Throw_TagCountIncorrect(pGroupName); - - pCounter--; - }; - - static const char *GroupName_Group = "Group"; - static const char *GroupName_StaticGroup = "StaticGroup"; - static const char *GroupName_Transform = "Transform"; - static const char *GroupName_Switch = "Switch"; - - bool close_found = false; - size_t counter_group = 0; - size_t counter_transform = 0; - size_t counter_switch = 0; - - // while create static node? Because objects name used deeper in "USE" attribute can be equal to some meta in node. - ParseHelper_Group_Begin(true); - while (mReader->read()) { - if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (XML_CheckNode_NameEqual("Shape")) { - ParseNode_Shape_Shape(); - } else if (XML_CheckNode_NameEqual(GroupName_Group)) { - GroupCounter_Increase(counter_group, GroupName_Group); - ParseNode_Grouping_Group(); - // if node is empty then decrease group counter at this place. - if (mReader->isEmptyElement()) GroupCounter_Decrease(counter_group, GroupName_Group); - } else if (XML_CheckNode_NameEqual(GroupName_StaticGroup)) { - GroupCounter_Increase(counter_group, GroupName_StaticGroup); - ParseNode_Grouping_StaticGroup(); - // if node is empty then decrease group counter at this place. - if (mReader->isEmptyElement()) GroupCounter_Decrease(counter_group, GroupName_StaticGroup); - } else if (XML_CheckNode_NameEqual(GroupName_Transform)) { - GroupCounter_Increase(counter_transform, GroupName_Transform); - ParseNode_Grouping_Transform(); - // if node is empty then decrease group counter at this place. - if (mReader->isEmptyElement()) GroupCounter_Decrease(counter_transform, GroupName_Transform); - } else if (XML_CheckNode_NameEqual(GroupName_Switch)) { - GroupCounter_Increase(counter_switch, GroupName_Switch); - ParseNode_Grouping_Switch(); - // if node is empty then decrease group counter at this place. - if (mReader->isEmptyElement()) GroupCounter_Decrease(counter_switch, GroupName_Switch); - } else if (XML_CheckNode_NameEqual("DirectionalLight")) { - ParseNode_Lighting_DirectionalLight(); - } else if (XML_CheckNode_NameEqual("PointLight")) { - ParseNode_Lighting_PointLight(); - } else if (XML_CheckNode_NameEqual("SpotLight")) { - ParseNode_Lighting_SpotLight(); - } else if (XML_CheckNode_NameEqual("Inline")) { - ParseNode_Networking_Inline(); - } else if (!ParseHelper_CheckRead_X3DMetadataObject()) { - XML_CheckNode_SkipUnsupported("Scene"); - } - } // if(mReader->getNodeType() == irr::io::EXN_ELEMENT) - else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if (XML_CheckNode_NameEqual("Scene")) { - close_found = true; - - break; - } else if (XML_CheckNode_NameEqual(GroupName_Group)) { - GroupCounter_Decrease(counter_group, GroupName_Group); - ParseNode_Grouping_GroupEnd(); - } else if (XML_CheckNode_NameEqual(GroupName_StaticGroup)) { - GroupCounter_Decrease(counter_group, GroupName_StaticGroup); - ParseNode_Grouping_StaticGroupEnd(); - } else if (XML_CheckNode_NameEqual(GroupName_Transform)) { - GroupCounter_Decrease(counter_transform, GroupName_Transform); - ParseNode_Grouping_TransformEnd(); - } else if (XML_CheckNode_NameEqual(GroupName_Switch)) { - GroupCounter_Decrease(counter_switch, GroupName_Switch); - ParseNode_Grouping_SwitchEnd(); - } - } // if(mReader->getNodeType() == irr::io::EXN_ELEMENT) else - } // while(mReader->read()) - - ParseHelper_Node_Exit(); - - if (counter_group) Throw_TagCountIncorrect("Group"); - if (counter_transform) Throw_TagCountIncorrect("Transform"); - if (counter_switch) Throw_TagCountIncorrect("Switch"); - if (!close_found) Throw_CloseNotFound("Scene"); -} - -/*********************************************************************************************************************************************/ -/******************************************************** Functions: BaseImporter set ********************************************************/ -/*********************************************************************************************************************************************/ - bool X3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const { const std::string extension = GetExtension(pFile); @@ -1460,7 +202,7 @@ void X3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy std::list light_list; // create nodes tree - Postprocess_BuildNode(*mNodeElementCur, *pScene->mRootNode, mesh_list, mat_list, light_list); +// Postprocess_BuildNode(*mNodeElementCur, *pScene->mRootNode, mesh_list, mat_list, light_list); // copy needed data to scene if (!mesh_list.empty()) { std::list::const_iterator it = mesh_list.begin(); @@ -1488,9 +230,7 @@ void X3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy for (size_t i = 0; i < pScene->mNumLights; i++) pScene->mLights[i] = *it++; } - } // END: fill aiScene with objects. - - ///TODO: IME optimize tree + } } } // namespace Assimp diff --git a/code/AssetLib/X3D/X3DImporter.hpp b/code/AssetLib/X3D/X3DImporter.hpp index 1e8127ab8..7e29458a1 100644 --- a/code/AssetLib/X3D/X3DImporter.hpp +++ b/code/AssetLib/X3D/X3DImporter.hpp @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -48,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef INCLUDED_AI_X3D_IMPORTER_H #define INCLUDED_AI_X3D_IMPORTER_H -#include "X3DImporter_Node.hpp" // Header files, Assimp. #include @@ -57,8 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include "FIReader.hpp" -//#include +#include + +#include namespace Assimp { @@ -234,6 +233,62 @@ inline void LogInfo(const std::string &message) { /// /// That's all for now. Enjoy /// +enum class X3DElemType { + ENET_Group, ///< Element has type "Group". + ENET_MetaBoolean, ///< Element has type "Metadata boolean". + ENET_MetaDouble, ///< Element has type "Metadata double". + ENET_MetaFloat, ///< Element has type "Metadata float". + ENET_MetaInteger, ///< Element has type "Metadata integer". + ENET_MetaSet, ///< Element has type "Metadata set". + ENET_MetaString, ///< Element has type "Metadata string". + ENET_Arc2D, ///< Element has type "Arc2D". + ENET_ArcClose2D, ///< Element has type "ArcClose2D". + ENET_Circle2D, ///< Element has type "Circle2D". + ENET_Disk2D, ///< Element has type "Disk2D". + ENET_Polyline2D, ///< Element has type "Polyline2D". + ENET_Polypoint2D, ///< Element has type "Polypoint2D". + ENET_Rectangle2D, ///< Element has type "Rectangle2D". + ENET_TriangleSet2D, ///< Element has type "TriangleSet2D". + ENET_Box, ///< Element has type "Box". + ENET_Cone, ///< Element has type "Cone". + ENET_Cylinder, ///< Element has type "Cylinder". + ENET_Sphere, ///< Element has type "Sphere". + ENET_ElevationGrid, ///< Element has type "ElevationGrid". + ENET_Extrusion, ///< Element has type "Extrusion". + ENET_Coordinate, ///< Element has type "Coordinate". + ENET_Normal, ///< Element has type "Normal". + ENET_TextureCoordinate, ///< Element has type "TextureCoordinate". + ENET_IndexedFaceSet, ///< Element has type "IndexedFaceSet". + ENET_IndexedLineSet, ///< Element has type "IndexedLineSet". + ENET_IndexedTriangleSet, ///< Element has type "IndexedTriangleSet". + ENET_IndexedTriangleFanSet, ///< Element has type "IndexedTriangleFanSet". + ENET_IndexedTriangleStripSet, ///< Element has type "IndexedTriangleStripSet". + ENET_LineSet, ///< Element has type "LineSet". + ENET_PointSet, ///< Element has type "PointSet". + ENET_TriangleSet, ///< Element has type "TriangleSet". + ENET_TriangleFanSet, ///< Element has type "TriangleFanSet". + ENET_TriangleStripSet, ///< Element has type "TriangleStripSet". + ENET_Color, ///< Element has type "Color". + ENET_ColorRGBA, ///< Element has type "ColorRGBA". + ENET_Shape, ///< Element has type "Shape". + ENET_Appearance, ///< Element has type "Appearance". + ENET_Material, ///< Element has type "Material". + ENET_ImageTexture, ///< Element has type "ImageTexture". + ENET_TextureTransform, ///< Element has type "TextureTransform". + ENET_DirectionalLight, ///< Element has type "DirectionalLight". + ENET_PointLight, ///< Element has type "PointLight". + ENET_SpotLight, ///< Element has type "SpotLight". + + ENET_Invalid ///< Element has invalid type and possible contain invalid data. +}; + +struct X3DNodeElementBase { + X3DNodeElementBase *Parent; + std::string ID; + std::list Child; + X3DElemType Type; +}; + class X3DImporter : public BaseImporter { public: @@ -259,527 +314,13 @@ public: /// \param [in] pFile - name of file to be parsed. /// \param [in] pIOHandler - pointer to IO helper object. void ParseFile( const std::string& pFile, IOSystem* pIOHandler ); - - /***********************************************/ - /********* Functions: BaseImporter set *********/ - /***********************************************/ - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig ) const; void GetExtensionList( std::set& pExtensionList ); void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ); const aiImporterDesc* GetInfo()const; + void Clear(); - -private: - /// Disabled copy constructor. - X3DImporter(const X3DImporter& pScene); - - /// Disabled assign operator. - X3DImporter& operator=(const X3DImporter& pScene); - - /// Clear all temporary data. - void Clear(); - - /***********************************************/ - /************* Functions: find set *************/ - /***********************************************/ - - /// Find requested node element. Search will be made in all existing nodes. - /// \param [in] pID - ID of requested element. - /// \param [in] pType - type of requested element. - /// \param [out] pElement - pointer to pointer to item found. - /// \return true - if the element is found, else - false. - bool FindNodeElement_FromRoot(const std::string& pID, const X3DNodeElementBase::EType pType, X3DNodeElementBase** pElement); - - /// Find requested node element. Search will be made from pointed node down to childs. - /// \param [in] pStartNode - pointer to start node. - /// \param [in] pID - ID of requested element. - /// \param [in] pType - type of requested element. - /// \param [out] pElement - pointer to pointer to item found. - /// \return true - if the element is found, else - false. - bool FindNodeElement_FromNode(X3DNodeElementBase* pStartNode, const std::string& pID, const X3DNodeElementBase::EType pType, - X3DNodeElementBase** pElement); - - /// Find requested node element. For "Node"'s accounting flag "Static". - /// \param [in] pName - name of requested element. - /// \param [in] pType - type of requested element. - /// \param [out] pElement - pointer to pointer to item found. - /// \return true - if the element is found, else - false. - bool FindNodeElement(const std::string& pName, const X3DNodeElementBase::EType pType, X3DNodeElementBase** pElement); - - /***********************************************/ - /********* Functions: postprocess set **********/ - /***********************************************/ - - /// \return transformation matrix from global coordinate system to local. - aiMatrix4x4 PostprocessHelper_Matrix_GlobalToCurrent() const; - - /// Check if child elements of node element is metadata and add it to temporary list. - /// \param [in] pNodeElement - node element where metadata is searching. - /// \param [out] pList - temporary list for collected metadata. - void PostprocessHelper_CollectMetadata(const X3DNodeElementBase& pNodeElement, std::list& pList) const; - - /// Check if type of node element is metadata. E.g. , . - /// \param [in] pType - checked type. - /// \return true - if the type corresponds to the metadata. - bool PostprocessHelper_ElementIsMetadata(const X3DNodeElementBase::EType pType) const; - - /// Check if type of node element is geometry object and can be used to build mesh. E.g. , . - /// \param [in] pType - checked type. - /// \return true - if the type corresponds to the mesh. - bool PostprocessHelper_ElementIsMesh(const X3DNodeElementBase::EType pType) const; - - /// Read CX3DImporter_NodeElement_Light, create aiLight and add it to list of the lights. - /// \param [in] pNodeElement - reference to lisght element(, , ). - /// \param [out] pSceneLightList - reference to list of the lights. - void Postprocess_BuildLight(const X3DNodeElementBase& pNodeElement, std::list& pSceneLightList) const; - - /// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract - /// all needed data from scene graph. - /// \param [in] pNodeElement - reference to material element(). - /// \param [out] pMaterial - pointer to pointer to created material. *pMaterial must be nullptr. - void Postprocess_BuildMaterial(const X3DNodeElementBase& pNodeElement, aiMaterial** pMaterial) const; - - /// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract - /// all needed data from scene graph. - /// \param [in] pNodeElement - reference to geometry object. - /// \param [out] pMesh - pointer to pointer to created mesh. *pMesh must be nullptr. - void Postprocess_BuildMesh(const X3DNodeElementBase& pNodeElement, aiMesh** pMesh) const; - - /// Create aiNode from CX3DImporter_NodeElement. Also function check children and make recursive call. - /// \param [out] pNode - pointer to pointer to created node. *pNode must be nullptr. - /// \param [in] pNodeElement - CX3DImporter_NodeElement which read. - /// \param [out] pSceneNode - aiNode for filling. - /// \param [out] pSceneMeshList - list with aiMesh which belong to scene. - /// \param [out] pSceneMaterialList - list with aiMaterial which belong to scene. - /// \param [out] pSceneLightList - list with aiLight which belong to scene. - void Postprocess_BuildNode(const X3DNodeElementBase& pNodeElement, aiNode& pSceneNode, std::list& pSceneMeshList, - std::list& pSceneMaterialList, std::list& pSceneLightList) const; - - /// To create mesh and material kept in . - /// \param pShapeNodeElement - reference to node element which kept data. - /// \param pNodeMeshInd - reference to list with mesh indices. When pShapeNodeElement will read new mesh index will be added to this list. - /// \param pSceneMeshList - reference to list with meshes. When pShapeNodeElement will read new mesh will be added to this list. - /// \param pSceneMaterialList - reference to list with materials. When pShapeNodeElement will read new material will be added to this list. - void Postprocess_BuildShape(const X3DShape& pShapeNodeElement, std::list& pNodeMeshInd, - std::list& pSceneMeshList, std::list& pSceneMaterialList) const; - - /// Check if child elements of node element is metadata and add it to scene node. - /// \param [in] pNodeElement - node element where metadata is searching. - /// \param [out] pSceneNode - scene node in which metadata will be added. - void Postprocess_CollectMetadata(const X3DNodeElementBase& pNodeElement, aiNode& pSceneNode) const; - - /***********************************************/ - /************** Functions: XML set *************/ - /***********************************************/ - - /// Check if current node is empty: . If not then exception will throwed. - void XML_CheckNode_MustBeEmpty(); - - /// Check if current node name is equal to pNodeName. - /// \param [in] pNodeName - name for checking. - /// return true if current node name is equal to pNodeName, else - false. - //bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; } - - /// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node. - /// \param [in] pParentNodeName - parent node name. Used for reporting. - void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName); - - /// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end. - /// \param [in] pNodeName - requested node name. - /// return true - if node is found, else - false. - bool XML_SearchNode(const std::string& pNodeName); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \return read data. - bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \return read data. - float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \return read data. - int32_t XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \param [out] pValue - read data. - void XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \param [out] pValue - read data. - void XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \param [out] pValue - read data. - void XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue); - - /// Read attribute value. - /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). - /// \param [out] pValue - read data. - 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_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_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_AsArrD(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_AsListCol3f(const int pAttrIdx, std::list& pValue); - - /// \overload void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::vector& pValue) - void XML_ReadNode_GetAttrVal_AsArrCol3f(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_AsListCol4f(const int pAttrIdx, std::list& pValue); - - /// \overload void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list& pValue) - void XML_ReadNode_GetAttrVal_AsArrCol4f(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_AsListVec2f(const int pAttrIdx, std::list& pValue); - - /// \overload void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list& pValue) - void XML_ReadNode_GetAttrVal_AsArrVec2f(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_AsListVec3f(const int pAttrIdx, std::list& pValue); - - /// \overload void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list& pValue) - void XML_ReadNode_GetAttrVal_AsArrVec3f(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_AsListS(const int pAttrIdx, std::list& pValue); - - /***********************************************/ - /******* Functions: geometry helper set *******/ - /***********************************************/ - - /// Make point on surface oXY. - /// \param [in] pAngle - angle in radians between radius-vector of point and oX axis. Angle extends from the oX axis counterclockwise to the radius-vector. - /// \param [in] pRadius - length of radius-vector. - /// \return made point coordinates. - aiVector3D GeometryHelper_Make_Point2D(const float pAngle, const float pRadius); - - /// Make 2D figure - linear circular arc with center in (0, 0). The z-coordinate is 0. The arc extends from the pStartAngle counterclockwise - /// to the pEndAngle. If pStartAngle and pEndAngle have the same value, a circle is specified. If the absolute difference between pStartAngle - /// and pEndAngle is greater than or equal to 2pi, a circle is specified. - /// \param [in] pStartAngle - angle in radians of start of the arc. - /// \param [in] pEndAngle - angle in radians of end of the arc. - /// \param [in] pRadius - radius of the arc. - /// \param [out] pNumSegments - number of segments in arc. In other words - tessellation factor. - /// \param [out] pVertices - generated vertices. - void GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, std::list& pVertices); - - /// Create line set from point set. - /// \param [in] pPoint - input points list. - /// \param [out] pLine - made lines list. - void GeometryHelper_Extend_PointToLine(const std::list& pPoint, std::list& pLine); - - /// Create CoordIdx of line set from CoordIdx of polyline set. - /// \param [in] pPolylineCoordIdx - vertices indices divided by delimiter "-1". Must contain faces with two or more indices. - /// \param [out] pLineCoordIdx - made CoordIdx of line set. - void GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list& pPolylineCoordIdx, std::list& pLineCoordIdx); - - /// Make 3D body - rectangular parallelepiped with center in (0, 0). QL mean quadlist (\sa pVertices). - /// \param [in] pSize - scale factor for body for every axis. E.g. (1, 2, 1) mean: X-size and Z-size - 1, Y-size - 2. - /// \param [out] pVertices - generated vertices. The list of vertices is grouped in quads. - void GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSize, std::list& pVertices); - - /// Create faces array from vertices indices array. - /// \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::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: - /// If the colorIndex field is not empty, one colour is used for each face of the mesh. There shall be at least as many indices in the - /// colorIndex field as there are faces in the mesh. The colorIndex field shall not contain any negative entries. - /// If the colorIndex field is empty, the colours in the X3DColorNode node are applied to each face of the mesh in order. - /// There shall be at least as many colours in the X3DColorNode node as there are faces. - /// b. If colorPerVertex is TRUE, colours are applied to each vertex, as follows: - /// If the colorIndex field is not empty, colours are applied to each vertex of the mesh in exactly the same manner that the coordIndex - /// field is used to choose coordinates for each vertex from the node. The colorIndex field shall contain end-of-face markers (-1) - /// in exactly the same places as the coordIndex field. - /// If the colorIndex field is empty, the coordIndex field is used to choose colours from the X3DColorNode node. - /// \param [in] pMesh - mesh for adding data. - /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1". - /// \param [in] pColorIdx - color indices for every vertex divided by delimiter "-1" if \ref pColorPerVertex is true. if \ref pColorPerVertex is false - /// 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::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::vector& pCoordIdx, const std::vector& pColorIdx, - const std::list& pColors, const bool pColorPerVertex) const; - - /// Add colors to mesh. - /// \param [in] pMesh - mesh for adding data. - /// \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& pColors, const bool pColorPerVertex) const; - - /// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const - 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::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::vector& pCoordIdx, const std::vector& pTexCoordIdx, - const std::list& pTexCoords) const; - - /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor; - void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pTexCoords) const; - - /// Create mesh. - /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1". - /// \param [in] pVertices - vertices of mesh. - /// \return created mesh. - aiMesh* GeometryHelper_MakeMesh(const std::vector& pCoordIdx, const std::list& pVertices) const; - - /***********************************************/ - /******** Functions: parse set private *********/ - /***********************************************/ - - /// Create node element with type "Node" in scene graph. That operation is needed when you enter to X3D group node - /// like , etc. When exiting from X3D group node(e.g. ) \ref ParseHelper_Node_Exit must - /// be called. - /// \param [in] pStatic - flag: if true then static node is created(e.g. ). - void ParseHelper_Group_Begin(const bool pStatic = false); - - /// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called. - /// \param [in] pNode - new current node. - void ParseHelper_Node_Enter(X3DNodeElementBase* pNode); - - /// This function must be called when exiting from X3D group node(e.g. ). \ref ParseHelper_Group_Begin. - void ParseHelper_Node_Exit(); - - /// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it - /// must be converted to right form - "0.xxx". - /// \param [in] pInStr - pointer to input string which can contain incorrect form of values. - /// \param [out[ pOutString - output string with right form of values. - void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString); - - /// Check if current node has nodes of type X3DMetadataObject. Why we must do it? Because X3DMetadataObject can be in any non-empty X3DNode. - /// Meaning that X3DMetadataObject can be in any non-empty node in . - /// \return true - if metadata node are found and parsed, false - metadata not found. - bool ParseHelper_CheckRead_X3DMetadataObject(); - - /// Check if current node has nodes of type X3DGeometricPropertyNode. X3DGeometricPropertyNode - /// X3DGeometricPropertyNode inheritors: - /// , , , , , , , , - /// , , , , , - /// , , . - /// \return true - if nodes are found and parsed, false - nodes not found. - bool ParseHelper_CheckRead_X3DGeometricPropertyNode(); - - /// Parse node of the file. - void ParseNode_Root(); - - /// Parse node of the file. - void ParseNode_Head(); - - /// Parse node of the file. - void ParseNode_Scene(); - - /// Parse child nodes of node. - /// \param [in] pNodeName - parsed node name. Must be set because that function is general and name needed for checking the end - /// and error reporing. - /// \param [in] pParentElement - parent metadata element. - void ParseNode_Metadata(X3DNodeElementBase* pParentElement, const std::string& pNodeName); - - /// Parse node of the file. - void ParseNode_MetadataBoolean(); - - /// Parse node of the file. - void ParseNode_MetadataDouble(); - - /// Parse node of the file. - void ParseNode_MetadataFloat(); - - /// Parse node of the file. - void ParseNode_MetadataInteger(); - - /// Parse node of the file. - void ParseNode_MetadataSet(); - - /// \fn void ParseNode_MetadataString() - /// Parse node of the file. - void ParseNode_MetadataString(); - - /// Parse node of the file. - void ParseNode_Geometry2D_Arc2D(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry2D_ArcClose2D(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry2D_Circle2D(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry2D_Disk2D(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry2D_Polyline2D(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry2D_Polypoint2D(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry2D_Rectangle2D(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry2D_TriangleSet2D(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry3D_Box(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry3D_Cone(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry3D_Cylinder(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry3D_ElevationGrid(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry3D_Extrusion(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry3D_IndexedFaceSet(XmlNode &node); - - /// Parse node of the file. - void ParseNode_Geometry3D_Sphere(XmlNode &node); - - /// Parse node of the file. And create new node in scene graph. - void ParseNode_Grouping_Group(XmlNode &node); - - /// Doing actions at an exit from . Walk up in scene graph. - void ParseNode_Grouping_GroupEnd(); - - /// Parse node of the file. And create new node in scene graph. - void ParseNode_Grouping_StaticGroup(XmlNode &node); - - /// Doing actions at an exit from . Walk up in scene graph. - void ParseNode_Grouping_StaticGroupEnd(); - - /// Parse node of the file. And create new node in scene graph. - void ParseNode_Grouping_Switch(XmlNode &node); - - /// Doing actions at an exit from . Walk up in scene graph. - void ParseNode_Grouping_SwitchEnd(); - - /// Parse node of the file. And create new node in scene graph. - void ParseNode_Grouping_Transform(XmlNode &node); - - /// Doing actions at an exit from . Walk up in scene graph. - void ParseNode_Grouping_TransformEnd(); - - /// Parse node of the file. - void ParseNode_Rendering_Color(); - - /// Parse node of the file. - void ParseNode_Rendering_ColorRGBA(); - - /// Parse node of the file. - void ParseNode_Rendering_Coordinate(); - - /// Parse node of the file. - void ParseNode_Rendering_Normal(); - - /// Parse node of the file. - void ParseNode_Rendering_IndexedLineSet(); - - /// Parse node of the file. - void ParseNode_Rendering_IndexedTriangleFanSet(); - - /// Parse node of the file. - void ParseNode_Rendering_IndexedTriangleSet(); - - /// Parse node of the file. - void ParseNode_Rendering_IndexedTriangleStripSet(); - - /// Parse node of the file. - void ParseNode_Rendering_LineSet(); - - /// Parse node of the file. - void ParseNode_Rendering_PointSet(); - - /// Parse node of the file. - void ParseNode_Rendering_TriangleFanSet(); - - /// Parse node of the file. - void ParseNode_Rendering_TriangleSet(); - - /// Parse node of the file. - void ParseNode_Rendering_TriangleStripSet(); - - /// Parse node of the file. - void ParseNode_Texturing_ImageTexture(); - - /// Parse node of the file. - void ParseNode_Texturing_TextureCoordinate(); - - /// Parse node of the file. - void ParseNode_Texturing_TextureTransform(); - - /// Parse node of the file. - void ParseNode_Shape_Shape(); - - /// Parse node of the file. - void ParseNode_Shape_Appearance(); - - /// Parse node of the file. - void ParseNode_Shape_Material(); - - /// Parse node of the file. - void ParseNode_Networking_Inline(); - - /// Parse node of the file. - void ParseNode_Lighting_DirectionalLight(); - - /// Parse node of the file. - void ParseNode_Lighting_PointLight(); - - /// Parse node of the file. - void ParseNode_Lighting_SpotLight(); - -private: + private: /***********************************************/ /******************** Types ********************/ /***********************************************/ @@ -796,7 +337,7 @@ private: /****************** Variables ******************/ /***********************************************/ X3DNodeElementBase* mNodeElementCur;///< Current element. - std::unique_ptr mReader;///< Pointer to XML-reader object + XmlParser *mXmlParser; IOSystem *mpIOHandler; };// class X3DImporter diff --git a/code/AssetLib/X3D/X3DImporter_Geometry2D.cpp b/code/AssetLib/X3D/X3DImporter_Geometry2D.cpp deleted file mode 100644 index 15775daef..000000000 --- a/code/AssetLib/X3D/X3DImporter_Geometry2D.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Geometry2D.cpp -/// \brief Parsing data from nodes of "Geometry2D" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Node.hpp" -#include "X3DImporter_Macro.hpp" - -namespace Assimp -{ - -// -// The Arc2D node specifies a linear circular arc whose center is at (0,0) and whose angles are measured starting at the positive x-axis and sweeping -// towards the positive y-axis. The radius field specifies the radius of the circle of which the arc is a portion. The arc extends from the startAngle -// counterclockwise to the endAngle. The values of startAngle and endAngle shall be in the range [-2pi, 2pi] radians (or the equivalent if a different -// angle base unit has been specified). If startAngle and endAngle have the same value, a circle is specified. -void X3DImporter::ParseNode_Geometry2D_Arc2D() { - std::string def, use; - float endAngle = AI_MATH_HALF_PI_F; - float radius = 1; - float startAngle = 0; - X3DNodeElementBase* ne = nullptr; - - /*MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("endAngle", endAngle, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("startAngle", startAngle, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_LOOPEND;*/ - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Arc2D, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DGeometry2D(X3DNodeElementBase::ENET_Arc2D, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // create point list of geometry object and convert it to line set. - std::list tlist; - - GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, tlist);///TODO: IME - AI_CONFIG for NumSeg - GeometryHelper_Extend_PointToLine(tlist, ((X3DGeometry2D*)ne)->Vertices); - ((X3DGeometry2D*)ne)->NumIndices = 2; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Arc2D"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// The ArcClose node specifies a portion of a circle whose center is at (0,0) and whose angles are measured starting at the positive x-axis and sweeping -// towards the positive y-axis. The end points of the arc specified are connected as defined by the closureType field. The radius field specifies the radius -// of the circle of which the arc is a portion. The arc extends from the startAngle counterclockwise to the endAngle. The value of radius shall be greater -// than zero. The values of startAngle and endAngle shall be in the range [-2pi, 2pi] radians (or the equivalent if a different default angle base unit has -// been specified). If startAngle and endAngle have the same value, a circle is specified and closureType is ignored. If the absolute difference between -// startAngle and endAngle is greater than or equal to 2pi, a complete circle is produced with no chord or radial line(s) drawn from the center. -// A closureType of "PIE" connects the end point to the start point by defining two straight line segments first from the end point to the center and then -// the center to the start point. A closureType of "CHORD" connects the end point to the start point by defining a straight line segment from the end point -// to the start point. Textures are applied individually to each face of the ArcClose2D. On the front (+Z) and back (-Z) faces of the ArcClose2D, when -// viewed from the +Z-axis, the texture is mapped onto each face with the same orientation as if the image were displayed normally in 2D. -void X3DImporter::ParseNode_Geometry2D_ArcClose2D() -{ - std::string def, use; - std::string closureType("PIE"); - float endAngle = AI_MATH_HALF_PI_F; - float radius = 1; - bool solid = false; - float startAngle = 0; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("closureType", closureType, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("endAngle", endAngle, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("startAngle", startAngle, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_ArcClose2D, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DGeometry2D(X3DNodeElementBase::ENET_ArcClose2D, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DGeometry2D*)ne)->Solid = solid; - // create point list of geometry object. - GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, ((X3DGeometry2D*)ne)->Vertices);///TODO: IME - AI_CONFIG for NumSeg - // add chord or two radiuses only if not a circle was defined - if(!((std::fabs(endAngle - startAngle) >= AI_MATH_TWO_PI_F) || (endAngle == startAngle))) - { - std::list& vlist = ((X3DGeometry2D*)ne)->Vertices;// just short alias. - - if((closureType == "PIE") || (closureType == "\"PIE\"")) - vlist.push_back(aiVector3D(0, 0, 0));// center point - first radial line - else if((closureType != "CHORD") && (closureType != "\"CHORD\"")) - Throw_IncorrectAttrValue("closureType"); - - vlist.push_back(*vlist.begin());// arc first point - chord from first to last point of arc(if CHORD) or second radial line(if PIE). - } - - ((X3DGeometry2D*)ne)->NumIndices = ((X3DGeometry2D*)ne)->Vertices.size(); - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "ArcClose2D"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Geometry2D_Circle2D() -{ - std::string def, use; - float radius = 1; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Circle2D, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DGeometry2D(X3DNodeElementBase::ENET_Circle2D, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // create point list of geometry object and convert it to line set. - std::list tlist; - - GeometryHelper_Make_Arc2D(0, 0, radius, 10, tlist);///TODO: IME - AI_CONFIG for NumSeg - GeometryHelper_Extend_PointToLine(tlist, ((X3DGeometry2D*)ne)->Vertices); - ((X3DGeometry2D*)ne)->NumIndices = 2; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Circle2D"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// The Disk2D node specifies a circular disk which is centred at (0, 0) in the local coordinate system. The outerRadius field specifies the radius of the -// outer dimension of the Disk2D. The innerRadius field specifies the inner dimension of the Disk2D. The value of outerRadius shall be greater than zero. -// The value of innerRadius shall be greater than or equal to zero and less than or equal to outerRadius. If innerRadius is zero, the Disk2D is completely -// filled. Otherwise, the area within the innerRadius forms a hole in the Disk2D. If innerRadius is equal to outerRadius, a solid circular line shall -// be drawn using the current line properties. Textures are applied individually to each face of the Disk2D. On the front (+Z) and back (-Z) faces of -// the Disk2D, when viewed from the +Z-axis, the texture is mapped onto each face with the same orientation as if the image were displayed normally in 2D. -void X3DImporter::ParseNode_Geometry2D_Disk2D() -{ - std::string def, use; - float innerRadius = 0; - float outerRadius = 1; - bool solid = false; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("innerRadius", innerRadius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("outerRadius", outerRadius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Disk2D, ne); - } - else - { - std::list tlist_o, tlist_i; - - if(innerRadius > outerRadius) Throw_IncorrectAttrValue("innerRadius"); - - // create and if needed - define new geometry object. - ne = new X3DGeometry2D(X3DNodeElementBase::ENET_Disk2D, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // create point list of geometry object. - ///TODO: IME - AI_CONFIG for NumSeg - GeometryHelper_Make_Arc2D(0, 0, outerRadius, 10, tlist_o);// outer circle - if(innerRadius == 0.0f) - {// make filled disk - // in tlist_o we already have points of circle. just copy it and sign as polygon. - ((X3DGeometry2D*)ne)->Vertices = tlist_o; - ((X3DGeometry2D*)ne)->NumIndices = tlist_o.size(); - } - else if(innerRadius == outerRadius) - {// make circle - // in tlist_o we already have points of circle. convert it to line set. - GeometryHelper_Extend_PointToLine(tlist_o, ((X3DGeometry2D*)ne)->Vertices); - ((X3DGeometry2D*)ne)->NumIndices = 2; - } - else - {// make disk - std::list& vlist = ((X3DGeometry2D*)ne)->Vertices;// just short alias. - - GeometryHelper_Make_Arc2D(0, 0, innerRadius, 10, tlist_i);// inner circle - // - // create quad list from two point lists - // - if(tlist_i.size() < 2) throw DeadlyImportError("Disk2D. Not enough points for creating quad list.");// tlist_i and tlist_o has equal size. - - // add all quads except last - for(std::list::iterator it_i = tlist_i.begin(), it_o = tlist_o.begin(); it_i != tlist_i.end();) - { - // do not forget - CCW direction - vlist.push_back(*it_i++);// 1st point - vlist.push_back(*it_o++);// 2nd point - vlist.push_back(*it_o);// 3rd point - vlist.push_back(*it_i);// 4th point - } - - // add last quad - vlist.push_back(*tlist_i.end());// 1st point - vlist.push_back(*tlist_o.end());// 2nd point - vlist.push_back(*tlist_o.begin());// 3rd point - vlist.push_back(*tlist_o.begin());// 4th point - - ((X3DGeometry2D*)ne)->NumIndices = 4; - } - - ((X3DGeometry2D*)ne)->Solid = solid; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Disk2D"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Geometry2D_Polyline2D() -{ - std::string def, use; - std::list lineSegments; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("lineSegments", lineSegments, XML_ReadNode_GetAttrVal_AsListVec2f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Polyline2D, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DGeometry2D(X3DNodeElementBase::ENET_Polyline2D, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // - // convert read point list of geometry object to line set. - // - std::list tlist; - - // convert vec2 to vec3 - for(std::list::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); ++it2) tlist.push_back(aiVector3D(it2->x, it2->y, 0)); - - // convert point set to line set - GeometryHelper_Extend_PointToLine(tlist, ((X3DGeometry2D*)ne)->Vertices); - ((X3DGeometry2D*)ne)->NumIndices = 2; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Polyline2D"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Geometry2D_Polypoint2D() -{ - std::string def, use; - std::list point; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("point", point, XML_ReadNode_GetAttrVal_AsListVec2f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Polypoint2D, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DGeometry2D(X3DNodeElementBase::ENET_Polypoint2D, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // convert vec2 to vec3 - for(std::list::iterator it2 = point.begin(); it2 != point.end(); ++it2) - { - ((X3DGeometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0)); - } - - ((X3DGeometry2D*)ne)->NumIndices = 1; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Polypoint2D"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Geometry2D_Rectangle2D() -{ - std::string def, use; - aiVector2D size(2, 2); - bool solid = false; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("size", size, XML_ReadNode_GetAttrVal_AsVec2f); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Rectangle2D, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DGeometry2D(X3DNodeElementBase::ENET_Rectangle2D, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - float x1 = -size.x / 2.0f; - float x2 = size.x / 2.0f; - float y1 = -size.y / 2.0f; - float y2 = size.y / 2.0f; - std::list& vlist = ((X3DGeometry2D*)ne)->Vertices;// just short alias. - - vlist.push_back(aiVector3D(x2, y1, 0));// 1st point - vlist.push_back(aiVector3D(x2, y2, 0));// 2nd point - vlist.push_back(aiVector3D(x1, y2, 0));// 3rd point - vlist.push_back(aiVector3D(x1, y1, 0));// 4th point - ((X3DGeometry2D*)ne)->Solid = solid; - ((X3DGeometry2D*)ne)->NumIndices = 4; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Rectangle2D"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Geometry2D_TriangleSet2D() -{ - std::string def, use; - bool solid = false; - std::list vertices; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("vertices", vertices, XML_ReadNode_GetAttrVal_AsListVec2f); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleSet2D, ne); - } - else - { - if(vertices.size() % 3) throw DeadlyImportError("TriangleSet2D. Not enough points for defining triangle."); - - // create and if needed - define new geometry object. - ne = new X3DGeometry2D(X3DNodeElementBase::ENET_TriangleSet2D, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // convert vec2 to vec3 - for(std::list::iterator it2 = vertices.begin(); it2 != vertices.end(); ++it2) - { - ((X3DGeometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0)); - } - - ((X3DGeometry2D*)ne)->Solid = solid; - ((X3DGeometry2D*)ne)->NumIndices = 3; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "TriangleSet2D"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Geometry3D.cpp b/code/AssetLib/X3D/X3DImporter_Geometry3D.cpp deleted file mode 100644 index 46ca54c02..000000000 --- a/code/AssetLib/X3D/X3DImporter_Geometry3D.cpp +++ /dev/null @@ -1,999 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Geometry3D.cpp -/// \brief Parsing data from nodes of "Geometry3D" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" - -// Header files, Assimp. -#include - -namespace Assimp -{ - -// -// The Box node specifies a rectangular parallelepiped box centred at (0, 0, 0) in the local coordinate system and aligned with the local coordinate axes. -// By default, the box measures 2 units in each dimension, from -1 to +1. The size field specifies the extents of the box along the X-, Y-, and Z-axes -// respectively and each component value shall be greater than zero. -void X3DImporter::ParseNode_Geometry3D_Box() -{ - std::string def, use; - bool solid = true; - aiVector3D size(2, 2, 2); - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("size", size, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Box, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DGeometry3D(X3DNodeElementBase::ENET_Box, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - GeometryHelper_MakeQL_RectParallelepiped(size, ((X3DGeometry3D*)ne)->Vertices);// get quad list - ((X3DGeometry3D*)ne)->Solid = solid; - ((X3DGeometry3D*)ne)->NumIndices = 4; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Box"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Geometry3D_Cone() -{ - std::string use, def; - bool bottom = true; - float bottomRadius = 1; - float height = 2; - bool side = true; - bool solid = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("side", side, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("bottom", bottom, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("height", height, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("bottomRadius", bottomRadius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Cone, ne); - } - else - { - const unsigned int tess = 30;///TODO: IME tessellation factor through ai_property - - std::vector tvec;// temp array for vertices. - - // create and if needed - define new geometry object. - ne = new X3DGeometry3D(X3DNodeElementBase::ENET_Cone, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // make cone or parts according to flags. - if(side) - { - StandardShapes::MakeCone(height, 0, bottomRadius, tess, tvec, !bottom); - } - else if(bottom) - { - StandardShapes::MakeCircle(bottomRadius, tess, tvec); - height = -(height / 2); - for(std::vector::iterator it = tvec.begin(); it != tvec.end(); ++it) it->y = height;// y - because circle made in oXZ. - } - - // copy data from temp array - for(std::vector::iterator it = tvec.begin(); it != tvec.end(); ++it) ((X3DGeometry3D*)ne)->Vertices.push_back(*it); - - ((X3DGeometry3D*)ne)->Solid = solid; - ((X3DGeometry3D*)ne)->NumIndices = 3; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Cone"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Geometry3D_Cylinder() -{ - std::string use, def; - bool bottom = true; - float height = 2; - float radius = 1; - bool side = true; - bool solid = true; - bool top = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("bottom", bottom, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("top", top, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("side", side, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("height", height, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Cylinder, ne); - } - else - { - const unsigned int tess = 30;///TODO: IME tessellation factor through ai_property - - std::vector tside;// temp array for vertices of side. - std::vector tcir;// temp array for vertices of circle. - - // create and if needed - define new geometry object. - ne = new X3DGeometry3D(X3DNodeElementBase::ENET_Cylinder, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // make cilynder or parts according to flags. - if(side) StandardShapes::MakeCone(height, radius, radius, tess, tside, true); - - height /= 2;// height defined for whole cylinder, when creating top and bottom circle we are using just half of height. - if(top || bottom) StandardShapes::MakeCircle(radius, tess, tcir); - // copy data from temp arrays - std::list& vlist = ((X3DGeometry3D*)ne)->Vertices;// just short alias. - - for(std::vector::iterator it = tside.begin(); it != tside.end(); ++it) vlist.push_back(*it); - - if(top) - { - for(std::vector::iterator it = tcir.begin(); it != tcir.end(); ++it) - { - (*it).y = height;// y - because circle made in oXZ. - vlist.push_back(*it); - } - }// if(top) - - if(bottom) - { - for(std::vector::iterator it = tcir.begin(); it != tcir.end(); ++it) - { - (*it).y = -height;// y - because circle made in oXZ. - vlist.push_back(*it); - } - }// if(top) - - ((X3DGeometry3D*)ne)->Solid = solid; - ((X3DGeometry3D*)ne)->NumIndices = 3; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Cylinder"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ColorNormalTexCoordContentModel can contain Color (or ColorRGBA), Normal and TextureCoordinate, in any order. No more than one instance of any single -// node type is allowed. A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -// The ElevationGrid node specifies a uniform rectangular grid of varying height in the Y=0 plane of the local coordinate system. The geometry is described -// by a scalar array of height values that specify the height of a surface above each point of the grid. The xDimension and zDimension fields indicate -// the number of elements of the grid height array in the X and Z directions. Both xDimension and zDimension shall be greater than or equal to zero. -// If either the xDimension or the zDimension is less than two, the ElevationGrid contains no quadrilaterals. -void X3DImporter::ParseNode_Geometry3D_ElevationGrid() -{ - std::string use, def; - bool ccw = true; - bool colorPerVertex = true; - float creaseAngle = 0; - std::vector height; - bool normalPerVertex = true; - bool solid = true; - int32_t xDimension = 0; - float xSpacing = 1; - int32_t zDimension = 0; - float zSpacing = 1; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool); - 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_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); - MACRO_ATTRREAD_CHECK_RET("zSpacing", zSpacing, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_ElevationGrid, ne); - } - else - { - if((xSpacing == 0.0f) || (zSpacing == 0.0f)) throw DeadlyImportError("Spacing in must be grater than zero."); - if((xDimension <= 0) || (zDimension <= 0)) throw DeadlyImportError("Dimension in must be grater than zero."); - if((size_t)(xDimension * zDimension) != height.size()) Throw_IncorrectAttrValue("Heights count must be equal to \"xDimension * zDimension\""); - - // create and if needed - define new geometry object. - ne = new X3DElevationGrid(X3DNodeElementBase::ENET_ElevationGrid, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DElevationGrid& grid_alias = *((X3DElevationGrid*)ne);// create alias for conveience - - {// create grid vertices list - std::vector::const_iterator he_it = height.begin(); - - for(int32_t zi = 0; zi < zDimension; zi++)// rows - { - for(int32_t xi = 0; xi < xDimension; xi++)// columns - { - aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi); - - grid_alias.Vertices.push_back(tvec); - ++he_it; - } - } - }// END: create grid vertices list - // - // create faces list. In "coordIdx" format - // - // check if we have quads - if((xDimension < 2) || (zDimension < 2))// only one element in dimension is set, create line set. - { - ((X3DElevationGrid*)ne)->NumIndices = 2;// will be holded as line set. - for(size_t i = 0, i_e = (grid_alias.Vertices.size() - 1); i < i_e; i++) - { - grid_alias.CoordIdx.push_back(static_cast(i)); - grid_alias.CoordIdx.push_back(static_cast(i + 1)); - grid_alias.CoordIdx.push_back(-1); - } - } - else// two or more elements in every dimension is set. create quad set. - { - ((X3DElevationGrid*)ne)->NumIndices = 4; - for(int32_t fzi = 0, fzi_e = (zDimension - 1); fzi < fzi_e; fzi++)// rows - { - for(int32_t fxi = 0, fxi_e = (xDimension - 1); fxi < fxi_e; fxi++)// columns - { - // points direction in face. - if(ccw) - { - // CCW: - // 3 2 - // 0 1 - grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + fxi); - grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + (fxi + 1)); - grid_alias.CoordIdx.push_back(fzi * xDimension + (fxi + 1)); - grid_alias.CoordIdx.push_back(fzi * xDimension + fxi); - } - else - { - // CW: - // 0 1 - // 3 2 - grid_alias.CoordIdx.push_back(fzi * xDimension + fxi); - grid_alias.CoordIdx.push_back(fzi * xDimension + (fxi + 1)); - grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + (fxi + 1)); - grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + fxi); - }// if(ccw) else - - grid_alias.CoordIdx.push_back(-1); - }// for(int32_t fxi = 0, fxi_e = (xDimension - 1); fxi < fxi_e; fxi++) - }// for(int32_t fzi = 0, fzi_e = (zDimension - 1); fzi < fzi_e; fzi++) - }// if((xDimension < 2) || (zDimension < 2)) else - - grid_alias.ColorPerVertex = colorPerVertex; - grid_alias.NormalPerVertex = normalPerVertex; - grid_alias.CreaseAngle = creaseAngle; - grid_alias.Solid = solid; - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("ElevationGrid"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; } - if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("ElevationGrid"); - - MACRO_NODECHECK_LOOPEND("ElevationGrid"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - }// if(!mReader->isEmptyElement()) else - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -template -static void GeometryHelper_Extrusion_CurveIsClosed(std::vector& pCurve, const bool pDropTail, const bool pRemoveLastPoint, bool& pCurveIsClosed) -{ - size_t cur_sz = pCurve.size(); - - pCurveIsClosed = false; - // for curve with less than four points checking is have no sense, - if(cur_sz < 4) return; - - for(size_t s = 3, s_e = cur_sz; s < s_e; s++) - { - // search for first point of duplicated part. - if(pCurve[0] == pCurve[s]) - { - bool found = true; - - // check if tail(indexed by b2) is duplicate of head(indexed by b1). - for(size_t b1 = 1, b2 = (s + 1); b2 < cur_sz; b1++, b2++) - { - if(pCurve[b1] != pCurve[b2]) - {// points not match: clear flag and break loop. - found = false; - - break; - } - }// for(size_t b1 = 1, b2 = (s + 1); b2 < cur_sz; b1++, b2++) - - // if duplicate tail is found then drop or not it depending on flags. - if(found) - { - pCurveIsClosed = true; - if(pDropTail) - { - if(!pRemoveLastPoint) s++;// prepare value for iterator's arithmetics. - - pCurve.erase(pCurve.begin() + s, pCurve.end());// remove tail - } - - break; - }// if(found) - }// if(pCurve[0] == pCurve[s]) - }// for(size_t s = 3, s_e = (cur_sz - 1); s < s_e; s++) -} - -static aiVector3D GeometryHelper_Extrusion_GetNextY(const size_t pSpine_PointIdx, const std::vector& pSpine, const bool pSpine_Closed) -{ - const size_t spine_idx_last = pSpine.size() - 1; - aiVector3D tvec; - - if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last))// at first special cases - { - if(pSpine_Closed) - {// If the spine curve is closed: The SCP for the first and last points is the same and is found using (spine[1] - spine[n - 2]) to compute the Y-axis. - // As we even for closed spine curve last and first point in pSpine are not the same: duplicates(spine[n - 1] which are equivalent to spine[0]) - // in tail are removed. - // So, last point in pSpine is a spine[n - 2] - tvec = pSpine[1] - pSpine[spine_idx_last]; - } - else if(pSpine_PointIdx == 0) - {// The Y-axis used for the first point is the vector from spine[0] to spine[1] - tvec = pSpine[1] - pSpine[0]; - } - else - {// The Y-axis used for the last point it is the vector from spine[n-2] to spine[n-1]. In our case(see above about dropping tail) spine[n - 1] is - // the spine[0]. - tvec = pSpine[spine_idx_last] - pSpine[spine_idx_last - 1]; - } - }// if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last)) - else - {// For all points other than the first or last: The Y-axis for spine[i] is found by normalizing the vector defined by (spine[i+1] - spine[i-1]). - tvec = pSpine[pSpine_PointIdx + 1] - pSpine[pSpine_PointIdx - 1]; - }// if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last)) else - - return tvec.Normalize(); -} - -static aiVector3D GeometryHelper_Extrusion_GetNextZ(const size_t pSpine_PointIdx, const std::vector& pSpine, const bool pSpine_Closed, - const aiVector3D pVecZ_Prev) -{ - const aiVector3D zero_vec(0); - const size_t spine_idx_last = pSpine.size() - 1; - - aiVector3D tvec; - - // at first special cases - if(pSpine.size() < 3)// spine have not enough points for vector calculations. - { - tvec.Set(0, 0, 1); - } - else if(pSpine_PointIdx == 0)// special case: first point - { - if(pSpine_Closed)// for calculating use previous point in curve s[n - 2]. In list it's a last point, because point s[n - 1] was removed as duplicate. - { - tvec = (pSpine[1] - pSpine[0]) ^ (pSpine[spine_idx_last] - pSpine[0]); - } - else // for not closed curve first and next point(s[0] and s[1]) has the same vector Z. - { - bool found = false; - - // As said: "If the Z-axis of the first point is undefined (because the spine is not closed and the first two spine segments are collinear) - // then the Z-axis for the first spine point with a defined Z-axis is used." - // Walk through spine and find Z. - for(size_t next_point = 2; (next_point <= spine_idx_last) && !found; next_point++) - { - // (pSpine[2] - pSpine[1]) ^ (pSpine[0] - pSpine[1]) - tvec = (pSpine[next_point] - pSpine[next_point - 1]) ^ (pSpine[next_point - 2] - pSpine[next_point - 1]); - found = !tvec.Equal(zero_vec); - } - - // if entire spine are collinear then use OZ axis. - if(!found) tvec.Set(0, 0, 1); - }// if(pSpine_Closed) else - }// else if(pSpine_PointIdx == 0) - else if(pSpine_PointIdx == spine_idx_last)// special case: last point - { - if(pSpine_Closed) - {// do not forget that real last point s[n - 1] is removed as duplicated. And in this case we are calculating vector Z for point s[n - 2]. - tvec = (pSpine[0] - pSpine[pSpine_PointIdx]) ^ (pSpine[pSpine_PointIdx - 1] - pSpine[pSpine_PointIdx]); - // if taken spine vectors are collinear then use previous vector Z. - if(tvec.Equal(zero_vec)) tvec = pVecZ_Prev; - } - else - {// vector Z for last point of not closed curve is previous vector Z. - tvec = pVecZ_Prev; - } - } - else// regular point - { - tvec = (pSpine[pSpine_PointIdx + 1] - pSpine[pSpine_PointIdx]) ^ (pSpine[pSpine_PointIdx - 1] - pSpine[pSpine_PointIdx]); - // if taken spine vectors are collinear then use previous vector Z. - if(tvec.Equal(zero_vec)) tvec = pVecZ_Prev; - } - - // After determining the Z-axis, its dot product with the Z-axis of the previous spine point is computed. If this value is negative, the Z-axis - // is flipped (multiplied by -1). - if((tvec * pVecZ_Prev) < 0) tvec = -tvec; - - return tvec.Normalize(); -} - -// -void X3DImporter::ParseNode_Geometry3D_Extrusion() -{ - std::string use, def; - bool beginCap = true; - bool ccw = true; - bool convex = true; - float creaseAngle = 0; - std::vector crossSection; - bool endCap = true; - std::vector orientation; - std::vector scale; - bool solid = true; - std::vector spine; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("beginCap", beginCap, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("convex", convex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("crossSection", crossSection, XML_ReadNode_GetAttrVal_AsArrVec2f); - MACRO_ATTRREAD_CHECK_RET("endCap", endCap, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("orientation", orientation, XML_ReadNode_GetAttrVal_AsArrF); - MACRO_ATTRREAD_CHECK_REF("scale", scale, XML_ReadNode_GetAttrVal_AsArrVec2f); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("spine", spine, XML_ReadNode_GetAttrVal_AsArrVec3f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Extrusion, ne); - } - else - { - // - // check if default values must be assigned - // - if(spine.size() == 0) - { - spine.resize(2); - spine[0].Set(0, 0, 0), spine[1].Set(0, 1, 0); - } - else if(spine.size() == 1) - { - throw DeadlyImportError("ParseNode_Geometry3D_Extrusion. Spine must have at least two points."); - } - - if(crossSection.size() == 0) - { - crossSection.resize(5); - crossSection[0].Set(1, 1), crossSection[1].Set(1, -1), crossSection[2].Set(-1, -1), crossSection[3].Set(-1, 1), crossSection[4].Set(1, 1); - } - - {// orientation - size_t ori_size = orientation.size() / 4; - - if(ori_size < spine.size()) - { - float add_ori[4];// values that will be added - - if(ori_size == 1)// if "orientation" has one element(means one MFRotation with four components) then use it value for all spine points. - { - add_ori[0] = orientation[0], add_ori[1] = orientation[1], add_ori[2] = orientation[2], add_ori[3] = orientation[3]; - } - else// else - use default values - { - add_ori[0] = 0, add_ori[1] = 0, add_ori[2] = 1, add_ori[3] = 0; - } - - orientation.reserve(spine.size() * 4); - for(size_t i = 0, i_e = (spine.size() - ori_size); i < i_e; i++) - orientation.push_back(add_ori[0]), orientation.push_back(add_ori[1]), orientation.push_back(add_ori[2]), orientation.push_back(add_ori[3]); - } - - if(orientation.size() % 4) throw DeadlyImportError("Attribute \"orientation\" in must has multiple four quantity of numbers."); - }// END: orientation - - {// scale - if(scale.size() < spine.size()) - { - aiVector2D add_sc; - - if(scale.size() == 1)// if "scale" has one element then use it value for all spine points. - add_sc = scale[0]; - else// else - use default values - add_sc.Set(1, 1); - - scale.reserve(spine.size()); - for(size_t i = 0, i_e = (spine.size() - scale.size()); i < i_e; i++) scale.push_back(add_sc); - } - }// END: scale - // - // create and if needed - define new geometry object. - // - ne = new X3DIndexedSet(X3DNodeElementBase::ENET_Extrusion, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DIndexedSet& ext_alias = *((X3DIndexedSet*)ne);// create alias for conveience - // assign part of input data - ext_alias.CCW = ccw; - ext_alias.Convex = convex; - ext_alias.CreaseAngle = creaseAngle; - ext_alias.Solid = solid; - - // - // How we done it at all? - // 1. At first we will calculate array of basises for every point in spine(look SCP in ISO-dic). Also "orientation" vector - // are applied vor every basis. - // 2. After that we can create array of point sets: which are scaled, transferred to basis of relative basis and at final translated to real position - // using relative spine point. - // 3. Next step is creating CoordIdx array(do not forget "-1" delimiter). While creating CoordIdx also created faces for begin and end caps, if - // needed. While createing CootdIdx is taking in account CCW flag. - // 4. The last step: create Vertices list. - // - bool spine_closed;// flag: true if spine curve is closed. - bool cross_closed;// flag: true if cross curve is closed. - std::vector basis_arr;// array of basises. ROW_a - X, ROW_b - Y, ROW_c - Z. - std::vector > pointset_arr;// array of point sets: cross curves. - - // detect closed curves - GeometryHelper_Extrusion_CurveIsClosed(crossSection, true, true, cross_closed);// true - drop tail, true - remove duplicate end. - GeometryHelper_Extrusion_CurveIsClosed(spine, true, true, spine_closed);// true - drop tail, true - remove duplicate end. - // If both cap are requested and spine curve is closed then we can make only one cap. Because second cap will be the same surface. - if(spine_closed) - { - beginCap |= endCap; - endCap = false; - } - - {// 1. Calculate array of basises. - aiMatrix4x4 rotmat; - aiVector3D vecX(0), vecY(0), vecZ(0); - - basis_arr.resize(spine.size()); - for(size_t i = 0, i_e = spine.size(); i < i_e; i++) - { - aiVector3D tvec; - - // get axises of basis. - vecY = GeometryHelper_Extrusion_GetNextY(i, spine, spine_closed); - vecZ = GeometryHelper_Extrusion_GetNextZ(i, spine, spine_closed, vecZ); - vecX = (vecY ^ vecZ).Normalize(); - // get rotation matrix and apply "orientation" to basis - aiMatrix4x4::Rotation(orientation[i * 4 + 3], aiVector3D(orientation[i * 4], orientation[i * 4 + 1], orientation[i * 4 + 2]), rotmat); - tvec = vecX, tvec *= rotmat, basis_arr[i].a1 = tvec.x, basis_arr[i].a2 = tvec.y, basis_arr[i].a3 = tvec.z; - tvec = vecY, tvec *= rotmat, basis_arr[i].b1 = tvec.x, basis_arr[i].b2 = tvec.y, basis_arr[i].b3 = tvec.z; - tvec = vecZ, tvec *= rotmat, basis_arr[i].c1 = tvec.x, basis_arr[i].c2 = tvec.y, basis_arr[i].c3 = tvec.z; - }// for(size_t i = 0, i_e = spine.size(); i < i_e; i++) - }// END: 1. Calculate array of basises - - {// 2. Create array of point sets. - aiMatrix4x4 scmat; - std::vector tcross(crossSection.size()); - - pointset_arr.resize(spine.size()); - for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; spi++) - { - aiVector3D tc23vec; - - tc23vec.Set(scale[spi].x, 0, scale[spi].y); - aiMatrix4x4::Scaling(tc23vec, scmat); - for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; cri++) - { - aiVector3D tvecX, tvecY, tvecZ; - - tc23vec.Set(crossSection[cri].x, 0, crossSection[cri].y); - // apply scaling to point - tcross[cri] = scmat * tc23vec; - // - // transfer point to new basis - // calculate coordinate in new basis - tvecX.Set(basis_arr[spi].a1, basis_arr[spi].a2, basis_arr[spi].a3), tvecX *= tcross[cri].x; - tvecY.Set(basis_arr[spi].b1, basis_arr[spi].b2, basis_arr[spi].b3), tvecY *= tcross[cri].y; - tvecZ.Set(basis_arr[spi].c1, basis_arr[spi].c2, basis_arr[spi].c3), tvecZ *= tcross[cri].z; - // apply new coordinates and translate it to spine point. - tcross[cri] = tvecX + tvecY + tvecZ + spine[spi]; - }// for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; i++) - - pointset_arr[spi] = tcross;// store transferred point set - }// for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; i++) - }// END: 2. Create array of point sets. - - {// 3. Create CoordIdx. - // add caps if needed - if(beginCap) - { - // add cap as polygon. vertices of cap are places at begin, so just add numbers from zero. - for(size_t i = 0, i_e = crossSection.size(); i < i_e; i++) ext_alias.CoordIndex.push_back(static_cast(i)); - - // add delimiter - ext_alias.CoordIndex.push_back(-1); - }// if(beginCap) - - if(endCap) - { - // add cap as polygon. vertices of cap are places at end, as for beginCap use just sequence of numbers but with offset. - size_t beg = (pointset_arr.size() - 1) * crossSection.size(); - - for(size_t i = beg, i_e = (beg + crossSection.size()); i < i_e; i++) ext_alias.CoordIndex.push_back(static_cast(i)); - - // add delimiter - ext_alias.CoordIndex.push_back(-1); - }// if(beginCap) - - // add quads - for(size_t spi = 0, spi_e = (spine.size() - 1); spi <= spi_e; spi++) - { - const size_t cr_sz = crossSection.size(); - const size_t cr_last = crossSection.size() - 1; - - size_t right_col;// hold index basis for points of quad placed in right column; - - if(spi != spi_e) - right_col = spi + 1; - else if(spine_closed)// if spine curve is closed then one more quad is needed: between first and last points of curve. - right_col = 0; - else - break;// if spine curve is not closed then break the loop, because spi is out of range for that type of spine. - - for(size_t cri = 0; cri < cr_sz; cri++) - { - if(cri != cr_last) - { - MACRO_FACE_ADD_QUAD(ccw, ext_alias.CoordIndex, - static_cast(spi * cr_sz + cri), - static_cast(right_col * cr_sz + cri), - static_cast(right_col * cr_sz + cri + 1), - static_cast(spi * cr_sz + cri + 1)); - // add delimiter - ext_alias.CoordIndex.push_back(-1); - } - else if(cross_closed)// if cross curve is closed then one more quad is needed: between first and last points of curve. - { - MACRO_FACE_ADD_QUAD(ccw, ext_alias.CoordIndex, - static_cast(spi * cr_sz + cri), - static_cast(right_col * cr_sz + cri), - static_cast(right_col * cr_sz + 0), - static_cast(spi * cr_sz + 0)); - // add delimiter - ext_alias.CoordIndex.push_back(-1); - } - }// for(size_t cri = 0; cri < cr_sz; cri++) - }// for(size_t spi = 0, spi_e = (spine.size() - 2); spi < spi_e; spi++) - }// END: 3. Create CoordIdx. - - {// 4. Create vertices list. - // just copy all vertices - for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; spi++) - { - for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; cri++) - { - ext_alias.Vertices.push_back(pointset_arr[spi][cri]); - } - } - }// END: 4. Create vertices list. -//PrintVectorSet("Ext. CoordIdx", ext_alias.CoordIndex); -//PrintVectorSet("Ext. Vertices", ext_alias.Vertices); - // check for child nodes - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Extrusion"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate, -// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute, -// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Geometry3D_IndexedFaceSet() -{ - std::string use, def; - bool ccw = true; - std::vector colorIndex; - bool colorPerVertex = true; - bool convex = true; - std::vector coordIndex; - float creaseAngle = 0; - std::vector normalIndex; - bool normalPerVertex = true; - bool solid = true; - std::vector texCoordIndex; - X3DNodeElementBase* 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_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_AsArrI32); - MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat); - 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_AsArrI32); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedFaceSet, ne); - } - else - { - // check data - if(coordIndex.size() == 0) throw DeadlyImportError("IndexedFaceSet must contain not empty \"coordIndex\" attribute."); - - // create and if needed - define new geometry object. - ne = new X3DIndexedSet(X3DNodeElementBase::ENET_IndexedFaceSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DIndexedSet& ne_alias = *((X3DIndexedSet*)ne); - - ne_alias.CCW = ccw; - ne_alias.ColorIndex = colorIndex; - ne_alias.ColorPerVertex = colorPerVertex; - ne_alias.Convex = convex; - ne_alias.CoordIndex = coordIndex; - ne_alias.CreaseAngle = creaseAngle; - ne_alias.NormalIndex = normalIndex; - ne_alias.NormalPerVertex = normalPerVertex; - ne_alias.Solid = solid; - ne_alias.TexCoordIndex = texCoordIndex; - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("IndexedFaceSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; } - if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedFaceSet"); - - MACRO_NODECHECK_LOOPEND("IndexedFaceSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Geometry3D_Sphere() -{ - std::string use, def; - ai_real radius = 1; - bool solid = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Sphere, ne); - } - else - { - const unsigned int tess = 3;///TODO: IME tessellation factor through ai_property - - std::vector tlist; - - // create and if needed - define new geometry object. - ne = new X3DGeometry3D(X3DNodeElementBase::ENET_Sphere, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - StandardShapes::MakeSphere(tess, tlist); - // copy data from temp array and apply scale - for(std::vector::iterator it = tlist.begin(); it != tlist.end(); ++it) - { - ((X3DGeometry3D*)ne)->Vertices.push_back(*it * radius); - } - - ((X3DGeometry3D*)ne)->Solid = solid; - ((X3DGeometry3D*)ne)->NumIndices = 3; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Sphere"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Group.cpp b/code/AssetLib/X3D/X3DImporter_Group.cpp deleted file mode 100644 index 60dfc4cc0..000000000 --- a/code/AssetLib/X3D/X3DImporter_Group.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Group.cpp -/// \brief Parsing data from nodes of "Grouping" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" - -#include - -namespace Assimp -{ - -// -// -// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes, -// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the -// precise palette of legal nodes that are available depends on assigned profile and components. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -// A Group node contains children nodes without introducing a new transformation. It is equivalent to a Transform node containing an identity transform. -void X3DImporter::ParseNode_Grouping_Group(XmlNode &node) { - //std::string def, use; - - std::string def = node.attribute("DEF").as_string(); - std::string use = node.attribute("USE").as_string(); - /*MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_LOOPEND;*/ - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - X3DNodeElementBase *ne = nullptr; - if (def.empty()) { - Throw_DEF_And_USE(node.name()); - } - if (!FindNodeElement(use, X3DNodeElementBase::ENET_Group, &ne)) { - Throw_USE_NotFound(node.name(), use); - } - mNodeElementCur->Child.push_back(ne); - //MACRO_USE_CHECKANDAPPLY(def, use, X3DNodeElementBase::ENET_Group, ne); - } else { - ParseHelper_Group_Begin();// create new grouping element and go deeper if node has children. - - // at this place new group mode created and made current, so we can name it. - if (!def.empty()) { - mNodeElementCur->ID = def; - } - // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in parser function. - - // for empty element exit from node in that place - //if(mReader->isEmptyElement()) - if (node.empty()) { - ParseHelper_Node_Exit(); - } - }// if(!use.empty()) else -} - -void X3DImporter::ParseNode_Grouping_GroupEnd() -{ - ParseHelper_Node_Exit();// go up in scene graph -} - -// -// -// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes, -// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the -// precise palette of legal nodes that are available depends on assigned profile and components. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -// The StaticGroup node contains children nodes which cannot be modified. StaticGroup children are guaranteed to not change, send events, receive events or -// contain any USE references outside the StaticGroup. -void X3DImporter::ParseNode_Grouping_StaticGroup(XmlNode &node) { -// std::string def, use; - std::string def = node.attribute("DEF").as_string(); - std::string use = node.attribute("USE").as_string(); - -/* MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_LOOPEND;*/ - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - X3DNodeElementBase* ne = nullptr; - if (!FindNodeElement(use, X3DNodeElementBase::ENET_Group, &ne)) { - Throw_USE_NotFound(node.name(), use); - } - mNodeElementCur->Child.push_back(ne); - -// MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne); - } - else - { - ParseHelper_Group_Begin(true);// create new grouping element and go deeper if node has children. - // at this place new group mode created and made current, so we can name it. - if(!def.empty()) mNodeElementCur->ID = def; - // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in parser function. - - // for empty element exit from node in that place - if (node.empty()) { - ParseHelper_Node_Exit(); - } - -// if(mReader->isEmptyElement()) ParseHelper_Node_Exit(); - }// if(!use.empty()) else -} - -void X3DImporter::ParseNode_Grouping_StaticGroupEnd() -{ - ParseHelper_Node_Exit();// go up in scene graph -} - -// -// -// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes, -// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the -// precise palette of legal nodes that are available depends on assigned profile and components. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -// The Switch grouping node traverses zero or one of the nodes specified in the children field. The whichChoice field specifies the index of the child -// to traverse, with the first child having index 0. If whichChoice is less than zero or greater than the number of nodes in the children field, nothing -// is chosen. -void X3DImporter::ParseNode_Grouping_Switch(XmlNode &node) { -// std::string def, use; - int32_t whichChoice = -1; - std::string def = node.attribute("DEF").as_string(); - std::string use = node.attribute("USE").as_string(); - pugi::xml_attribute attr = node.attribute("whichChoise"); - whichChoice = attr.as_int(); - /*MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("whichChoice", whichChoice, XML_ReadNode_GetAttrVal_AsI32); - MACRO_ATTRREAD_LOOPEND;*/ - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - X3DNodeElementBase* ne = nullptr; - if (!FindNodeElement(use, X3DNodeElementBase::ENET_Group, &ne)) { - Throw_USE_NotFound(node.name(), use); - } - mNodeElementCur->Child.push_back(ne); - - -// MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne); - } - else - { - ParseHelper_Group_Begin();// create new grouping element and go deeper if node has children. - // at this place new group mode created and made current, so we can name it. - if(!def.empty()) mNodeElementCur->ID = def; - - // also set values specific to this type of group - ((X3DGroup*)mNodeElementCur)->UseChoice = true; - ((X3DGroup*)mNodeElementCur)->Choice = whichChoice; - // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in parser function. - - // for empty element exit from node in that place -// if(mReader->isEmptyElement()) ParseHelper_Node_Exit(); - if (node.empty()) { - ParseHelper_Node_Exit(); - } - - }// if(!use.empty()) else -} - -void X3DImporter::ParseNode_Grouping_SwitchEnd() -{ - // just exit from node. Defined choice will be accepted at post-processing stage. - ParseHelper_Node_Exit();// go up in scene graph -} - -void ReadAttrAsVec3f(pugi::xml_node &node, const std::string &attrName, aiVector3D &vec) { - const pugi::xml_attribute &attr = node.attribute(attrName.c_str()); - if (attr.empty()) { - return; - } - - std::string data = attr.as_string(); - std::vector token; - tokenize(data, token, " "); - vec.x = (ai_real)std::atof(token[0].c_str()); - vec.y = (ai_real)std::atof(token[1].c_str()); - vec.z = (ai_real)std::atof(token[2].c_str()); -} - - -void ReadAttrAsFloatArray(pugi::xml_node &node, const std::string &attrName, size_t numComponents, std::vector &tvec) { - pugi::xml_attribute attr = node.attribute(attrName.c_str()); - std::string data = attr.as_string(); - std::vector token; - tokenize(data, token, " "); - if (token.size() != numComponents) throw DeadlyImportError(": rotation vector must have 4 elements."); - for (size_t i = 0; i < numComponents; ++i) { - tvec.push_back((ai_real)std::atof(token[i].c_str())); - } -} - -// -// -// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes, -// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the -// precise palette of legal nodes that are available depends on assigned profile and components. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -// The Transform node is a grouping node that defines a coordinate system for its children that is relative to the coordinate systems of its ancestors. -// Given a 3-dimensional point P and Transform node, P is transformed into point P' in its parent's coordinate system by a series of intermediate -// transformations. In matrix transformation notation, where C (center), SR (scaleOrientation), T (translation), R (rotation), and S (scale) are the -// equivalent transformation matrices, -// P' = T * C * R * SR * S * -SR * -C * P -void X3DImporter::ParseNode_Grouping_Transform(XmlNode &node) { - aiVector3D center(0, 0, 0); - float rotation[4] = { 0, 0, 1, 0 }; - aiVector3D scale(1, 1, 1); // A value of zero indicates that any child geometry shall not be displayed - float scale_orientation[4] = { 0, 0, 1, 0 }; - aiVector3D translation(0, 0, 0); - aiMatrix4x4 matr, tmatr; - //std::string use, def; - - //MACRO_ATTRREAD_LOOPBEG; - std::string def = node.attribute("DEF").as_string(); - std::string use = node.attribute("USE").as_string(); - - //MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - ReadAttrAsVec3f(node, "center", center); - ReadAttrAsVec3f(node, "scale", scale); - ReadAttrAsVec3f(node, "translation", translation); - /*MACRO_ATTRREAD_CHECK_REF("center", center, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_REF("scale", scale, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_REF("translation", translation, XML_ReadNode_GetAttrVal_AsVec3f);*/ - if (hasAttribute(node, "rotation")) { - std::vector tvec; - ReadAttrAsFloatArray(node, "rotation", 4, tvec); - memcpy(rotation, tvec.data(), sizeof(rotation)); - } - if (hasAttribute(node, "scaleOrientation")) { - std::vector tvec; - ReadAttrAsFloatArray(node, "rotation", 4, tvec); - ::memcpy(scale_orientation, tvec.data(), sizeof(scale_orientation)); - } - /*if(an == "rotation") - { - std::vector tvec; - - XML_ReadNode_GetAttrVal_AsArrF(idx, tvec); - if(tvec.size() != 4) throw DeadlyImportError(": rotation vector must have 4 elements."); - - memcpy(rotation, tvec.data(), sizeof(rotation)); - - continue; - } - - if(an == "scaleOrientation"){ - - std::vector tvec; - XML_ReadNode_GetAttrVal_AsArrF(idx, tvec); - if ( tvec.size() != 4 ) - { - throw DeadlyImportError( ": scaleOrientation vector must have 4 elements." ); - } - - ::memcpy(scale_orientation, tvec.data(), sizeof(scale_orientation) ); - - continue; - } - - MACRO_ATTRREAD_LOOPEND;*/ - - // if "USE" defined then find already defined element. - if(!use.empty()) { - X3DNodeElementBase* ne = nullptr; - if (!FindNodeElement(use, X3DNodeElementBase::ENET_Group, &ne)) { - Throw_USE_NotFound(node.name(), use); - } - mNodeElementCur->Child.push_back(ne); - - //MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne); - } - else - { - ParseHelper_Group_Begin();// create new grouping element and go deeper if node has children. - // at this place new group mode created and made current, so we can name it. - if ( !def.empty() ) - { - mNodeElementCur->ID = def; - } - - // - // also set values specific to this type of group - // - // calculate transformation matrix - aiMatrix4x4::Translation(translation, matr);// T - aiMatrix4x4::Translation(center, tmatr);// C - matr *= tmatr; - aiMatrix4x4::Rotation(rotation[3], aiVector3D(rotation[0], rotation[1], rotation[2]), tmatr);// R - matr *= tmatr; - aiMatrix4x4::Rotation(scale_orientation[3], aiVector3D(scale_orientation[0], scale_orientation[1], scale_orientation[2]), tmatr);// SR - matr *= tmatr; - aiMatrix4x4::Scaling(scale, tmatr);// S - matr *= tmatr; - aiMatrix4x4::Rotation(-scale_orientation[3], aiVector3D(scale_orientation[0], scale_orientation[1], scale_orientation[2]), tmatr);// -SR - matr *= tmatr; - aiMatrix4x4::Translation(-center, tmatr);// -C - matr *= tmatr; - // and assign it - ((X3DGroup*)mNodeElementCur)->Transformation = matr; - // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in parser function. - - // for empty element exit from node in that place - if ( node.empty() ) { - ParseHelper_Node_Exit(); - } - }// if(!use.empty()) else -} - -void X3DImporter::ParseNode_Grouping_TransformEnd() -{ - ParseHelper_Node_Exit();// go up in scene graph -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Light.cpp b/code/AssetLib/X3D/X3DImporter_Light.cpp deleted file mode 100644 index d56eb5ecf..000000000 --- a/code/AssetLib/X3D/X3DImporter_Light.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Light.cpp -/// \brief Parsing data from nodes of "Lighting" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" -#include - -namespace Assimp { - -// -void X3DImporter::ParseNode_Lighting_DirectionalLight() -{ - std::string def, use; - float ambientIntensity = 0; - aiColor3D color(1, 1, 1); - aiVector3D direction(0, 0, -1); - bool global = false; - float intensity = 1; - bool on = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsCol3f); - MACRO_ATTRREAD_CHECK_REF("direction", direction, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_RET("global", global, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("intensity", intensity, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("on", on, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_DirectionalLight, ne); - } - else - { - if(on) - { - // create and if needed - define new geometry object. - ne = new X3DLight(X3DNodeElementBase::ENET_DirectionalLight, mNodeElementCur); - if(!def.empty()) - ne->ID = def; - else - ne->ID = "DirectionalLight_" + to_string((size_t)ne);// make random name - - ((X3DLight*)ne)->AmbientIntensity = ambientIntensity; - ((X3DLight*)ne)->Color = color; - ((X3DLight*)ne)->Direction = direction; - ((X3DLight*)ne)->Global = global; - ((X3DLight*)ne)->Intensity = intensity; - // Assimp want a node with name similar to a light. "Why? I don't no." ) - ParseHelper_Group_Begin(false); - - mNodeElementCur->ID = ne->ID;// assign name to node and return to light element. - ParseHelper_Node_Exit(); - // check for child nodes - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "DirectionalLight"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(on) - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Lighting_PointLight() -{ - std::string def, use; - float ambientIntensity = 0; - aiVector3D attenuation( 1, 0, 0 ); - aiColor3D color( 1, 1, 1 ); - bool global = true; - float intensity = 1; - aiVector3D location( 0, 0, 0 ); - bool on = true; - float radius = 100; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("attenuation", attenuation, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsCol3f); - MACRO_ATTRREAD_CHECK_RET("global", global, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("intensity", intensity, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("location", location, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_RET("on", on, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_PointLight, ne); - } - else - { - if(on) - { - // create and if needed - define new geometry object. - ne = new X3DLight(X3DNodeElementBase::ENET_PointLight, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DLight*)ne)->AmbientIntensity = ambientIntensity; - ((X3DLight*)ne)->Attenuation = attenuation; - ((X3DLight*)ne)->Color = color; - ((X3DLight*)ne)->Global = global; - ((X3DLight*)ne)->Intensity = intensity; - ((X3DLight*)ne)->Location = location; - ((X3DLight*)ne)->Radius = radius; - // Assimp want a node with name similar to a light. "Why? I don't no." ) - ParseHelper_Group_Begin(false); - // make random name - if(ne->ID.empty()) ne->ID = "PointLight_" + to_string((size_t)ne); - - mNodeElementCur->ID = ne->ID;// assign name to node and return to light element. - ParseHelper_Node_Exit(); - // check for child nodes - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "PointLight"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(on) - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Lighting_SpotLight() -{ - std::string def, use; - float ambientIntensity = 0; - aiVector3D attenuation( 1, 0, 0 ); - float beamWidth = 0.7854f; - aiColor3D color( 1, 1, 1 ); - float cutOffAngle = 1.570796f; - aiVector3D direction( 0, 0, -1 ); - bool global = true; - float intensity = 1; - aiVector3D location( 0, 0, 0 ); - bool on = true; - float radius = 100; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("attenuation", attenuation, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_RET("beamWidth", beamWidth, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsCol3f); - MACRO_ATTRREAD_CHECK_RET("cutOffAngle", cutOffAngle, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("direction", direction, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_RET("global", global, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("intensity", intensity, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("location", location, XML_ReadNode_GetAttrVal_AsVec3f); - MACRO_ATTRREAD_CHECK_RET("on", on, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_SpotLight, ne); - } - else - { - if(on) - { - // create and if needed - define new geometry object. - ne = new X3DLight(X3DNodeElementBase::ENET_SpotLight, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - if(beamWidth > cutOffAngle) beamWidth = cutOffAngle; - - ((X3DLight*)ne)->AmbientIntensity = ambientIntensity; - ((X3DLight*)ne)->Attenuation = attenuation; - ((X3DLight*)ne)->BeamWidth = beamWidth; - ((X3DLight*)ne)->Color = color; - ((X3DLight*)ne)->CutOffAngle = cutOffAngle; - ((X3DLight*)ne)->Direction = direction; - ((X3DLight*)ne)->Global = global; - ((X3DLight*)ne)->Intensity = intensity; - ((X3DLight*)ne)->Location = location; - ((X3DLight*)ne)->Radius = radius; - - // Assimp want a node with name similar to a light. "Why? I don't no." ) - ParseHelper_Group_Begin(false); - // make random name - if(ne->ID.empty()) ne->ID = "SpotLight_" + to_string((size_t)ne); - - mNodeElementCur->ID = ne->ID;// assign name to node and return to light element. - ParseHelper_Node_Exit(); - // check for child nodes - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "SpotLight"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(on) - }// if(!use.empty()) else -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Macro.hpp b/code/AssetLib/X3D/X3DImporter_Macro.hpp deleted file mode 100644 index 2463c7762..000000000 --- a/code/AssetLib/X3D/X3DImporter_Macro.hpp +++ /dev/null @@ -1,195 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Macro.hpp -/// \brief Useful macrodefines. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef X3DIMPORTER_MACRO_HPP_INCLUDED -#define X3DIMPORTER_MACRO_HPP_INCLUDED - -/// \def MACRO_USE_CHECKANDAPPLY(pDEF, pUSE, pNE) -/// Used for regular checking while attribute "USE" is defined. -/// \param [in] pDEF - string holding "DEF" value. -/// \param [in] pUSE - string holding "USE" value. -/// \param [in] pType - type of element to find. -/// \param [out] pNE - pointer to found node element. -#define MACRO_USE_CHECKANDAPPLY(pDEF, pUSE, pType, pNE) \ - do { \ - XML_CheckNode_MustBeEmpty(); \ - if(!pDEF.empty()) Throw_DEF_And_USE(); \ - if(!FindNodeElement(pUSE, CX3DImporter_NodeElement::pType, &pNE)) Throw_USE_NotFound(pUSE); \ - \ - NodeElement_Cur->Child.push_back(pNE);/* add found object as child to current element */ \ - } while(false) - -/// \def MACRO_ATTRREAD_LOOPBEG -/// Begin of loop that read attributes values. -#define MACRO_ATTRREAD_LOOPBEG \ - for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \ - { \ - std::string an(mReader->getAttributeName(idx)); - -/// \def MACRO_ATTRREAD_LOOPEND -/// End of loop that read attributes values. -#define MACRO_ATTRREAD_LOOPEND \ - Throw_IncorrectAttr(an); \ - } - -/// \def MACRO_ATTRREAD_CHECK_REF -/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then -/// "continue" will called. -/// \param [in] pAttrName - attribute name. -/// \param [out] pVarName - output variable name. -/// \param [in] pFunction - function which read attribute value and write it to pVarName. -#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \ - if(an == pAttrName) \ - { \ - pFunction(idx, pVarName); \ - continue; \ - } - -/// \def MACRO_ATTRREAD_CHECK_RET -/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction. -/// If result was read then "continue" will called. -/// \param [in] pAttrName - attribute name. -/// \param [out] pVarName - output variable name. -/// \param [in] pFunction - function which read attribute value and write it to pVarName. -#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \ - if(an == pAttrName) \ - { \ - pVarName = pFunction(idx); \ - continue; \ - } - -/// \def MACRO_ATTRREAD_CHECKUSEDEF_RET -/// Compact variant for checking "USE" and "DEF". Also skip bbox attributes: "bboxCenter", "bboxSize". -/// If result was read then "continue" will called. -/// \param [out] pDEF_Var - output variable name for "DEF" value. -/// \param [out] pUSE_Var - output variable name for "USE" value. -#define MACRO_ATTRREAD_CHECKUSEDEF_RET(pDEF_Var, pUSE_Var) \ - MACRO_ATTRREAD_CHECK_RET("DEF", pDEF_Var, mReader->getAttributeValue); \ - MACRO_ATTRREAD_CHECK_RET("USE", pUSE_Var, mReader->getAttributeValue); \ - if(an == "bboxCenter") continue; \ - if(an == "bboxSize") continue; \ - if(an == "containerField") continue; \ - do {} while(false) - -/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName) -/// Begin of loop of parsing child nodes. Do not add ';' at end. -/// \param [in] pNodeName - current node name. -#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \ - do { \ - bool close_found = false; \ - \ - while(mReader->read()) \ - { \ - if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \ - { - -/// \def MACRO_NODECHECK_LOOPEND(pNodeName) -/// End of loop of parsing child nodes. -/// \param [in] pNodeName - current node name. -#define MACRO_NODECHECK_LOOPEND(pNodeName) \ - }/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \ - else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \ - { \ - if(XML_CheckNode_NameEqual(pNodeName)) \ - { \ - close_found = true; \ - \ - break; \ - } \ - }/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \ - }/* while(mReader->read()) */ \ - \ - if(!close_found) Throw_CloseNotFound(pNodeName); \ - \ - } while(false) - -#define MACRO_NODECHECK_METADATA(pNodeName) \ - MACRO_NODECHECK_LOOPBEGIN(pNodeName) \ - /* and childs must be metadata nodes */ \ - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported(pNodeName); \ - MACRO_NODECHECK_LOOPEND(pNodeName) - -/// \def MACRO_FACE_ADD_QUAD_FA(pCCW, pOut, pIn, pP1, pP2, pP3, pP4) -/// Add points as quad. Means that pP1..pP4 set in CCW order. -#define MACRO_FACE_ADD_QUAD_FA(pCCW, pOut, pIn, pP1, pP2, pP3, pP4) \ - do { \ - if(pCCW) \ - { \ - pOut.push_back(pIn[pP1]); \ - pOut.push_back(pIn[pP2]); \ - pOut.push_back(pIn[pP3]); \ - pOut.push_back(pIn[pP4]); \ - } \ - else \ - { \ - pOut.push_back(pIn[pP4]); \ - pOut.push_back(pIn[pP3]); \ - pOut.push_back(pIn[pP2]); \ - pOut.push_back(pIn[pP1]); \ - } \ - } while(false) - -/// \def MACRO_FACE_ADD_QUAD(pCCW, pOut, pP1, pP2, pP3, pP4) -/// Add points as quad. Means that pP1..pP4 set in CCW order. -#define MACRO_FACE_ADD_QUAD(pCCW, pOut, pP1, pP2, pP3, pP4) \ - do { \ - if(pCCW) \ - { \ - pOut.push_back(pP1); \ - pOut.push_back(pP2); \ - pOut.push_back(pP3); \ - pOut.push_back(pP4); \ - } \ - else \ - { \ - pOut.push_back(pP4); \ - pOut.push_back(pP3); \ - pOut.push_back(pP2); \ - pOut.push_back(pP1); \ - } \ - } while(false) - -#endif // X3DIMPORTER_MACRO_HPP_INCLUDED diff --git a/code/AssetLib/X3D/X3DImporter_Metadata.cpp b/code/AssetLib/X3D/X3DImporter_Metadata.cpp deleted file mode 100644 index 86916b537..000000000 --- a/code/AssetLib/X3D/X3DImporter_Metadata.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Metadata.cpp -/// \brief Parsing data from nodes of "Metadata" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" - -namespace Assimp -{ - -/// \def MACRO_METADATA_FINDCREATE(pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaName) -/// Find element by "USE" or create new one. -/// \param [in] pDEF_Var - variable name with "DEF" value. -/// \param [in] pUSE_Var - variable name with "USE" value. -/// \param [in] pReference - variable name with "reference" value. -/// \param [in] pValue - variable name with "value" value. -/// \param [in, out] pNE - pointer to node element. -/// \param [in] pMetaClass - Class of node. -/// \param [in] pMetaName - Name of node. -/// \param [in] pType - type of element to find. -#define MACRO_METADATA_FINDCREATE(pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaClass, pMetaName, pType) \ - /* if "USE" defined then find already defined element. */ \ - if(!pUSE_Var.empty()) \ - { \ - MACRO_USE_CHECKANDAPPLY(pDEF_Var, pUSE_Var, pType, pNE); \ - } \ - else \ - { \ - pNE = new pMetaClass(NodeElement_Cur); \ - if(!pDEF_Var.empty()) pNE->ID = pDEF_Var; \ - \ - ((pMetaClass*)pNE)->Reference = pReference; \ - ((pMetaClass*)pNE)->Value = pValue; \ - /* also metadata node can contain childs */ \ - if(!mReader->isEmptyElement()) \ - ParseNode_Metadata(pNE, pMetaName);/* in that case node element will be added to child elements list of current node. */ \ - else \ - NodeElement_Cur->Child.push_back(pNE);/* else - add element to child list manually */ \ - \ - NodeElement_List.push_back(pNE);/* add new element to elements list. */ \ - }/* if(!pUSE_Var.empty()) else */ \ - \ - do {} while(false) - -bool X3DImporter::ParseHelper_CheckRead_X3DMetadataObject() -{ - if(XML_CheckNode_NameEqual("MetadataBoolean")) - ParseNode_MetadataBoolean(); - else if(XML_CheckNode_NameEqual("MetadataDouble")) - ParseNode_MetadataDouble(); - else if(XML_CheckNode_NameEqual("MetadataFloat")) - ParseNode_MetadataFloat(); - else if(XML_CheckNode_NameEqual("MetadataInteger")) - ParseNode_MetadataInteger(); - else if(XML_CheckNode_NameEqual("MetadataSet")) - ParseNode_MetadataSet(); - else if(XML_CheckNode_NameEqual("MetadataString")) - ParseNode_MetadataString(); - else - return false; - - return true; -} - -void X3DImporter::ParseNode_Metadata(X3DNodeElementBase* pParentElement, const std::string& /*pNodeName*/) -{ - ParseHelper_Node_Enter(pParentElement); - MACRO_NODECHECK_METADATA(mReader->getNodeName()); - ParseHelper_Node_Exit(); -} - -// -void X3DImporter::ParseNode_MetadataBoolean() -{ - std::string def, use; - std::string name, reference; - std::vector value; - X3DNodeElementBase* 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_AsArrB); - MACRO_ATTRREAD_LOOPEND; - - MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, X3DMetaBoolean, "MetadataBoolean", ENET_MetaBoolean); -} - -// -void X3DImporter::ParseNode_MetadataDouble() -{ - std::string def, use; - std::string name, reference; - std::vector value; - X3DNodeElementBase* 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_AsArrD); - MACRO_ATTRREAD_LOOPEND; - - MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, X3DMetaDouble, "MetadataDouble", ENET_MetaDouble); -} - -// -void X3DImporter::ParseNode_MetadataFloat() -{ - std::string def, use; - std::string name, reference; - std::vector value; - X3DNodeElementBase* 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_AsArrF); - MACRO_ATTRREAD_LOOPEND; - - MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, X3DMetaFloat, "MetadataFloat", ENET_MetaFloat); -} - -// -void X3DImporter::ParseNode_MetadataInteger() -{ - std::string def, use; - std::string name, reference; - std::vector value; - X3DNodeElementBase* 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_AsArrI32); - MACRO_ATTRREAD_LOOPEND; - - MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, X3DMetaInteger, "MetadataInteger", ENET_MetaInteger); -} - -// -void X3DImporter::ParseNode_MetadataSet() -{ - std::string def, use; - std::string name, reference; - X3DNodeElementBase* 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_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_MetaSet, ne); - } - else - { - ne = new X3DMetaSet(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DMetaSet*)ne)->Reference = reference; - // also metadata node can contain childs - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "MetadataSet"); - else - mNodeElementCur->Child.push_back(ne);// made object as child to current element - - NodeElement_List.push_back(ne);// add new element to elements list. - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_MetadataString() -{ - std::string def, use; - std::string name, reference; - std::list value; - X3DNodeElementBase* 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_AsListS); - MACRO_ATTRREAD_LOOPEND; - - MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, X3DMetaString, "MetadataString", ENET_MetaString); -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Networking.cpp b/code/AssetLib/X3D/X3DImporter_Networking.cpp deleted file mode 100644 index a1428cf86..000000000 --- a/code/AssetLib/X3D/X3DImporter_Networking.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Networking.cpp -/// \brief Parsing data from nodes of "Networking" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" - -// Header files, Assimp. -#include - -//#include - -namespace Assimp -{ - -//static std::regex pattern_parentDir(R"((^|/)[^/]+/../)"); -static std::string parentDir("/../"); - -// -void X3DImporter::ParseNode_Networking_Inline() -{ - std::string def, use; - bool load = true; - std::list url; - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("load", load, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("url", url, XML_ReadNode_GetAttrVal_AsListS); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - X3DNodeElementBase* ne; - - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne); - } - else - { - ParseHelper_Group_Begin(true);// create new grouping element and go deeper if node has children. - // at this place new group mode created and made current, so we can name it. - if(!def.empty()) mNodeElementCur->ID = def; - - if(load && !url.empty()) - { - std::string full_path = mpIOHandler->CurrentDirectory() + url.front(); - - //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)); - ParseFile(full_path, mpIOHandler); - mpIOHandler->PopDirectory(); - } - - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) ParseNode_Metadata(mNodeElementCur, "Inline"); - - // exit from node in that place - ParseHelper_Node_Exit(); - }// if(!use.empty()) else -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Node.hpp b/code/AssetLib/X3D/X3DImporter_Node.hpp deleted file mode 100644 index 340cf449e..000000000 --- a/code/AssetLib/X3D/X3DImporter_Node.hpp +++ /dev/null @@ -1,507 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Node.hpp -/// \brief Elements of scene graph. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef INCLUDED_AI_X3D_IMPORTER_NODE_H -#define INCLUDED_AI_X3D_IMPORTER_NODE_H - -// Header files, Assimp. -#include -#include - -// Header files, stdlib. -#include -#include -#include - -/// Base class for elements of nodes. -class X3DNodeElementBase { -public: - /// Define what data type contain node element. - enum EType { - ENET_Group, ///< Element has type "Group". - ENET_MetaBoolean, ///< Element has type "Metadata boolean". - ENET_MetaDouble, ///< Element has type "Metadata double". - ENET_MetaFloat, ///< Element has type "Metadata float". - ENET_MetaInteger, ///< Element has type "Metadata integer". - ENET_MetaSet, ///< Element has type "Metadata set". - ENET_MetaString, ///< Element has type "Metadata string". - ENET_Arc2D, ///< Element has type "Arc2D". - ENET_ArcClose2D, ///< Element has type "ArcClose2D". - ENET_Circle2D, ///< Element has type "Circle2D". - ENET_Disk2D, ///< Element has type "Disk2D". - ENET_Polyline2D, ///< Element has type "Polyline2D". - ENET_Polypoint2D, ///< Element has type "Polypoint2D". - ENET_Rectangle2D, ///< Element has type "Rectangle2D". - ENET_TriangleSet2D, ///< Element has type "TriangleSet2D". - ENET_Box, ///< Element has type "Box". - ENET_Cone, ///< Element has type "Cone". - ENET_Cylinder, ///< Element has type "Cylinder". - ENET_Sphere, ///< Element has type "Sphere". - ENET_ElevationGrid, ///< Element has type "ElevationGrid". - ENET_Extrusion, ///< Element has type "Extrusion". - ENET_Coordinate, ///< Element has type "Coordinate". - ENET_Normal, ///< Element has type "Normal". - ENET_TextureCoordinate, ///< Element has type "TextureCoordinate". - ENET_IndexedFaceSet, ///< Element has type "IndexedFaceSet". - ENET_IndexedLineSet, ///< Element has type "IndexedLineSet". - ENET_IndexedTriangleSet, ///< Element has type "IndexedTriangleSet". - ENET_IndexedTriangleFanSet, ///< Element has type "IndexedTriangleFanSet". - ENET_IndexedTriangleStripSet, ///< Element has type "IndexedTriangleStripSet". - ENET_LineSet, ///< Element has type "LineSet". - ENET_PointSet, ///< Element has type "PointSet". - ENET_TriangleSet, ///< Element has type "TriangleSet". - ENET_TriangleFanSet, ///< Element has type "TriangleFanSet". - ENET_TriangleStripSet, ///< Element has type "TriangleStripSet". - ENET_Color, ///< Element has type "Color". - ENET_ColorRGBA, ///< Element has type "ColorRGBA". - ENET_Shape, ///< Element has type "Shape". - ENET_Appearance, ///< Element has type "Appearance". - ENET_Material, ///< Element has type "Material". - ENET_ImageTexture, ///< Element has type "ImageTexture". - ENET_TextureTransform, ///< Element has type "TextureTransform". - ENET_DirectionalLight, ///< Element has type "DirectionalLight". - ENET_PointLight, ///< Element has type "PointLight". - ENET_SpotLight, ///< Element has type "SpotLight". - - ENET_Invalid ///< Element has invalid type and possible contain invalid data. - }; - - const EType Type; - - std::string ID; ///< ID of the element. Can be empty. In X3D synonym for "ID" attribute. - X3DNodeElementBase *Parent; ///< Parent element. If nullptr then this node is root. - std::list Child; ///< Child elements. - - /// @brief The destructor, virtual. - virtual ~X3DNodeElementBase() { - // empty - } - -protected: - /// In constructor inheritor must set element type. - /// \param [in] pType - element type. - /// \param [in] pParent - parent element. - X3DNodeElementBase(const EType pType, X3DNodeElementBase *pParent) : - Type(pType), Parent(pParent) {} - - X3DNodeElementBase(const X3DNodeElementBase &pNodeElement) = delete; - X3DNodeElementBase &operator=(const X3DNodeElementBase &pNodeElement) = delete; - X3DNodeElementBase() = delete; -}; // class IX3DImporter_NodeElement - -/// \class CX3DImporter_NodeElement_Group -/// Class that define grouping node. Define transformation matrix for children. -/// Also can select which child will be kept and others are removed. -class X3DGroup : public X3DNodeElementBase { -public: - aiMatrix4x4 Transformation; ///< Transformation matrix. - - /// \var bool Static - /// As you know node elements can use already defined node elements when attribute "USE" is defined. - /// Standard search when looking for an element in the whole scene graph, existing at this moment. - /// If a node is marked as static, the children(or lower) can not search for elements in the nodes upper then static. - bool Static; - - bool UseChoice; ///< Flag: if true then use number from \ref Choice to choose what the child will be kept. - int32_t Choice; ///< Number of the child which will be kept. - -public: - /// Constructor. - /// \param [in] pParent - pointer to parent node. - /// \param [in] pStatic - static node flag. - X3DGroup(X3DNodeElementBase *pParent, const bool pStatic = false) : - X3DNodeElementBase(ENET_Group, pParent), - Static(pStatic), - UseChoice(false) { - // empty - } -}; // class CX3DImporter_NodeElement_Group - -/// This struct describe meta-value. -class X3DMeta : public X3DNodeElementBase { -public: - std::string Name; ///< Name of metadata object. - - /// If provided, it identifies the metadata standard or other specification that defines the name field. If the reference field is not provided or is - /// empty, the meaning of the name field is considered implicit to the characters in the string. - std::string Reference; - - /// In constructor inheritor must set element type. - /// \param [in] pType - element type. - /// \param [in] pParent - pointer to parent node. - X3DMeta(const EType pType, X3DNodeElementBase *pParent) : - X3DNodeElementBase(pType, pParent) {} -}; // class CX3DImporter_NodeElement_Meta - -/// \struct CX3DImporter_NodeElement_MetaBoolean -/// This struct describe metavalue of type boolean. -struct X3DMetaBoolean : public X3DMeta { - std::vector Value; ///< Stored value. - - /// \fn CX3DImporter_NodeElement_MetaBoolean(CX3DImporter_NodeElement* pParent) - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DMetaBoolean(X3DNodeElementBase *pParent) : - X3DMeta(ENET_MetaBoolean, pParent) {} - -}; // struct CX3DImporter_NodeElement_MetaBoolean - -/// \struct CX3DImporter_NodeElement_MetaDouble -/// This struct describe metavalue of type double. -struct X3DMetaDouble : public X3DMeta { - std::vector Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DMetaDouble(X3DNodeElementBase *pParent) : - X3DMeta(ENET_MetaDouble, pParent) {} - -}; // struct CX3DImporter_NodeElement_MetaDouble - -/// This struct describe metavalue of type float. -struct X3DMetaFloat : public X3DMeta { - std::vector Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DMetaFloat(X3DNodeElementBase *pParent) : - X3DMeta(ENET_MetaFloat, pParent) {} - -}; // struct CX3DImporter_NodeElement_MetaFloat - -/// This struct describe metavalue of type integer. -struct X3DMetaInteger : public X3DMeta { - std::vector Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DMetaInteger(X3DNodeElementBase *pParent) : - X3DMeta(ENET_MetaInteger, pParent) {} - -}; // struct CX3DImporter_NodeElement_MetaInteger - -/// This struct describe container for metaobjects. -struct X3DMetaSet : public X3DMeta { - std::list Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DMetaSet(X3DNodeElementBase *pParent) : - X3DMeta(ENET_MetaSet, pParent) {} - -}; // struct CX3DImporter_NodeElement_MetaSet - -/// This struct describe metavalue of type string. -struct X3DMetaString : public X3DMeta { - std::list Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DMetaString(X3DNodeElementBase *pParent) : - X3DMeta(ENET_MetaString, pParent) {} - -}; // struct CX3DImporter_NodeElement_MetaString - -/// This struct hold value. -struct X3DColor : public X3DNodeElementBase { - std::list Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DColor(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_Color, pParent) {} - -}; // struct CX3DImporter_NodeElement_Color - -/// This struct hold value. -struct X3DColorRGBA : public X3DNodeElementBase { - std::list Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DColorRGBA(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_ColorRGBA, pParent) {} - -}; // struct CX3DImporter_NodeElement_ColorRGBA - -/// This struct hold value. -struct X3DCoordinate : public X3DNodeElementBase { - std::list Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DCoordinate(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_Coordinate, pParent) {} - -}; // struct CX3DImporter_NodeElement_Coordinate - -/// This struct hold value. -struct X3DNormal : public X3DNodeElementBase { - std::list Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DNormal(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_Normal, pParent) {} - -}; // struct CX3DImporter_NodeElement_Normal - -/// This struct hold value. -struct X3DTextureCoordinate : public X3DNodeElementBase { - std::list Value; ///< Stored value. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DTextureCoordinate(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_TextureCoordinate, pParent) {} - -}; // struct CX3DImporter_NodeElement_TextureCoordinate - -/// Two-dimensional figure. -class X3DGeometry2D : public X3DNodeElementBase { -public: - std::list Vertices; ///< Vertices list. - size_t NumIndices; ///< Number of indices in one face. - bool Solid; ///< Flag: if true then render must use back-face culling, else render must draw both sides of object. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - /// \param [in] pType - type of geometry object. - X3DGeometry2D(const EType pType, X3DNodeElementBase *pParent) : - X3DNodeElementBase(pType, pParent), Solid(true) {} - -}; // class CX3DImporter_NodeElement_Geometry2D - -/// Three-dimensional body. -class X3DGeometry3D : public X3DNodeElementBase { -public: - std::list Vertices; ///< Vertices list. - size_t NumIndices; ///< Number of indices in one face. - bool Solid; ///< Flag: if true then render must use back-face culling, else render must draw both sides of object. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - /// \param [in] pType - type of geometry object. - X3DGeometry3D(const EType pType, X3DNodeElementBase *pParent) : - X3DNodeElementBase(pType, pParent), Vertices(), NumIndices(0), Solid(true) { - // empty - } -}; // class CX3DImporter_NodeElement_Geometry3D - -/// \class CX3DImporter_NodeElement_ElevationGrid -/// Uniform rectangular grid of varying height. -class X3DElevationGrid : public X3DGeometry3D { -public: - bool NormalPerVertex; ///< If true then normals are defined for every vertex, else for every face(line). - bool ColorPerVertex; ///< If true then colors are defined for every vertex, else for every face(line). - /// 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::vector CoordIdx; ///< Coordinates list by faces. In X3D format: "-1" - delimiter for faces. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - /// \param [in] pType - type of geometry object. - X3DElevationGrid(const EType pType, X3DNodeElementBase *pParent) : - X3DGeometry3D(pType, pParent) {} - -}; // class CX3DImporter_NodeElement_IndexedSet - -/// Shape with indexed vertices. -class X3DIndexedSet : public X3DGeometry3D { -public: - /// The ccw field defines the ordering of the vertex coordinates of the geometry with respect to user-given or automatically generated normal vectors - /// used in the lighting model equations. If ccw is TRUE, the normals shall follow the right hand rule; the orientation of each normal with respect to - /// the vertices (taken in order) shall be such that the vertices appear to be oriented in a counterclockwise order when the vertices are viewed (in the - /// local coordinate system of the Shape) from the opposite direction as the normal. If ccw is FALSE, the normals shall be oriented in the opposite - /// 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::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). - /// 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::vector CoordIndex; ///< Field to specify the polygonal faces by indexing into the . - /// 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::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::vector TexCoordIndex; ///< Field to specify the polygonal faces by indexing into the . - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - /// \param [in] pType - type of geometry object. - X3DIndexedSet(const EType pType, X3DNodeElementBase *pParent) : - X3DGeometry3D(pType, pParent) {} - -}; // class CX3DImporter_NodeElement_IndexedSet - -/// Shape with set of vertices. -class X3DSet : public X3DGeometry3D { -public: - /// The ccw field defines the ordering of the vertex coordinates of the geometry with respect to user-given or automatically generated normal vectors - /// used in the lighting model equations. If ccw is TRUE, the normals shall follow the right hand rule; the orientation of each normal with respect to - /// the vertices (taken in order) shall be such that the vertices appear to be oriented in a counterclockwise order when the vertices are viewed (in the - /// local coordinate system of the Shape) from the opposite direction as the normal. If ccw is FALSE, the normals shall be oriented in the opposite - /// 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; - 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::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. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - /// \param [in] pType - type of geometry object. - X3DSet(const EType pType, X3DNodeElementBase *pParent) : - X3DGeometry3D(pType, pParent) {} - -}; // class CX3DImporter_NodeElement_Set - -/// This struct hold value. -struct X3DShape : public X3DNodeElementBase { - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DShape(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_Shape, pParent) {} - -}; // struct CX3DImporter_NodeElement_Shape - -/// This struct hold value. -struct X3DAppearance : public X3DNodeElementBase { - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DAppearance(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_Appearance, pParent) {} - -}; // struct CX3DImporter_NodeElement_Appearance - -/// Material. -class X3DMaterial : public X3DNodeElementBase { -public: - float AmbientIntensity; ///< Specifies how much ambient light from light sources this surface shall reflect. - aiColor3D DiffuseColor; ///< Reflects all X3D light sources depending on the angle of the surface with respect to the light source. - aiColor3D EmissiveColor; ///< Models "glowing" objects. This can be useful for displaying pre-lit models. - float Shininess; ///< Lower shininess values produce soft glows, while higher values result in sharper, smaller highlights. - aiColor3D SpecularColor; ///< The specularColor and shininess fields determine the specular highlights. - float Transparency; ///< Specifies how "clear" an object is, with 1.0 being completely transparent, and 0.0 completely opaque. - - /// Constructor. - /// \param [in] pParent - pointer to parent node. - /// \param [in] pType - type of geometry object. - X3DMaterial(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_Material, pParent), - AmbientIntensity(0.0f), - DiffuseColor(), - EmissiveColor(), - Shininess(0.0f), - SpecularColor(), - Transparency(1.0f) { - // empty - } -}; // class CX3DImporter_NodeElement_Material - -/// This struct hold value. -struct X3DImageTexture : public X3DNodeElementBase { - /// RepeatS and RepeatT, that specify how the texture wraps in the S and T directions. If repeatS is TRUE (the default), the texture map is repeated - /// outside the [0.0, 1.0] texture coordinate range in the S direction so that it fills the shape. If repeatS is FALSE, the texture coordinates are - /// clamped in the S direction to lie within the [0.0, 1.0] range. The repeatT field is analogous to the repeatS field. - bool RepeatS; - bool RepeatT; ///< See \ref RepeatS. - std::string URL; ///< URL of the texture. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DImageTexture(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_ImageTexture, pParent) {} -}; // struct CX3DImporter_NodeElement_ImageTexture - -/// This struct hold value. -struct X3DTextureTransform : public X3DNodeElementBase { - aiVector2D Center; ///< Specifies a translation offset in texture coordinate space about which the rotation and scale fields are applied. - float Rotation; ///< Specifies a rotation in angle base units of the texture coordinates about the center point after the scale has been applied. - aiVector2D Scale; ///< Specifies a scaling factor in S and T of the texture coordinates about the center point. - aiVector2D Translation; ///< Specifies a translation of the texture coordinates. - - /// Constructor - /// \param [in] pParent - pointer to parent node. - X3DTextureTransform(X3DNodeElementBase *pParent) : - X3DNodeElementBase(ENET_TextureTransform, pParent) {} - -}; // struct CX3DImporter_NodeElement_TextureTransform - -/// This struct hold value. -struct X3DLight : public X3DNodeElementBase { - float AmbientIntensity; ///< Specifies the intensity of the ambient emission from the light. - aiColor3D Color; ///< specifies the spectral colour properties of both the direct and ambient light emission as an RGB value. - aiVector3D Direction; ///< Specifies the direction vector of the illumination emanating from the light source in the local coordinate system. - /// Field that determines whether the light is global or scoped. Global lights illuminate all objects that fall within their volume of lighting influence. - /// Scoped lights only illuminate objects that are in the same transformation hierarchy as the light. - bool Global; - float Intensity; ///< Specifies the brightness of the direct emission from the light. - - /// PointLight node's illumination falls off with distance as specified by three attenuation coefficients. The attenuation factor - /// is: "1 / max(attenuation[0] + attenuation[1] * r + attenuation[2] * r2, 1)", where r is the distance from the light to the surface being illuminated. - aiVector3D Attenuation; - aiVector3D Location; ///< Specifies a translation offset of the centre point of the light source from the light's local coordinate system origin. - float Radius; ///< Specifies the radial extent of the solid angle and the maximum distance from location that may be illuminated by the light source. - float BeamWidth; ///< Specifies an inner solid angle in which the light source emits light at uniform full intensity. - float CutOffAngle; ///< The light source's emission intensity drops off from the inner solid angle (beamWidth) to the outer solid angle (cutOffAngle). - - /// Constructor - /// \param [in] pParent - pointer to parent node. - /// \param [in] pLightType - type of the light source. - X3DLight(EType pLightType, X3DNodeElementBase *pParent) : - X3DNodeElementBase(pLightType, pParent) {} - -}; // struct CX3DImporter_NodeElement_Light - -#endif // INCLUDED_AI_X3D_IMPORTER_NODE_H diff --git a/code/AssetLib/X3D/X3DImporter_Postprocess.cpp b/code/AssetLib/X3D/X3DImporter_Postprocess.cpp deleted file mode 100644 index 3bb581d91..000000000 --- a/code/AssetLib/X3D/X3DImporter_Postprocess.cpp +++ /dev/null @@ -1,829 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Postprocess.cpp -/// \brief Convert built scenegraph and objects to Assimp scenegraph. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" - -// Header files, Assimp. -#include -#include -#include - -// Header files, stdlib. -#include -#include -#include - -namespace Assimp -{ - -aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const -{ - X3DNodeElementBase* cur_node; - std::list matr; - aiMatrix4x4 out_matr; - - // starting walk from current element to root - cur_node = mNodeElementCur; - if(cur_node != nullptr) - { - do - { - // if cur_node is group then store group transformation matrix in list. - if(cur_node->Type == X3DNodeElementBase::ENET_Group) matr.push_back(((X3DGroup*)cur_node)->Transformation); - - cur_node = cur_node->Parent; - } while(cur_node != nullptr); - } - - // multiplicate all matrices in reverse order - for(std::list::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit); - - return out_matr; -} - -void X3DImporter::PostprocessHelper_CollectMetadata(const X3DNodeElementBase& pNodeElement, std::list& pList) const -{ - // walk through childs and find for metadata. - for(std::list::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it) - { - if(((*el_it)->Type == X3DNodeElementBase::ENET_MetaBoolean) || ((*el_it)->Type == X3DNodeElementBase::ENET_MetaDouble) || - ((*el_it)->Type == X3DNodeElementBase::ENET_MetaFloat) || ((*el_it)->Type == X3DNodeElementBase::ENET_MetaInteger) || - ((*el_it)->Type == X3DNodeElementBase::ENET_MetaString)) - { - pList.push_back(*el_it); - } - else if((*el_it)->Type == X3DNodeElementBase::ENET_MetaSet) - { - PostprocessHelper_CollectMetadata(**el_it, pList); - } - }// for(std::list::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) -} - -bool X3DImporter::PostprocessHelper_ElementIsMetadata(const X3DNodeElementBase::EType pType) const -{ - if((pType == X3DNodeElementBase::ENET_MetaBoolean) || (pType == X3DNodeElementBase::ENET_MetaDouble) || - (pType == X3DNodeElementBase::ENET_MetaFloat) || (pType == X3DNodeElementBase::ENET_MetaInteger) || - (pType == X3DNodeElementBase::ENET_MetaString) || (pType == X3DNodeElementBase::ENET_MetaSet)) - { - return true; - } - else - { - return false; - } -} - -bool X3DImporter::PostprocessHelper_ElementIsMesh(const X3DNodeElementBase::EType pType) const -{ - if((pType == X3DNodeElementBase::ENET_Arc2D) || (pType == X3DNodeElementBase::ENET_ArcClose2D) || - (pType == X3DNodeElementBase::ENET_Box) || (pType == X3DNodeElementBase::ENET_Circle2D) || - (pType == X3DNodeElementBase::ENET_Cone) || (pType == X3DNodeElementBase::ENET_Cylinder) || - (pType == X3DNodeElementBase::ENET_Disk2D) || (pType == X3DNodeElementBase::ENET_ElevationGrid) || - (pType == X3DNodeElementBase::ENET_Extrusion) || (pType == X3DNodeElementBase::ENET_IndexedFaceSet) || - (pType == X3DNodeElementBase::ENET_IndexedLineSet) || (pType == X3DNodeElementBase::ENET_IndexedTriangleFanSet) || - (pType == X3DNodeElementBase::ENET_IndexedTriangleSet) || (pType == X3DNodeElementBase::ENET_IndexedTriangleStripSet) || - (pType == X3DNodeElementBase::ENET_PointSet) || (pType == X3DNodeElementBase::ENET_LineSet) || - (pType == X3DNodeElementBase::ENET_Polyline2D) || (pType == X3DNodeElementBase::ENET_Polypoint2D) || - (pType == X3DNodeElementBase::ENET_Rectangle2D) || (pType == X3DNodeElementBase::ENET_Sphere) || - (pType == X3DNodeElementBase::ENET_TriangleFanSet) || (pType == X3DNodeElementBase::ENET_TriangleSet) || - (pType == X3DNodeElementBase::ENET_TriangleSet2D) || (pType == X3DNodeElementBase::ENET_TriangleStripSet)) - { - return true; - } - else - { - return false; - } -} - -void X3DImporter::Postprocess_BuildLight(const X3DNodeElementBase& pNodeElement, std::list& pSceneLightList) const -{ - const X3DLight& ne = *( ( X3DLight* ) &pNodeElement ); - aiMatrix4x4 transform_matr = PostprocessHelper_Matrix_GlobalToCurrent(); - aiLight* new_light = new aiLight; - - new_light->mName = ne.ID; - new_light->mColorAmbient = ne.Color * ne.AmbientIntensity; - new_light->mColorDiffuse = ne.Color * ne.Intensity; - new_light->mColorSpecular = ne.Color * ne.Intensity; - switch(pNodeElement.Type) - { - case X3DNodeElementBase::ENET_DirectionalLight: - new_light->mType = aiLightSource_DIRECTIONAL; - new_light->mDirection = ne.Direction, new_light->mDirection *= transform_matr; - - break; - case X3DNodeElementBase::ENET_PointLight: - new_light->mType = aiLightSource_POINT; - new_light->mPosition = ne.Location, new_light->mPosition *= transform_matr; - new_light->mAttenuationConstant = ne.Attenuation.x; - new_light->mAttenuationLinear = ne.Attenuation.y; - new_light->mAttenuationQuadratic = ne.Attenuation.z; - - break; - case X3DNodeElementBase::ENET_SpotLight: - new_light->mType = aiLightSource_SPOT; - new_light->mPosition = ne.Location, new_light->mPosition *= transform_matr; - new_light->mDirection = ne.Direction, new_light->mDirection *= transform_matr; - new_light->mAttenuationConstant = ne.Attenuation.x; - new_light->mAttenuationLinear = ne.Attenuation.y; - new_light->mAttenuationQuadratic = ne.Attenuation.z; - new_light->mAngleInnerCone = ne.BeamWidth; - new_light->mAngleOuterCone = ne.CutOffAngle; - - break; - default: - throw DeadlyImportError("Postprocess_BuildLight. Unknown type of light: " + to_string(pNodeElement.Type) + "."); - } - - pSceneLightList.push_back(new_light); -} - -void X3DImporter::Postprocess_BuildMaterial(const X3DNodeElementBase& pNodeElement, aiMaterial** pMaterial) const -{ - // check argument - if(pMaterial == nullptr) throw DeadlyImportError("Postprocess_BuildMaterial. pMaterial is nullptr."); - if(*pMaterial != nullptr) throw DeadlyImportError("Postprocess_BuildMaterial. *pMaterial must be nullptr."); - - *pMaterial = new aiMaterial; - aiMaterial& taimat = **pMaterial;// creating alias for convenience. - - // at this point pNodeElement point to node. Walk through childs and add all stored data. - for(std::list::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it) - { - if((*el_it)->Type == X3DNodeElementBase::ENET_Material) - { - aiColor3D tcol3; - float tvalf; - X3DMaterial& tnemat = *((X3DMaterial*)*el_it); - - tcol3.r = tnemat.AmbientIntensity, tcol3.g = tnemat.AmbientIntensity, tcol3.b = tnemat.AmbientIntensity; - taimat.AddProperty(&tcol3, 1, AI_MATKEY_COLOR_AMBIENT); - taimat.AddProperty(&tnemat.DiffuseColor, 1, AI_MATKEY_COLOR_DIFFUSE); - taimat.AddProperty(&tnemat.EmissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE); - taimat.AddProperty(&tnemat.SpecularColor, 1, AI_MATKEY_COLOR_SPECULAR); - tvalf = 1; - taimat.AddProperty(&tvalf, 1, AI_MATKEY_SHININESS_STRENGTH); - taimat.AddProperty(&tnemat.Shininess, 1, AI_MATKEY_SHININESS); - tvalf = 1.0f - tnemat.Transparency; - taimat.AddProperty(&tvalf, 1, AI_MATKEY_OPACITY); - }// if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material) - else if((*el_it)->Type == X3DNodeElementBase::ENET_ImageTexture) - { - X3DImageTexture& tnetex = *((X3DImageTexture*)*el_it); - aiString url_str(tnetex.URL.c_str()); - int mode = aiTextureOp_Multiply; - - taimat.AddProperty(&url_str, AI_MATKEY_TEXTURE_DIFFUSE(0)); - taimat.AddProperty(&tnetex.RepeatS, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0)); - taimat.AddProperty(&tnetex.RepeatT, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0)); - taimat.AddProperty(&mode, 1, AI_MATKEY_TEXOP_DIFFUSE(0)); - }// else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_ImageTexture) - else if((*el_it)->Type == X3DNodeElementBase::ENET_TextureTransform) - { - aiUVTransform trans; - X3DTextureTransform& tnetextr = *((X3DTextureTransform*)*el_it); - - trans.mTranslation = tnetextr.Translation - tnetextr.Center; - trans.mScaling = tnetextr.Scale; - trans.mRotation = tnetextr.Rotation; - taimat.AddProperty(&trans, 1, AI_MATKEY_UVTRANSFORM_DIFFUSE(0)); - }// else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_TextureTransform) - }// for(std::list::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) -} - -void X3DImporter::Postprocess_BuildMesh(const X3DNodeElementBase& pNodeElement, aiMesh** pMesh) const -{ - // check argument - if(pMesh == nullptr) throw DeadlyImportError("Postprocess_BuildMesh. pMesh is nullptr."); - if(*pMesh != nullptr) throw DeadlyImportError("Postprocess_BuildMesh. *pMesh must be nullptr."); - - /************************************************************************************************************************************/ - /************************************************************ Geometry2D ************************************************************/ - /************************************************************************************************************************************/ - if((pNodeElement.Type == X3DNodeElementBase::ENET_Arc2D) || (pNodeElement.Type == X3DNodeElementBase::ENET_ArcClose2D) || - (pNodeElement.Type == X3DNodeElementBase::ENET_Circle2D) || (pNodeElement.Type == X3DNodeElementBase::ENET_Disk2D) || - (pNodeElement.Type == X3DNodeElementBase::ENET_Polyline2D) || (pNodeElement.Type == X3DNodeElementBase::ENET_Polypoint2D) || - (pNodeElement.Type == X3DNodeElementBase::ENET_Rectangle2D) || (pNodeElement.Type == X3DNodeElementBase::ENET_TriangleSet2D)) - { - X3DGeometry2D& tnemesh = *((X3DGeometry2D*)&pNodeElement);// create alias for convenience - std::vector tarr; - - tarr.reserve(tnemesh.Vertices.size()); - for(std::list::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it); - *pMesh = StandardShapes::MakeMesh(tarr, static_cast(tnemesh.NumIndices));// create mesh from vertices using Assimp help. - - return;// mesh is build, nothing to do anymore. - } - /************************************************************************************************************************************/ - /************************************************************ Geometry3D ************************************************************/ - /************************************************************************************************************************************/ - // - // Predefined figures - // - if((pNodeElement.Type == X3DNodeElementBase::ENET_Box) || (pNodeElement.Type == X3DNodeElementBase::ENET_Cone) || - (pNodeElement.Type == X3DNodeElementBase::ENET_Cylinder) || (pNodeElement.Type == X3DNodeElementBase::ENET_Sphere)) - { - X3DGeometry3D& tnemesh = *((X3DGeometry3D*)&pNodeElement);// create alias for convenience - std::vector tarr; - - tarr.reserve(tnemesh.Vertices.size()); - for(std::list::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it); - - *pMesh = StandardShapes::MakeMesh(tarr, static_cast(tnemesh.NumIndices));// create mesh from vertices using Assimp help. - - return;// mesh is build, nothing to do anymore. - } - // - // Parametric figures - // - if(pNodeElement.Type == X3DNodeElementBase::ENET_ElevationGrid) - { - X3DElevationGrid& tnemesh = *((X3DElevationGrid*)&pNodeElement);// create alias for convenience - - // at first create mesh from existing vertices. - *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIdx, tnemesh.Vertices); - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, ((X3DColor*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, ((X3DColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Normal) - MeshGeometry_AddNormal(**pMesh, ((X3DNormal*)*ch_it)->Value, tnemesh.NormalPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_TextureCoordinate) - MeshGeometry_AddTexCoord(**pMesh, ((X3DTextureCoordinate*)*ch_it)->Value); - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid) - // - // Indexed primitives sets - // - if(pNodeElement.Type == X3DNodeElementBase::ENET_IndexedFaceSet) - { - X3DIndexedSet& tnemesh = *((X3DIndexedSet*)&pNodeElement);// create alias for convenience - - // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - { - *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((X3DCoordinate*)*ch_it)->Value); - } - } - - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((X3DColor*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((X3DColorRGBA*)*ch_it)->Value, - tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - {} // skip because already read when mesh created. - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Normal) - MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((X3DNormal*)*ch_it)->Value, - tnemesh.NormalPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_TextureCoordinate) - MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((X3DTextureCoordinate*)*ch_it)->Value); - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet) - - if(pNodeElement.Type == X3DNodeElementBase::ENET_IndexedLineSet) - { - X3DIndexedSet& tnemesh = *((X3DIndexedSet*)&pNodeElement);// create alias for convenience - - // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - { - *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((X3DCoordinate*)*ch_it)->Value); - } - } - - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - ai_assert(*pMesh); - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((X3DColor*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((X3DColorRGBA*)*ch_it)->Value, - tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - {} // skip because already read when mesh created. - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet) - - if((pNodeElement.Type == X3DNodeElementBase::ENET_IndexedTriangleSet) || - (pNodeElement.Type == X3DNodeElementBase::ENET_IndexedTriangleFanSet) || - (pNodeElement.Type == X3DNodeElementBase::ENET_IndexedTriangleStripSet)) - { - X3DIndexedSet& tnemesh = *((X3DIndexedSet*)&pNodeElement);// create alias for convenience - - // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - { - *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((X3DCoordinate*)*ch_it)->Value); - } - } - - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - ai_assert(*pMesh); - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((X3DColor*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((X3DColorRGBA*)*ch_it)->Value, - tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - {} // skip because already read when mesh created. - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Normal) - MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((X3DNormal*)*ch_it)->Value, - tnemesh.NormalPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_TextureCoordinate) - MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((X3DTextureCoordinate*)*ch_it)->Value); - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \ - IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet)) - - if(pNodeElement.Type == X3DNodeElementBase::ENET_Extrusion) - { - X3DIndexedSet& tnemesh = *((X3DIndexedSet*)&pNodeElement);// create alias for convenience - - *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, tnemesh.Vertices); - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Extrusion) - - // - // Primitives sets - // - if(pNodeElement.Type == X3DNodeElementBase::ENET_PointSet) - { - X3DSet& tnemesh = *((X3DSet*)&pNodeElement);// create alias for convenience - - // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - { - std::vector vec_copy; - - vec_copy.reserve(((X3DCoordinate*)*ch_it)->Value.size()); - for(std::list::const_iterator it = ((X3DCoordinate*)*ch_it)->Value.begin(); - it != ((X3DCoordinate*)*ch_it)->Value.end(); ++it) - { - vec_copy.push_back(*it); - } - - *pMesh = StandardShapes::MakeMesh(vec_copy, 1); - } - } - - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - ai_assert(*pMesh); - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, ((X3DColor*)*ch_it)->Value, true); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, ((X3DColorRGBA*)*ch_it)->Value, true); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - {} // skip because already read when mesh created. - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet) - - if(pNodeElement.Type == X3DNodeElementBase::ENET_LineSet) - { - X3DSet& tnemesh = *((X3DSet*)&pNodeElement);// create alias for convenience - - // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - { - *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((X3DCoordinate*)*ch_it)->Value); - } - } - - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - ai_assert(*pMesh); - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, ((X3DColor*)*ch_it)->Value, true); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, ((X3DColorRGBA*)*ch_it)->Value, true); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - {} // skip because already read when mesh created. - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet) - - if(pNodeElement.Type == X3DNodeElementBase::ENET_TriangleFanSet) - { - X3DSet& tnemesh = *((X3DSet*)&pNodeElement);// create alias for convenience - - // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - { - *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((X3DCoordinate*)*ch_it)->Value); - } - } - - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if ( nullptr == *pMesh ) { - break; - } - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, ((X3DColor*)*ch_it)->Value,tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, ((X3DColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - {} // skip because already read when mesh created. - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Normal) - MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((X3DNormal*)*ch_it)->Value, - tnemesh.NormalPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_TextureCoordinate) - MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((X3DTextureCoordinate*)*ch_it)->Value); - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet) - - if(pNodeElement.Type == X3DNodeElementBase::ENET_TriangleSet) - { - X3DSet& tnemesh = *((X3DSet*)&pNodeElement);// create alias for convenience - - // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - { - std::vector vec_copy; - - vec_copy.reserve(((X3DCoordinate*)*ch_it)->Value.size()); - for(std::list::const_iterator it = ((X3DCoordinate*)*ch_it)->Value.begin(); - it != ((X3DCoordinate*)*ch_it)->Value.end(); ++it) - { - vec_copy.push_back(*it); - } - - *pMesh = StandardShapes::MakeMesh(vec_copy, 3); - } - } - - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - ai_assert(*pMesh); - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, ((X3DColor*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, ((X3DColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - {} // skip because already read when mesh created. - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Normal) - MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((X3DNormal*)*ch_it)->Value, - tnemesh.NormalPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_TextureCoordinate) - MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((X3DTextureCoordinate*)*ch_it)->Value); - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet) - - if(pNodeElement.Type == X3DNodeElementBase::ENET_TriangleStripSet) - { - X3DSet& tnemesh = *((X3DSet*)&pNodeElement);// create alias for convenience - - // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - { - *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((X3DCoordinate*)*ch_it)->Value); - } - } - - // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - { - ai_assert(*pMesh); - if((*ch_it)->Type == X3DNodeElementBase::ENET_Color) - MeshGeometry_AddColor(**pMesh, ((X3DColor*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_ColorRGBA) - MeshGeometry_AddColor(**pMesh, ((X3DColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Coordinate) - {} // skip because already read when mesh created. - else if((*ch_it)->Type == X3DNodeElementBase::ENET_Normal) - MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((X3DNormal*)*ch_it)->Value, - tnemesh.NormalPerVertex); - else if((*ch_it)->Type == X3DNodeElementBase::ENET_TextureCoordinate) - MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((X3DTextureCoordinate*)*ch_it)->Value); - else - throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + "."); - }// for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) - - return;// mesh is build, nothing to do anymore. - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet) - - throw DeadlyImportError("Postprocess_BuildMesh. Unknown mesh type: " + to_string(pNodeElement.Type) + "."); -} - -void X3DImporter::Postprocess_BuildNode(const X3DNodeElementBase& pNodeElement, aiNode& pSceneNode, std::list& pSceneMeshList, - std::list& pSceneMaterialList, std::list& pSceneLightList) const -{ - std::list::const_iterator chit_begin = pNodeElement.Child.begin(); - std::list::const_iterator chit_end = pNodeElement.Child.end(); - std::list SceneNode_Child; - std::list SceneNode_Mesh; - - // At first read all metadata - Postprocess_CollectMetadata(pNodeElement, pSceneNode); - // check if we have deal with grouping node. Which can contain transformation or switch - if(pNodeElement.Type == X3DNodeElementBase::ENET_Group) - { - const X3DGroup& tne_group = *((X3DGroup*)&pNodeElement);// create alias for convenience - - pSceneNode.mTransformation = tne_group.Transformation; - if(tne_group.UseChoice) - { - // If Choice is less than zero or greater than the number of nodes in the children field, nothing is chosen. - if((tne_group.Choice < 0) || ((size_t)tne_group.Choice >= pNodeElement.Child.size())) - { - chit_begin = pNodeElement.Child.end(); - chit_end = pNodeElement.Child.end(); - } - else - { - for(size_t i = 0; i < (size_t)tne_group.Choice; i++) ++chit_begin;// forward iterator to chosen node. - - chit_end = chit_begin; - ++chit_end;// point end iterator to next element after chosen node. - } - }// if(tne_group.UseChoice) - }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group) - - // Reserve memory for fast access and check children. - for(std::list::const_iterator it = chit_begin; it != chit_end; ++it) - {// in this loop we do not read metadata because it's already read at begin. - if((*it)->Type == X3DNodeElementBase::ENET_Group) - { - // if child is group then create new node and do recursive call. - aiNode* new_node = new aiNode; - - new_node->mName = (*it)->ID; - new_node->mParent = &pSceneNode; - SceneNode_Child.push_back(new_node); - Postprocess_BuildNode(**it, *new_node, pSceneMeshList, pSceneMaterialList, pSceneLightList); - } - else if((*it)->Type == X3DNodeElementBase::ENET_Shape) - { - // shape can contain only one geometry and one appearance nodes. - Postprocess_BuildShape(*((X3DShape*)*it), SceneNode_Mesh, pSceneMeshList, pSceneMaterialList); - } - else if(((*it)->Type == X3DNodeElementBase::ENET_DirectionalLight) || ((*it)->Type == X3DNodeElementBase::ENET_PointLight) || - ((*it)->Type == X3DNodeElementBase::ENET_SpotLight)) - { - Postprocess_BuildLight(*((X3DLight*)*it), pSceneLightList); - } - else if(!PostprocessHelper_ElementIsMetadata((*it)->Type))// skip metadata - { - throw DeadlyImportError("Postprocess_BuildNode. Unknown type: " + to_string((*it)->Type) + "."); - } - }// for(std::list::const_iterator it = chit_begin; it != chit_end; it++) - - // copy data about children and meshes to aiNode. - if(!SceneNode_Child.empty()) - { - std::list::const_iterator it = SceneNode_Child.begin(); - - pSceneNode.mNumChildren = static_cast(SceneNode_Child.size()); - pSceneNode.mChildren = new aiNode*[pSceneNode.mNumChildren]; - for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++; - } - - if(!SceneNode_Mesh.empty()) - { - std::list::const_iterator it = SceneNode_Mesh.begin(); - - pSceneNode.mNumMeshes = static_cast(SceneNode_Mesh.size()); - pSceneNode.mMeshes = new unsigned int[pSceneNode.mNumMeshes]; - for(size_t i = 0; i < pSceneNode.mNumMeshes; i++) pSceneNode.mMeshes[i] = *it++; - } - - // that's all. return to previous deals -} - -void X3DImporter::Postprocess_BuildShape(const X3DShape& pShapeNodeElement, std::list& pNodeMeshInd, - std::list& pSceneMeshList, std::list& pSceneMaterialList) const -{ - aiMaterial* tmat = nullptr; - aiMesh* tmesh = nullptr; - X3DNodeElementBase::EType mesh_type = X3DNodeElementBase::ENET_Invalid; - unsigned int mat_ind = 0; - - for(std::list::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); ++it) - { - if(PostprocessHelper_ElementIsMesh((*it)->Type)) - { - Postprocess_BuildMesh(**it, &tmesh); - if(tmesh != nullptr) - { - // if mesh successfully built then add data about it to arrays - pNodeMeshInd.push_back(static_cast(pSceneMeshList.size())); - pSceneMeshList.push_back(tmesh); - // keep mesh type. Need above for texture coordinate generation. - mesh_type = (*it)->Type; - } - } - else if((*it)->Type == X3DNodeElementBase::ENET_Appearance) - { - Postprocess_BuildMaterial(**it, &tmat); - if(tmat != nullptr) - { - // if material successfully built then add data about it to array - mat_ind = static_cast(pSceneMaterialList.size()); - pSceneMaterialList.push_back(tmat); - } - } - }// for(std::list::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++) - - // associate read material with read mesh. - if((tmesh != nullptr) && (tmat != nullptr)) - { - tmesh->mMaterialIndex = mat_ind; - // Check texture mapping. If material has texture but mesh has no texture coordinate then try to ask Assimp to generate texture coordinates. - if((tmat->GetTextureCount(aiTextureType_DIFFUSE) != 0) && !tmesh->HasTextureCoords(0)) - { - int32_t tm; - aiVector3D tvec3; - - switch(mesh_type) - { - case X3DNodeElementBase::ENET_Box: - tm = aiTextureMapping_BOX; - break; - case X3DNodeElementBase::ENET_Cone: - case X3DNodeElementBase::ENET_Cylinder: - tm = aiTextureMapping_CYLINDER; - break; - case X3DNodeElementBase::ENET_Sphere: - tm = aiTextureMapping_SPHERE; - break; - default: - tm = aiTextureMapping_PLANE; - break; - }// switch(mesh_type) - - tmat->AddProperty(&tm, 1, AI_MATKEY_MAPPING_DIFFUSE(0)); - }// if((tmat->GetTextureCount(aiTextureType_DIFFUSE) != 0) && !tmesh->HasTextureCoords(0)) - }// if((tmesh != nullptr) && (tmat != nullptr)) -} - -void X3DImporter::Postprocess_CollectMetadata(const X3DNodeElementBase& pNodeElement, aiNode& pSceneNode) const -{ - std::list meta_list; - size_t meta_idx; - - PostprocessHelper_CollectMetadata(pNodeElement, meta_list);// find metadata in current node element. - if ( !meta_list.empty() ) - { - if ( pSceneNode.mMetaData != nullptr ) { - throw DeadlyImportError( "Postprocess. MetaData member in node are not nullptr. Something went wrong." ); - } - - // copy collected metadata to output node. - pSceneNode.mMetaData = aiMetadata::Alloc( static_cast(meta_list.size()) ); - meta_idx = 0; - for(std::list::const_iterator it = meta_list.begin(); it != meta_list.end(); ++it, ++meta_idx) - { - X3DMeta* cur_meta = (X3DMeta*)*it; - - // due to limitations we can add only first element of value list. - // Add an element according to its type. - if((*it)->Type == X3DNodeElementBase::ENET_MetaBoolean) - { - if(((X3DMetaBoolean*)cur_meta)->Value.size() > 0) { - const bool v = (bool) *( ( (X3DMetaBoolean*) cur_meta )->Value.begin()); - pSceneNode.mMetaData->Set(static_cast(meta_idx), cur_meta->Name, v); - } - } - else if((*it)->Type == X3DNodeElementBase::ENET_MetaDouble) - { - if(((X3DMetaDouble*)cur_meta)->Value.size() > 0) - pSceneNode.mMetaData->Set(static_cast(meta_idx), cur_meta->Name, (float)*(((X3DMetaDouble*)cur_meta)->Value.begin())); - } - else if((*it)->Type == X3DNodeElementBase::ENET_MetaFloat) - { - if(((X3DMetaFloat*)cur_meta)->Value.size() > 0) - pSceneNode.mMetaData->Set(static_cast(meta_idx), cur_meta->Name, *(((X3DMetaFloat*)cur_meta)->Value.begin())); - } - else if((*it)->Type == X3DNodeElementBase::ENET_MetaInteger) - { - if(((X3DMetaInteger*)cur_meta)->Value.size() > 0) - pSceneNode.mMetaData->Set(static_cast(meta_idx), cur_meta->Name, *(((X3DMetaInteger*)cur_meta)->Value.begin())); - } - else if((*it)->Type == X3DNodeElementBase::ENET_MetaString) - { - if(((X3DMetaString*)cur_meta)->Value.size() > 0) - { - aiString tstr(((X3DMetaString*)cur_meta)->Value.begin()->data()); - - pSceneNode.mMetaData->Set(static_cast(meta_idx), cur_meta->Name, tstr); - } - } - else - { - throw DeadlyImportError("Postprocess. Unknown metadata type."); - }// if((*it)->Type == CX3DImporter_NodeElement::ENET_Meta*) else - }// for(std::list::const_iterator it = meta_list.begin(); it != meta_list.end(); it++) - }// if( !meta_list.empty() ) -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Rendering.cpp b/code/AssetLib/X3D/X3DImporter_Rendering.cpp deleted file mode 100644 index 6b3f2fd34..000000000 --- a/code/AssetLib/X3D/X3DImporter_Rendering.cpp +++ /dev/null @@ -1,1071 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Rendering.cpp -/// \brief Parsing data from nodes of "Rendering" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" - -namespace Assimp -{ - -// -void X3DImporter::ParseNode_Rendering_Color() -{ - std::string use, def; - std::list color; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsListCol3f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Color, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DColor(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DColor*)ne)->Value = color; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Color"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Rendering_ColorRGBA() -{ - std::string use, def; - std::list color; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsListCol4f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_ColorRGBA, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DColorRGBA(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DColorRGBA*)ne)->Value = color; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "ColorRGBA"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Rendering_Coordinate() -{ - std::string use, def; - std::list point; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("point", point, XML_ReadNode_GetAttrVal_AsListVec3f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Coordinate, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DCoordinate(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DCoordinate*)ne)->Value = point; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Coordinate"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can -// contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_IndexedLineSet() -{ - std::string use, def; - std::vector colorIndex; - bool colorPerVertex = true; - std::vector coordIndex; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - 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_AsArrI32); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedLineSet, ne); - } - else - { - // check data - if((coordIndex.size() < 2) || ((coordIndex.back() == (-1)) && (coordIndex.size() < 3))) - throw DeadlyImportError("IndexedLineSet must contain not empty \"coordIndex\" attribute."); - - // create and if needed - define new geometry object. - ne = new X3DIndexedSet(X3DNodeElementBase::ENET_IndexedLineSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DIndexedSet& ne_alias = *((X3DIndexedSet*)ne); - - ne_alias.ColorIndex = colorIndex; - ne_alias.ColorPerVertex = colorPerVertex; - ne_alias.CoordIndex = coordIndex; - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("IndexedLineSet"); - // check for Color and Coordinate nodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedLineSet"); - - MACRO_NODECHECK_LOOPEND("IndexedLineSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate, -// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute, -// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet() -{ - std::string use, def; - bool ccw = true; - bool colorPerVertex = true; - std::vector index; - bool normalPerVertex = true; - bool solid = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - 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_AsArrI32); - MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleFanSet, ne); - } - else - { - // check data - if(index.size() == 0) throw DeadlyImportError("IndexedTriangleFanSet must contain not empty \"index\" attribute."); - - // create and if needed - define new geometry object. - ne = new X3DIndexedSet(X3DNodeElementBase::ENET_IndexedTriangleFanSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DIndexedSet& ne_alias = *((X3DIndexedSet*)ne); - - ne_alias.CCW = ccw; - ne_alias.ColorPerVertex = colorPerVertex; - ne_alias.NormalPerVertex = normalPerVertex; - ne_alias.Solid = solid; - - ne_alias.CoordIndex.clear(); - int counter = 0; - int32_t idx[3]; - for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it) - { - idx[2] = *idx_it; - if (idx[2] < 0) - { - counter = 0; - } - else - { - if (counter >= 2) - { - if(ccw) - { - ne_alias.CoordIndex.push_back(idx[0]); - ne_alias.CoordIndex.push_back(idx[1]); - ne_alias.CoordIndex.push_back(idx[2]); - } - else - { - ne_alias.CoordIndex.push_back(idx[0]); - ne_alias.CoordIndex.push_back(idx[2]); - ne_alias.CoordIndex.push_back(idx[1]); - } - ne_alias.CoordIndex.push_back(-1); - idx[1] = idx[2]; - } - else - { - idx[counter] = idx[2]; - } - ++counter; - } - }// for(std::list::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++) - - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleFanSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; } - if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleFanSet"); - - MACRO_NODECHECK_LOOPEND("IndexedTriangleFanSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate, -// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute, -// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_IndexedTriangleSet() -{ - std::string use, def; - bool ccw = true; - bool colorPerVertex = true; - std::vector index; - bool normalPerVertex = true; - bool solid = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - 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_AsArrI32); - MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleSet, ne); - } - else - { - // check data - if(index.size() == 0) throw DeadlyImportError("IndexedTriangleSet must contain not empty \"index\" attribute."); - - // create and if needed - define new geometry object. - ne = new X3DIndexedSet(X3DNodeElementBase::ENET_IndexedTriangleSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DIndexedSet& ne_alias = *((X3DIndexedSet*)ne); - - ne_alias.CCW = ccw; - ne_alias.ColorPerVertex = colorPerVertex; - ne_alias.NormalPerVertex = normalPerVertex; - ne_alias.Solid = solid; - - ne_alias.CoordIndex.clear(); - int counter = 0; - int32_t idx[3]; - for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it) - { - idx[counter++] = *idx_it; - if (counter > 2) - { - counter = 0; - if(ccw) - { - ne_alias.CoordIndex.push_back(idx[0]); - ne_alias.CoordIndex.push_back(idx[1]); - ne_alias.CoordIndex.push_back(idx[2]); - } - else - { - ne_alias.CoordIndex.push_back(idx[0]); - ne_alias.CoordIndex.push_back(idx[2]); - ne_alias.CoordIndex.push_back(idx[1]); - } - ne_alias.CoordIndex.push_back(-1); - } - }// for(std::list::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++) - - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; } - if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleSet"); - - MACRO_NODECHECK_LOOPEND("IndexedTriangleSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate, -// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute, -// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet() -{ - std::string use, def; - bool ccw = true; - bool colorPerVertex = true; - std::vector index; - bool normalPerVertex = true; - bool solid = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - 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_AsArrI32); - MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleStripSet, ne); - } - else - { - // check data - if(index.size() == 0) throw DeadlyImportError("IndexedTriangleStripSet must contain not empty \"index\" attribute."); - - // create and if needed - define new geometry object. - ne = new X3DIndexedSet(X3DNodeElementBase::ENET_IndexedTriangleStripSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DIndexedSet& ne_alias = *((X3DIndexedSet*)ne); - - ne_alias.CCW = ccw; - ne_alias.ColorPerVertex = colorPerVertex; - ne_alias.NormalPerVertex = normalPerVertex; - ne_alias.Solid = solid; - - ne_alias.CoordIndex.clear(); - int counter = 0; - int32_t idx[3]; - for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it) - { - idx[2] = *idx_it; - if (idx[2] < 0) - { - counter = 0; - } - else - { - if (counter >= 2) - { - if(ccw) - { - ne_alias.CoordIndex.push_back(idx[0]); - ne_alias.CoordIndex.push_back(idx[1]); - ne_alias.CoordIndex.push_back(idx[2]); - } - else - { - ne_alias.CoordIndex.push_back(idx[0]); - ne_alias.CoordIndex.push_back(idx[2]); - ne_alias.CoordIndex.push_back(idx[1]); - } - ne_alias.CoordIndex.push_back(-1); - } - idx[counter & 1] = idx[2]; - ++counter; - } - }// for(std::list::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++) - - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleStripSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; } - if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleStripSet"); - - MACRO_NODECHECK_LOOPEND("IndexedTriangleStripSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can -// contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_LineSet() -{ - std::string use, def; - std::vector vertexCount; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("vertexCount", vertexCount, XML_ReadNode_GetAttrVal_AsArrI32); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_LineSet, ne); - } - else - { - // check data - if(vertexCount.size() == 0) throw DeadlyImportError("LineSet must contain not empty \"vertexCount\" attribute."); - - // create and if needed - define new geometry object. - ne = new X3DSet(X3DNodeElementBase::ENET_LineSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DSet& ne_alias = *((X3DSet*)ne); - - ne_alias.VertexCount = vertexCount; - // create CoordIdx - size_t coord_num = 0; - - ne_alias.CoordIndex.clear(); - 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."); - - for(int32_t i = 0; i < *vc_it; i++) ne_alias.CoordIndex.push_back(static_cast(coord_num++));// add vertices indices - - ne_alias.CoordIndex.push_back(-1);// add face delimiter. - } - - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("LineSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("LineSet"); - - MACRO_NODECHECK_LOOPEND("LineSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can -// contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_PointSet() -{ - std::string use, def; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_PointSet, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DIndexedSet(X3DNodeElementBase::ENET_PointSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("PointSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("PointSet"); - - MACRO_NODECHECK_LOOPEND("PointSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate, -// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute, -// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_TriangleFanSet() -{ - std::string use, def; - bool ccw = true; - bool colorPerVertex = true; - std::vector fanCount; - bool normalPerVertex = true; - bool solid = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - 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_AsArrI32); - MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleFanSet, ne); - } - else - { - // check data - if(fanCount.size() == 0) throw DeadlyImportError("TriangleFanSet must contain not empty \"fanCount\" attribute."); - - // create and if needed - define new geometry object. - ne = new X3DSet(X3DNodeElementBase::ENET_TriangleFanSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DSet& ne_alias = *((X3DSet*)ne); - - ne_alias.CCW = ccw; - ne_alias.ColorPerVertex = colorPerVertex; - ne_alias.VertexCount = fanCount; - ne_alias.NormalPerVertex = normalPerVertex; - ne_alias.Solid = solid; - // create CoordIdx - size_t coord_num_first, coord_num_prev; - - ne_alias.CoordIndex.clear(); - // assign indices for first triangle - coord_num_first = 0; - coord_num_prev = 1; - 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."); - - for(int32_t vc = 2; vc < *vc_it; vc++) - { - if(ccw) - { - // 2 1 - // 0 - ne_alias.CoordIndex.push_back(static_cast(coord_num_first));// first vertex is a center and always is [0]. - ne_alias.CoordIndex.push_back(static_cast(coord_num_prev++)); - ne_alias.CoordIndex.push_back(static_cast(coord_num_prev)); - } - else - { - // 1 2 - // 0 - ne_alias.CoordIndex.push_back(static_cast(coord_num_first));// first vertex is a center and always is [0]. - ne_alias.CoordIndex.push_back(static_cast(coord_num_prev + 1)); - ne_alias.CoordIndex.push_back(static_cast(coord_num_prev++)); - }// if(ccw) else - - ne_alias.CoordIndex.push_back(-1);// add face delimiter. - }// for(int32_t vc = 2; vc < *vc_it; vc++) - - coord_num_prev++;// that index will be center of next fan - coord_num_first = coord_num_prev++;// forward to next point - second point of fan - }// for(std::list::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("TriangleFanSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; } - if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleFanSet"); - - MACRO_NODECHECK_LOOPEND("TriangleFanSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate, -// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute, -// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_TriangleSet() -{ - std::string use, def; - bool ccw = true; - bool colorPerVertex = true; - bool normalPerVertex = true; - bool solid = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - 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_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleSet, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DIndexedSet(X3DNodeElementBase::ENET_TriangleSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DSet& ne_alias = *((X3DSet*)ne); - - ne_alias.CCW = ccw; - ne_alias.ColorPerVertex = colorPerVertex; - ne_alias.NormalPerVertex = normalPerVertex; - ne_alias.Solid = solid; - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("TriangleSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; } - if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleSet"); - - MACRO_NODECHECK_LOOPEND("TriangleSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate, -// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute, -// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. -// -void X3DImporter::ParseNode_Rendering_TriangleStripSet() -{ - std::string use, def; - bool ccw = true; - bool colorPerVertex = true; - std::vector stripCount; - bool normalPerVertex = true; - bool solid = true; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - 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_AsArrI32); - MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleStripSet, ne); - } - else - { - // check data - if(stripCount.size() == 0) throw DeadlyImportError("TriangleStripSet must contain not empty \"stripCount\" attribute."); - - // create and if needed - define new geometry object. - ne = new X3DSet(X3DNodeElementBase::ENET_TriangleStripSet, mNodeElementCur); - if(!def.empty()) ne->ID = def; - - X3DSet& ne_alias = *((X3DSet*)ne); - - ne_alias.CCW = ccw; - ne_alias.ColorPerVertex = colorPerVertex; - ne_alias.VertexCount = stripCount; - ne_alias.NormalPerVertex = normalPerVertex; - ne_alias.Solid = solid; - // create CoordIdx - size_t coord_num0, coord_num1, coord_num2;// indices of current triangle - bool odd_tri;// sequence of current triangle - size_t coord_num_sb;// index of first point of strip - - ne_alias.CoordIndex.clear(); - coord_num_sb = 0; - 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."); - - // set initial values for first triangle - coord_num0 = coord_num_sb; - coord_num1 = coord_num_sb + 1; - coord_num2 = coord_num_sb + 2; - odd_tri = true; - - for(int32_t vc = 2; vc < *vc_it; vc++) - { - if(ccw) - { - // 0 2 - // 1 - ne_alias.CoordIndex.push_back(static_cast(coord_num0)); - ne_alias.CoordIndex.push_back(static_cast(coord_num1)); - ne_alias.CoordIndex.push_back(static_cast(coord_num2)); - } - else - { - // 0 1 - // 2 - ne_alias.CoordIndex.push_back(static_cast(coord_num0)); - ne_alias.CoordIndex.push_back(static_cast(coord_num2)); - ne_alias.CoordIndex.push_back(static_cast(coord_num1)); - }// if(ccw) else - - ne_alias.CoordIndex.push_back(-1);// add face delimiter. - // prepare values for next triangle - if(odd_tri) - { - coord_num0 = coord_num2; - coord_num2++; - } - else - { - coord_num1 = coord_num2; - coord_num2 = coord_num1 + 1; - } - - odd_tri = !odd_tri; - coord_num_sb = coord_num2;// that index will be start of next strip - }// for(int32_t vc = 2; vc < *vc_it; vc++) - }// for(std::list::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("TriangleStripSet"); - // check for X3DComposedGeometryNodes - if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; } - if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; } - if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; } - if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; } - if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleStripSet"); - - MACRO_NODECHECK_LOOPEND("TriangleStripSet"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Rendering_Normal() -{ -std::string use, def; -std::list vector; -X3DNodeElementBase* ne; - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("vector", vector, XML_ReadNode_GetAttrVal_AsListVec3f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Normal, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DNormal(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DNormal*)ne)->Value = vector; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Normal"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Shape.cpp b/code/AssetLib/X3D/X3DImporter_Shape.cpp deleted file mode 100644 index 0572da1e5..000000000 --- a/code/AssetLib/X3D/X3DImporter_Shape.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Shape.cpp -/// \brief Parsing data from nodes of "Shape" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" - -namespace Assimp -{ - -// -// -// "ShapeChildContentModel is the child-node content model corresponding to X3DShapeNode. ShapeChildContentModel can contain a single Appearance node and a -// single geometry node, in any order. -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model." -// -// A Shape node is unlit if either of the following is true: -// The shape's appearance field is nullptr (default). -// The material field in the Appearance node is nullptr (default). -// NOTE Geometry nodes that represent lines or points do not support lighting. -void X3DImporter::ParseNode_Shape_Shape() -{ - std::string use, def; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Shape, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DShape(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("Shape"); - // check for appearance node - if(XML_CheckNode_NameEqual("Appearance")) { ParseNode_Shape_Appearance(); continue; } - // check for X3DGeometryNodes - if(XML_CheckNode_NameEqual("Arc2D")) { ParseNode_Geometry2D_Arc2D(); continue; } - if(XML_CheckNode_NameEqual("ArcClose2D")) { ParseNode_Geometry2D_ArcClose2D(); continue; } - if(XML_CheckNode_NameEqual("Circle2D")) { ParseNode_Geometry2D_Circle2D(); continue; } - if(XML_CheckNode_NameEqual("Disk2D")) { ParseNode_Geometry2D_Disk2D(); continue; } - if(XML_CheckNode_NameEqual("Polyline2D")) { ParseNode_Geometry2D_Polyline2D(); continue; } - if(XML_CheckNode_NameEqual("Polypoint2D")) { ParseNode_Geometry2D_Polypoint2D(); continue; } - if(XML_CheckNode_NameEqual("Rectangle2D")) { ParseNode_Geometry2D_Rectangle2D(); continue; } - if(XML_CheckNode_NameEqual("TriangleSet2D")) { ParseNode_Geometry2D_TriangleSet2D(); continue; } - if(XML_CheckNode_NameEqual("Box")) { ParseNode_Geometry3D_Box(); continue; } - if(XML_CheckNode_NameEqual("Cone")) { ParseNode_Geometry3D_Cone(); continue; } - if(XML_CheckNode_NameEqual("Cylinder")) { ParseNode_Geometry3D_Cylinder(); continue; } - if(XML_CheckNode_NameEqual("ElevationGrid")) { ParseNode_Geometry3D_ElevationGrid(); continue; } - if(XML_CheckNode_NameEqual("Extrusion")) { ParseNode_Geometry3D_Extrusion(); continue; } - if(XML_CheckNode_NameEqual("IndexedFaceSet")) { ParseNode_Geometry3D_IndexedFaceSet(); continue; } - if(XML_CheckNode_NameEqual("Sphere")) { ParseNode_Geometry3D_Sphere(); continue; } - if(XML_CheckNode_NameEqual("IndexedLineSet")) { ParseNode_Rendering_IndexedLineSet(); continue; } - if(XML_CheckNode_NameEqual("LineSet")) { ParseNode_Rendering_LineSet(); continue; } - if(XML_CheckNode_NameEqual("PointSet")) { ParseNode_Rendering_PointSet(); continue; } - if(XML_CheckNode_NameEqual("IndexedTriangleFanSet")) { ParseNode_Rendering_IndexedTriangleFanSet(); continue; } - if(XML_CheckNode_NameEqual("IndexedTriangleSet")) { ParseNode_Rendering_IndexedTriangleSet(); continue; } - if(XML_CheckNode_NameEqual("IndexedTriangleStripSet")) { ParseNode_Rendering_IndexedTriangleStripSet(); continue; } - if(XML_CheckNode_NameEqual("TriangleFanSet")) { ParseNode_Rendering_TriangleFanSet(); continue; } - if(XML_CheckNode_NameEqual("TriangleSet")) { ParseNode_Rendering_TriangleSet(); continue; } - if(XML_CheckNode_NameEqual("TriangleStripSet")) { ParseNode_Rendering_TriangleStripSet(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Shape"); - - MACRO_NODECHECK_LOOPEND("Shape"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -// -// "Child-node content model corresponding to X3DAppearanceChildNode. Appearance can contain FillProperties, LineProperties, Material, any Texture node and -// any TextureTransform node, in any order. No more than one instance of these nodes is allowed. Appearance may also contain multiple shaders (ComposedShader, -// PackagedShader, ProgramShader). -// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model." -// -void X3DImporter::ParseNode_Shape_Appearance() -{ - std::string use, def; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Appearance, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DAppearance(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - // check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("Appearance"); - if(XML_CheckNode_NameEqual("Material")) { ParseNode_Shape_Material(); continue; } - if(XML_CheckNode_NameEqual("ImageTexture")) { ParseNode_Texturing_ImageTexture(); continue; } - if(XML_CheckNode_NameEqual("TextureTransform")) { ParseNode_Texturing_TextureTransform(); continue; } - // check for X3DMetadataObject - if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Appearance"); - - MACRO_NODECHECK_LOOPEND("Appearance"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - } - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Shape_Material() -{ - std::string use, def; - float ambientIntensity = 0.2f; - float shininess = 0.2f; - float transparency = 0; - aiColor3D diffuseColor(0.8f, 0.8f, 0.8f); - aiColor3D emissiveColor(0, 0, 0); - aiColor3D specularColor(0, 0, 0); - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("shininess", shininess, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_RET("transparency", transparency, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("diffuseColor", diffuseColor, XML_ReadNode_GetAttrVal_AsCol3f); - MACRO_ATTRREAD_CHECK_REF("emissiveColor", emissiveColor, XML_ReadNode_GetAttrVal_AsCol3f); - MACRO_ATTRREAD_CHECK_REF("specularColor", specularColor, XML_ReadNode_GetAttrVal_AsCol3f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_Material, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DMaterial(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DMaterial*)ne)->AmbientIntensity = ambientIntensity; - ((X3DMaterial*)ne)->Shininess = shininess; - ((X3DMaterial*)ne)->Transparency = transparency; - ((X3DMaterial*)ne)->DiffuseColor = diffuseColor; - ((X3DMaterial*)ne)->EmissiveColor = emissiveColor; - ((X3DMaterial*)ne)->SpecularColor = specularColor; - // check for child nodes - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "Material"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DImporter_Texturing.cpp b/code/AssetLib/X3D/X3DImporter_Texturing.cpp deleted file mode 100644 index 99fb78c1d..000000000 --- a/code/AssetLib/X3D/X3DImporter_Texturing.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 X3DImporter_Texturing.cpp -/// \brief Parsing data from nodes of "Texturing" set of X3D. -/// \date 2015-2016 -/// \author smal.root@gmail.com - -#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER - -#include "X3DImporter.hpp" -#include "X3DImporter_Macro.hpp" - -namespace Assimp -{ - -// -// When the url field contains no values ([]), texturing is disabled. -void X3DImporter::ParseNode_Texturing_ImageTexture() -{ - std::string use, def; - bool repeatS = true; - bool repeatT = true; - std::list url; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_RET("repeatS", repeatS, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_RET("repeatT", repeatT, XML_ReadNode_GetAttrVal_AsBool); - MACRO_ATTRREAD_CHECK_REF("url", url, XML_ReadNode_GetAttrVal_AsListS); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_ImageTexture, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DImageTexture(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DImageTexture*)ne)->RepeatS = repeatS; - ((X3DImageTexture*)ne)->RepeatT = repeatT; - // Attribute "url" can contain list of strings. But we need only one - first. - if(!url.empty()) - ((X3DImageTexture*)ne)->URL = url.front(); - else - ((X3DImageTexture*)ne)->URL = ""; - - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "ImageTexture"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Texturing_TextureCoordinate() -{ - std::string use, def; - std::list point; - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("point", point, XML_ReadNode_GetAttrVal_AsListVec2f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_TextureCoordinate, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DTextureCoordinate(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DTextureCoordinate*)ne)->Value = point; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "TextureCoordinate"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -// -void X3DImporter::ParseNode_Texturing_TextureTransform() -{ - std::string use, def; - aiVector2D center(0, 0); - float rotation = 0; - aiVector2D scale(1, 1); - aiVector2D translation(0, 0); - X3DNodeElementBase* ne( nullptr ); - - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); - MACRO_ATTRREAD_CHECK_REF("center", center, XML_ReadNode_GetAttrVal_AsVec2f); - MACRO_ATTRREAD_CHECK_RET("rotation", rotation, XML_ReadNode_GetAttrVal_AsFloat); - MACRO_ATTRREAD_CHECK_REF("scale", scale, XML_ReadNode_GetAttrVal_AsVec2f); - MACRO_ATTRREAD_CHECK_REF("translation", translation, XML_ReadNode_GetAttrVal_AsVec2f); - MACRO_ATTRREAD_LOOPEND; - - // if "USE" defined then find already defined element. - if(!use.empty()) - { - MACRO_USE_CHECKANDAPPLY(def, use, ENET_TextureTransform, ne); - } - else - { - // create and if needed - define new geometry object. - ne = new X3DTextureTransform(mNodeElementCur); - if(!def.empty()) ne->ID = def; - - ((X3DTextureTransform*)ne)->Center = center; - ((X3DTextureTransform*)ne)->Rotation = rotation; - ((X3DTextureTransform*)ne)->Scale = scale; - ((X3DTextureTransform*)ne)->Translation = translation; - // check for X3DMetadataObject childs. - if(!mReader->isEmptyElement()) - ParseNode_Metadata(ne, "TextureTransform"); - else - mNodeElementCur->Child.push_back(ne);// add made object as child to current element - - NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph - }// if(!use.empty()) else -} - -}// namespace Assimp - -#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER diff --git a/code/AssetLib/X3D/X3DVocabulary.cpp b/code/AssetLib/X3D/X3DVocabulary.cpp deleted file mode 100644 index 7a251e540..000000000 --- a/code/AssetLib/X3D/X3DVocabulary.cpp +++ /dev/null @@ -1,1677 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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" - -#include - -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 diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 77f111209..0c889a94d 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -800,21 +800,6 @@ ADD_ASSIMP_IMPORTER( X ADD_ASSIMP_IMPORTER( X3D AssetLib/X3D/X3DImporter.cpp AssetLib/X3D/X3DImporter.hpp - AssetLib/X3D/X3DImporter_Geometry2D.cpp - AssetLib/X3D/X3DImporter_Geometry3D.cpp - AssetLib/X3D/X3DImporter_Group.cpp - AssetLib/X3D/X3DImporter_Light.cpp - AssetLib/X3D/X3DImporter_Macro.hpp - AssetLib/X3D/X3DImporter_Metadata.cpp - AssetLib/X3D/X3DImporter_Networking.cpp - AssetLib/X3D/X3DImporter_Node.hpp - AssetLib/X3D/X3DImporter_Postprocess.cpp - AssetLib/X3D/X3DImporter_Rendering.cpp - AssetLib/X3D/X3DImporter_Shape.cpp - AssetLib/X3D/X3DImporter_Texturing.cpp - #AssetLib/X3D/FIReader.hpp - #AssetLib/X3D/FIReader.cpp - #AssetLib/X3D/X3DVocabulary.cpp ) ADD_ASSIMP_IMPORTER( GLTF diff --git a/include/assimp/ParsingUtils.h b/include/assimp/ParsingUtils.h index 28c2f0e76..8fb795c84 100644 --- a/include/assimp/ParsingUtils.h +++ b/include/assimp/ParsingUtils.h @@ -39,7 +39,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ - /** @file ParsingUtils.h * @brief Defines helper functions for text parsing */ @@ -48,12 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_PARSING_UTILS_H_INC #ifdef __GNUC__ -# pragma GCC system_header +#pragma GCC system_header #endif #include #include #include +#include namespace Assimp { @@ -71,57 +71,53 @@ static const unsigned int BufferSize = 4096; // --------------------------------------------------------------------------------- template AI_FORCE_INLINE -char_t ToLower( char_t in ) { - return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in; + char_t + ToLower(char_t in) { + return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in + 0x20) : in; } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE -char_t ToUpper( char_t in) { - return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in; + char_t + ToUpper(char_t in) { + return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in - 0x20) : in; } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool IsUpper( char_t in) { +AI_FORCE_INLINE bool IsUpper(char_t in) { return (in >= (char_t)'A' && in <= (char_t)'Z'); } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool IsLower( char_t in) { +AI_FORCE_INLINE bool IsLower(char_t in) { return (in >= (char_t)'a' && in <= (char_t)'z'); } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool IsSpace( char_t in) { +AI_FORCE_INLINE bool IsSpace(char_t in) { return (in == (char_t)' ' || in == (char_t)'\t'); } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool IsLineEnd( char_t in) { - return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f'); +AI_FORCE_INLINE bool IsLineEnd(char_t in) { + return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0' || in == (char_t)'\f'); } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool IsSpaceOrNewLine( char_t in) { +AI_FORCE_INLINE bool IsSpaceOrNewLine(char_t in) { return IsSpace(in) || IsLineEnd(in); } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool SkipSpaces( const char_t* in, const char_t** out) { - while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) { +AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out) { + while (*in == (char_t)' ' || *in == (char_t)'\t') { ++in; } *out = in; @@ -130,21 +126,19 @@ bool SkipSpaces( const char_t* in, const char_t** out) { // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool SkipSpaces( const char_t** inout) { - return SkipSpaces(*inout,inout); +AI_FORCE_INLINE bool SkipSpaces(const char_t **inout) { + return SkipSpaces(*inout, inout); } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool SkipLine( const char_t* in, const char_t** out) { - while( *in != ( char_t )'\r' && *in != ( char_t )'\n' && *in != ( char_t )'\0' ) { +AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out) { + while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0') { ++in; } // files are opened in binary mode. Ergo there are both NL and CR - while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { + while (*in == (char_t)'\r' || *in == (char_t)'\n') { ++in; } *out = in; @@ -153,16 +147,14 @@ bool SkipLine( const char_t* in, const char_t** out) { // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool SkipLine( const char_t** inout) { - return SkipLine(*inout,inout); +AI_FORCE_INLINE bool SkipLine(const char_t **inout) { + return SkipLine(*inout, inout); } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) { - while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { +AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out) { + while (*in == (char_t)' ' || *in == (char_t)'\t' || *in == (char_t)'\r' || *in == (char_t)'\n') { ++in; } *out = in; @@ -171,27 +163,25 @@ bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) { // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool SkipSpacesAndLineEnd( const char_t** inout) { - return SkipSpacesAndLineEnd(*inout,inout); +AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t **inout) { + return SkipSpacesAndLineEnd(*inout, inout); } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] ) { - if( ( char_t )'\0' == *buffer ) { +AI_FORCE_INLINE bool GetNextLine(const char_t *&buffer, char_t out[BufferSize]) { + if ((char_t)'\0' == *buffer) { return false; } - char* _out = out; - char* const end = _out + BufferSize; - while( !IsLineEnd( *buffer ) && _out < end ) { + char *_out = out; + char *const end = _out + BufferSize; + while (!IsLineEnd(*buffer) && _out < end) { *_out++ = *buffer++; } *_out = (char_t)'\0'; - while( IsLineEnd( *buffer ) && '\0' != *buffer ) { + while (IsLineEnd(*buffer) && '\0' != *buffer) { ++buffer; } @@ -200,18 +190,16 @@ bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] ) { // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE bool IsNumeric( char_t in) { - return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in; +AI_FORCE_INLINE bool IsNumeric(char_t in) { + return (in >= '0' && in <= '9') || '-' == in || '+' == in; } // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE -bool TokenMatch(char_t*& in, const char* token, unsigned int len) -{ - if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) { +AI_FORCE_INLINE bool TokenMatch(char_t *&in, const char *token, unsigned int len) { + if (!::strncmp(token, in, len) && IsSpaceOrNewLine(in[len])) { if (in[len] != '\0') { - in += len+1; + in += len + 1; } else { // If EOF after the token make sure we don't go past end of buffer in += len; @@ -228,9 +216,9 @@ bool TokenMatch(char_t*& in, const char* token, unsigned int len) * @param len Number of characters to check */ AI_FORCE_INLINE -bool TokenMatchI(const char*& in, const char* token, unsigned int len) { - if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) { - in += len+1; +bool TokenMatchI(const char *&in, const char *token, unsigned int len) { + if (!ASSIMP_strincmp(token, in, len) && IsSpaceOrNewLine(in[len])) { + in += len + 1; return true; } return false; @@ -238,22 +226,22 @@ bool TokenMatchI(const char*& in, const char* token, unsigned int len) { // --------------------------------------------------------------------------------- AI_FORCE_INLINE -void SkipToken(const char*& in) { +void SkipToken(const char *&in) { SkipSpaces(&in); - while ( !IsSpaceOrNewLine( *in ) ) { + while (!IsSpaceOrNewLine(*in)) { ++in; } } // --------------------------------------------------------------------------------- AI_FORCE_INLINE -std::string GetNextToken(const char*& in) { +std::string GetNextToken(const char *&in) { SkipSpacesAndLineEnd(&in); - const char* cur = in; - while ( !IsSpaceOrNewLine( *in ) ) { + const char *cur = in; + while (!IsSpaceOrNewLine(*in)) { ++in; } - return std::string(cur,(size_t)(in-cur)); + return std::string(cur, (size_t)(in - cur)); } // --------------------------------------------------------------------------------- @@ -289,6 +277,6 @@ AI_FORCE_INLINE unsigned int tokenize(const string_type &str, std::vector