pull/4170/head
Kim Kulling 2021-11-10 20:37:27 +01:00
parent 791cb195be
commit 8ed18621db
15 changed files with 741 additions and 708 deletions

View File

@ -75,7 +75,7 @@ bool X3DImporter::isNodeEmpty(XmlNode &node) {
} }
void X3DImporter::checkNodeMustBeEmpty(XmlNode &node) { void X3DImporter::checkNodeMustBeEmpty(XmlNode &node) {
if (isNodeEmpty(node)) throw DeadlyImportError(std::string("Node <") + node.name() + "> must be empty."); if (!isNodeEmpty(node)) throw DeadlyImportError(std::string("Node <") + node.name() + "> must be empty.");
} }
void X3DImporter::skipUnsupportedNode(const std::string &pParentNodeName, XmlNode &node) { void X3DImporter::skipUnsupportedNode(const std::string &pParentNodeName, XmlNode &node) {
@ -321,7 +321,7 @@ void X3DImporter::readHead(XmlNode &node) {
for (auto currentNode : node.children()) { for (auto currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "meta") { if (currentName == "meta") {
checkNodeMustBeEmpty(node); //checkNodeMustBeEmpty(node);
meta_entry entry; meta_entry entry;
if (XmlParser::getStdStrAttribute(currentNode, "name", entry.name)) { if (XmlParser::getStdStrAttribute(currentNode, "name", entry.name)) {
XmlParser::getStdStrAttribute(currentNode, "content", entry.value); XmlParser::getStdStrAttribute(currentNode, "content", entry.value);
@ -339,6 +339,9 @@ void X3DImporter::readHead(XmlNode &node) {
} }
void X3DImporter::readChildNodes(XmlNode &node, const std::string &pParentNodeName) { void X3DImporter::readChildNodes(XmlNode &node, const std::string &pParentNodeName) {
if (node.empty()) {
return;
}
for (auto currentNode : node.children()) { for (auto currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "Shape") if (currentName == "Shape")
@ -463,6 +466,8 @@ void X3DImporter::ParseHelper_Group_Begin(const bool pStatic) {
} }
void X3DImporter::ParseHelper_Node_Enter(X3DNodeElementBase *pNode) { void X3DImporter::ParseHelper_Node_Enter(X3DNodeElementBase *pNode) {
ai_assert(nullptr != pNode);
mNodeElementCur->Children.push_back(pNode); // add new element to current element child list. mNodeElementCur->Children.push_back(pNode); // add new element to current element child list.
mNodeElementCur = pNode; // switch current element to new one. mNodeElementCur = pNode; // switch current element to new one.
} }
@ -471,6 +476,9 @@ void X3DImporter::ParseHelper_Node_Exit() {
// check if we can walk up. // check if we can walk up.
if (mNodeElementCur != nullptr) { if (mNodeElementCur != nullptr) {
mNodeElementCur = mNodeElementCur->Parent; mNodeElementCur = mNodeElementCur->Parent;
} else {
int i = 0;
++i;
} }
} }

View File

@ -270,6 +270,7 @@ public:
void Clear(); void Clear();
private: private:
X3DNodeElementBase *MACRO_USE_CHECKANDAPPLY(XmlNode &node, std::string pDEF, std::string pUSE, X3DElemType pType, X3DNodeElementBase *pNE);
bool isNodeEmpty(XmlNode &node); bool isNodeEmpty(XmlNode &node);
void checkNodeMustBeEmpty(XmlNode &node); void checkNodeMustBeEmpty(XmlNode &node);
void skipUnsupportedNode(const std::string &pParentNodeName, XmlNode &node); void skipUnsupportedNode(const std::string &pParentNodeName, XmlNode &node);

View File

@ -78,7 +78,7 @@ void X3DImporter::readArc2D(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Arc2D, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Arc2D, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Arc2D, mNodeElementCur); ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Arc2D, mNodeElementCur);
@ -138,7 +138,7 @@ void X3DImporter::readArcClose2D(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ArcClose2D, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ArcClose2D, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_ArcClose2D, mNodeElementCur); ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_ArcClose2D, mNodeElementCur);
@ -185,7 +185,7 @@ void X3DImporter::readCircle2D(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Circle2D, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Circle2D, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Circle2D, mNodeElementCur); ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Circle2D, mNodeElementCur);
@ -234,7 +234,7 @@ void X3DImporter::readDisk2D(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Disk2D, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Disk2D, ne);
} else { } else {
std::list<aiVector3D> tlist_o, tlist_i; std::list<aiVector3D> tlist_o, tlist_i;
@ -308,7 +308,7 @@ void X3DImporter::readPolyline2D(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Polyline2D, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Polyline2D, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Polyline2D, mNodeElementCur); ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Polyline2D, mNodeElementCur);
@ -351,7 +351,7 @@ void X3DImporter::readPolypoint2D(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Polypoint2D, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Polypoint2D, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Polypoint2D, mNodeElementCur); ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Polypoint2D, mNodeElementCur);
@ -391,7 +391,7 @@ void X3DImporter::readRectangle2D(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Rectangle2D, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Rectangle2D, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Rectangle2D, mNodeElementCur); ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Rectangle2D, mNodeElementCur);
@ -437,7 +437,7 @@ void X3DImporter::readTriangleSet2D(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleSet2D, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleSet2D, ne);
} else { } else {
if (vertices.size() % 3) throw DeadlyImportError("TriangleSet2D. Not enough points for defining triangle."); if (vertices.size() % 3) throw DeadlyImportError("TriangleSet2D. Not enough points for defining triangle.");

File diff suppressed because it is too large Load Diff

View File

@ -72,9 +72,8 @@ void X3DImporter::startReadGroup(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
X3DNodeElementBase *ne; X3DNodeElementBase *ne = nullptr;
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
} else { } else {
ParseHelper_Group_Begin(); // create new grouping element and go deeper if node has children. 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. // at this place new group mode created and made current, so we can name it.
@ -111,9 +110,9 @@ void X3DImporter::startReadStaticGroup(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
X3DNodeElementBase *ne; X3DNodeElementBase *ne = nullptr;
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
} else { } else {
ParseHelper_Group_Begin(true); // create new grouping element and go deeper if node has children. 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. // at this place new group mode created and made current, so we can name it.
@ -154,9 +153,9 @@ void X3DImporter::startReadSwitch(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
X3DNodeElementBase *ne; X3DNodeElementBase *ne=nullptr;
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
} else { } else {
ParseHelper_Group_Begin(); // create new grouping element and go deeper if node has children. 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. // at this place new group mode created and made current, so we can name it.
@ -228,7 +227,7 @@ void X3DImporter::startReadTransform(XmlNode &node) {
if (!use.empty()) { if (!use.empty()) {
X3DNodeElementBase *ne(nullptr); X3DNodeElementBase *ne(nullptr);
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
} else { } else {
ParseHelper_Group_Begin(); // create new grouping element and go deeper if node has children. 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. // at this place new group mode created and made current, so we can name it.

View File

@ -83,7 +83,7 @@ void X3DImporter::readDirectionalLight(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_DirectionalLight, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_DirectionalLight, ne);
} else { } else {
if (on) { if (on) {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
@ -150,7 +150,7 @@ void X3DImporter::readPointLight(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointLight, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointLight, ne);
} else { } else {
if (on) { if (on) {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
@ -227,7 +227,7 @@ void X3DImporter::readSpotLight(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_SpotLight, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_SpotLight, ne);
} else { } else {
if (on) { if (on) {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.

View File

@ -47,20 +47,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef X3DIMPORTER_MACRO_HPP_INCLUDED #ifndef X3DIMPORTER_MACRO_HPP_INCLUDED
#define X3DIMPORTER_MACRO_HPP_INCLUDED #define X3DIMPORTER_MACRO_HPP_INCLUDED
/// \def MACRO_USE_CHECKANDAPPLY(pDEF, pUSE, pNE) #include <assimp/XmlParser.h>
#include "X3DImporter.hpp"
#include <string>
namespace Assimp {
/// Used for regular checking while attribute "USE" is defined. /// Used for regular checking while attribute "USE" is defined.
/// \param [in] pNode - pugi xml node to read. /// \param [in] pNode - pugi xml node to read.
/// \param [in] pDEF - string holding "DEF" value. /// \param [in] pDEF - string holding "DEF" value.
/// \param [in] pUSE - string holding "USE" value. /// \param [in] pUSE - string holding "USE" value.
/// \param [in] pType - type of element to find. /// \param [in] pType - type of element to find.
/// \param [out] pNE - pointer to found node element. /// \param [out] pNE - pointer to found node element.
#define MACRO_USE_CHECKANDAPPLY(pNode, pDEF, pUSE, pType, pNE) \ inline X3DNodeElementBase *X3DImporter::MACRO_USE_CHECKANDAPPLY(XmlNode &node, std::string pDEF, std::string pUSE, X3DElemType pType, X3DNodeElementBase *pNE) {
do { \ if (nullptr == mNodeElementCur) {
checkNodeMustBeEmpty(pNode); \ printf("here\n");
if (!pDEF.empty()) Throw_DEF_And_USE(pNode.name()); \ }
if (!FindNodeElement(pUSE, X3DElemType::pType, &pNE)) Throw_USE_NotFound(pNode.name(), pUSE); \
mNodeElementCur->Children.push_back(pNE); /* add found object as child to current element */ \ //do {
} while (false) checkNodeMustBeEmpty(node);
if (!pDEF.empty())
Assimp::Throw_DEF_And_USE(node.name());
if (!FindNodeElement(pUSE, pType, &pNE))
Assimp::Throw_USE_NotFound(node.name(), pUSE);
mNodeElementCur->Children.push_back(pNE); /* add found object as child to current element */
//} while (false);
return pNE;
}
} // namespace Assimp
/// \def MACRO_ATTRREAD_CHECKUSEDEF_RET /// \def MACRO_ATTRREAD_CHECKUSEDEF_RET
/// Compact variant for checking "USE" and "DEF". /// Compact variant for checking "USE" and "DEF".

View File

@ -93,7 +93,7 @@ void X3DImporter::childrenReadMetadata(XmlNode &node, X3DNodeElementBase *pParen
#define MACRO_METADATA_FINDCREATE(pNode, pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaClass, pMetaName, pType) \ #define MACRO_METADATA_FINDCREATE(pNode, pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaClass, pMetaName, pType) \
/* if "USE" defined then find already defined element. */ \ /* if "USE" defined then find already defined element. */ \
if (!pUSE_Var.empty()) { \ if (!pUSE_Var.empty()) { \
MACRO_USE_CHECKANDAPPLY(pNode, pDEF_Var, pUSE_Var, pType, pNE); \ ne = MACRO_USE_CHECKANDAPPLY(pNode, pDEF_Var, pUSE_Var, pType, pNE); \
} else { \ } else { \
pNE = new pMetaClass(mNodeElementCur); \ pNE = new pMetaClass(mNodeElementCur); \
if (!pDEF_Var.empty()) pNE->ID = pDEF_Var; \ if (!pDEF_Var.empty()) pNE->ID = pDEF_Var; \
@ -213,13 +213,13 @@ void X3DImporter::readMetadataSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_MetaSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_MetaSet, ne);
} else { } else {
ne = new X3DNodeElementMetaSet(mNodeElementCur); ne = new X3DNodeElementMetaSet(mNodeElementCur);
if (!def.empty()) ne->ID = def; if (!def.empty()) ne->ID = def;
((X3DNodeElementMetaSet *)ne)->Reference = reference; ((X3DNodeElementMetaSet *)ne)->Reference = reference;
// also metadata node can contain childs // also metadata node can contain children
if (!isNodeEmpty(node)) if (!isNodeEmpty(node))
childrenReadMetadata(node, ne, "MetadataSet"); childrenReadMetadata(node, ne, "MetadataSet");
else else

View File

@ -78,10 +78,9 @@ void X3DImporter::readInline(XmlNode &node) {
X3DXmlHelper::getStringListAttribute(node, "url", url); X3DXmlHelper::getStringListAttribute(node, "url", url);
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
X3DNodeElementBase *ne = nullptr;
if (!use.empty()) { if (!use.empty()) {
X3DNodeElementBase *ne; ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
} else { } else {
ParseHelper_Group_Begin(true); // create new grouping element and go deeper if node has children. 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. // at this place new group mode created and made current, so we can name it.

View File

@ -67,7 +67,7 @@ void X3DImporter::readColor(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Color, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Color, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementColor(mNodeElementCur); ne = new X3DNodeElementColor(mNodeElementCur);
@ -99,7 +99,7 @@ void X3DImporter::readColorRGBA(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ColorRGBA, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ColorRGBA, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementColorRGBA(mNodeElementCur); ne = new X3DNodeElementColorRGBA(mNodeElementCur);
@ -131,7 +131,7 @@ void X3DImporter::readCoordinate(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Coordinate, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Coordinate, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementCoordinate(mNodeElementCur); ne = new X3DNodeElementCoordinate(mNodeElementCur);
@ -174,7 +174,7 @@ void X3DImporter::readIndexedLineSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedLineSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedLineSet, ne);
} else { } else {
// check data // check data
if ((coordIndex.size() < 2) || ((coordIndex.back() == (-1)) && (coordIndex.size() < 3))) if ((coordIndex.size() < 2) || ((coordIndex.back() == (-1)) && (coordIndex.size() < 3)))
@ -248,7 +248,7 @@ void X3DImporter::readIndexedTriangleFanSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleFanSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleFanSet, ne);
} else { } else {
// check data // check data
if (index.size() == 0) throw DeadlyImportError("IndexedTriangleFanSet must contain not empty \"index\" attribute."); if (index.size() == 0) throw DeadlyImportError("IndexedTriangleFanSet must contain not empty \"index\" attribute.");
@ -354,7 +354,7 @@ void X3DImporter::readIndexedTriangleSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleSet, ne);
} else { } else {
// check data // check data
if (index.size() == 0) throw DeadlyImportError("IndexedTriangleSet must contain not empty \"index\" attribute."); if (index.size() == 0) throw DeadlyImportError("IndexedTriangleSet must contain not empty \"index\" attribute.");
@ -453,10 +453,12 @@ void X3DImporter::readIndexedTriangleStripSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleStripSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleStripSet, ne);
} else { } else {
// check data // check data
if (index.size() == 0) throw DeadlyImportError("IndexedTriangleStripSet must contain not empty \"index\" attribute."); if (index.empty()) {
throw DeadlyImportError("IndexedTriangleStripSet must contain not empty \"index\" attribute.");
}
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_IndexedTriangleStripSet, mNodeElementCur); ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_IndexedTriangleStripSet, mNodeElementCur);
@ -544,10 +546,12 @@ void X3DImporter::readLineSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_LineSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_LineSet, ne);
} else { } else {
// check data // check data
if (vertexCount.size() == 0) throw DeadlyImportError("LineSet must contain not empty \"vertexCount\" attribute."); if (vertexCount.empty()) {
throw DeadlyImportError("LineSet must contain not empty \"vertexCount\" attribute.");
}
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementSet(X3DElemType::ENET_LineSet, mNodeElementCur); ne = new X3DNodeElementSet(X3DElemType::ENET_LineSet, mNodeElementCur);
@ -612,7 +616,7 @@ void X3DImporter::readPointSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointSet, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_PointSet, mNodeElementCur); ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_PointSet, mNodeElementCur);
@ -677,10 +681,12 @@ void X3DImporter::readTriangleFanSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleFanSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleFanSet, ne);
} else { } else {
// check data // check data
if (fanCount.size() == 0) throw DeadlyImportError("TriangleFanSet must contain not empty \"fanCount\" attribute."); if (fanCount.empty()) {
throw DeadlyImportError("TriangleFanSet must contain not empty \"fanCount\" attribute.");
}
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementSet(X3DElemType::ENET_TriangleFanSet, mNodeElementCur); ne = new X3DNodeElementSet(X3DElemType::ENET_TriangleFanSet, mNodeElementCur);
@ -784,7 +790,7 @@ void X3DImporter::readTriangleSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleSet, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_TriangleSet, mNodeElementCur); ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_TriangleSet, mNodeElementCur);
@ -859,7 +865,7 @@ void X3DImporter::readTriangleStripSet(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleStripSet, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleStripSet, ne);
} else { } else {
// check data // check data
if (stripCount.size() == 0) throw DeadlyImportError("TriangleStripSet must contain not empty \"stripCount\" attribute."); if (stripCount.size() == 0) throw DeadlyImportError("TriangleStripSet must contain not empty \"stripCount\" attribute.");
@ -958,14 +964,14 @@ void X3DImporter::readTriangleStripSet(XmlNode &node) {
void X3DImporter::readNormal(XmlNode &node) { void X3DImporter::readNormal(XmlNode &node) {
std::string use, def; std::string use, def;
std::list<aiVector3D> vector; std::list<aiVector3D> vector;
X3DNodeElementBase *ne; X3DNodeElementBase *ne=nullptr;
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use); MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
X3DXmlHelper::getVector3DListAttribute(node, "vector", vector); X3DXmlHelper::getVector3DListAttribute(node, "vector", vector);
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Normal, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Normal, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementNormal(mNodeElementCur); ne = new X3DNodeElementNormal(mNodeElementCur);

View File

@ -60,7 +60,7 @@ void X3DImporter::readShape(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Shape, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Shape, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementShape(mNodeElementCur); ne = new X3DNodeElementShape(mNodeElementCur);
@ -74,31 +74,55 @@ void X3DImporter::readShape(XmlNode &node) {
// check for appearance node // check for appearance node
if (currentChildName == "Appearance") readAppearance(currentChildNode); if (currentChildName == "Appearance") readAppearance(currentChildNode);
// check for X3DGeometryNodes // check for X3DGeometryNodes
else if (currentChildName == "Arc2D") readArc2D(currentChildNode); else if (currentChildName == "Arc2D")
else if (currentChildName == "ArcClose2D") readArcClose2D(currentChildNode); readArc2D(currentChildNode);
else if (currentChildName == "Circle2D") readCircle2D(currentChildNode); else if (currentChildName == "ArcClose2D")
else if (currentChildName == "Disk2D") readDisk2D(currentChildNode); readArcClose2D(currentChildNode);
else if (currentChildName == "Polyline2D") readPolyline2D(currentChildNode); else if (currentChildName == "Circle2D")
else if (currentChildName == "Polypoint2D") readPolypoint2D(currentChildNode); readCircle2D(currentChildNode);
else if (currentChildName == "Rectangle2D") readRectangle2D(currentChildNode); else if (currentChildName == "Disk2D")
else if (currentChildName == "TriangleSet2D") readTriangleSet2D(currentChildNode); readDisk2D(currentChildNode);
else if (currentChildName == "Box") readBox(currentChildNode); else if (currentChildName == "Polyline2D")
else if (currentChildName == "Cone") readCone(currentChildNode); readPolyline2D(currentChildNode);
else if (currentChildName == "Cylinder") readCylinder(currentChildNode); else if (currentChildName == "Polypoint2D")
else if (currentChildName == "ElevationGrid") readElevationGrid(currentChildNode); readPolypoint2D(currentChildNode);
else if (currentChildName == "Extrusion") readExtrusion(currentChildNode); else if (currentChildName == "Rectangle2D")
else if (currentChildName == "IndexedFaceSet") readIndexedFaceSet(currentChildNode); readRectangle2D(currentChildNode);
else if (currentChildName == "Sphere") readSphere(currentChildNode); else if (currentChildName == "TriangleSet2D")
else if (currentChildName == "IndexedLineSet") readIndexedLineSet(currentChildNode); readTriangleSet2D(currentChildNode);
else if (currentChildName == "LineSet") readLineSet(currentChildNode); else if (currentChildName == "Box")
else if (currentChildName == "PointSet") readPointSet(currentChildNode); readBox(currentChildNode);
else if (currentChildName == "IndexedTriangleFanSet") readIndexedTriangleFanSet(currentChildNode); else if (currentChildName == "Cone")
else if (currentChildName == "IndexedTriangleSet") readIndexedTriangleSet(currentChildNode); readCone(currentChildNode);
else if (currentChildName == "IndexedTriangleStripSet") readIndexedTriangleStripSet(currentChildNode); else if (currentChildName == "Cylinder")
else if (currentChildName == "TriangleFanSet") readTriangleFanSet(currentChildNode); readCylinder(currentChildNode);
else if (currentChildName == "TriangleSet") readTriangleSet(currentChildNode); else if (currentChildName == "ElevationGrid")
readElevationGrid(currentChildNode);
else if (currentChildName == "Extrusion")
readExtrusion(currentChildNode);
else if (currentChildName == "IndexedFaceSet")
readIndexedFaceSet(currentChildNode);
else if (currentChildName == "Sphere")
readSphere(currentChildNode);
else if (currentChildName == "IndexedLineSet")
readIndexedLineSet(currentChildNode);
else if (currentChildName == "LineSet")
readLineSet(currentChildNode);
else if (currentChildName == "PointSet")
readPointSet(currentChildNode);
else if (currentChildName == "IndexedTriangleFanSet")
readIndexedTriangleFanSet(currentChildNode);
else if (currentChildName == "IndexedTriangleSet")
readIndexedTriangleSet(currentChildNode);
else if (currentChildName == "IndexedTriangleStripSet")
readIndexedTriangleStripSet(currentChildNode);
else if (currentChildName == "TriangleFanSet")
readTriangleFanSet(currentChildNode);
else if (currentChildName == "TriangleSet")
readTriangleSet(currentChildNode);
// check for X3DMetadataObject // check for X3DMetadataObject
else if (!checkForMetadataNode(currentChildNode)) skipUnsupportedNode("Shape", currentChildNode); else if (!checkForMetadataNode(currentChildNode))
skipUnsupportedNode("Shape", currentChildNode);
} }
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
@ -123,42 +147,41 @@ void X3DImporter::readShape(XmlNode &node) {
// </Appearance> // </Appearance>
void X3DImporter::readAppearance(XmlNode &node) { void X3DImporter::readAppearance(XmlNode &node) {
std::string use, def; std::string use, def;
X3DNodeElementBase* ne( nullptr ); X3DNodeElementBase *ne(nullptr);
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use); MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) if (!use.empty()) {
{ ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Appearance, ne);
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Appearance, ne); } else {
} // create and if needed - define new geometry object.
else ne = new X3DNodeElementAppearance(mNodeElementCur);
{ if (!def.empty()) ne->ID = def;
// create and if needed - define new geometry object.
ne = new X3DNodeElementAppearance(mNodeElementCur);
if(!def.empty()) ne->ID = def;
// check for child nodes // check for child nodes
if(!isNodeEmpty(node)) if (!isNodeEmpty(node)) {
{ ParseHelper_Node_Enter(ne);
ParseHelper_Node_Enter(ne);
for (auto currentChildNode : node.children()) { for (auto currentChildNode : node.children()) {
const std::string &currentChildName = currentChildNode.name(); const std::string &currentChildName = currentChildNode.name();
if (currentChildName == "Material") readMaterial(currentChildNode); if (currentChildName == "Material")
else if (currentChildName == "ImageTexture") readImageTexture(currentChildNode); readMaterial(currentChildNode);
else if (currentChildName == "TextureTransform") readTextureTransform(currentChildNode); else if (currentChildName == "ImageTexture")
readImageTexture(currentChildNode);
else if (currentChildName == "TextureTransform")
readTextureTransform(currentChildNode);
// check for X3DMetadataObject // check for X3DMetadataObject
else if (!checkForMetadataNode(currentChildNode)) skipUnsupportedNode("Appearance", currentChildNode); else if (!checkForMetadataNode(currentChildNode))
skipUnsupportedNode("Appearance", currentChildNode);
} }
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
}// if(!isNodeEmpty(node)) } // if(!isNodeEmpty(node))
else else {
{ mNodeElementCur->Children.push_back(ne); // add made object as child to current element
mNodeElementCur->Children.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 NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
}// if(!use.empty()) else } // if(!use.empty()) else
} }
// <Material // <Material
@ -179,7 +202,7 @@ void X3DImporter::readMaterial(XmlNode &node) {
aiColor3D diffuseColor(0.8f, 0.8f, 0.8f); aiColor3D diffuseColor(0.8f, 0.8f, 0.8f);
aiColor3D emissiveColor(0, 0, 0); aiColor3D emissiveColor(0, 0, 0);
aiColor3D specularColor(0, 0, 0); aiColor3D specularColor(0, 0, 0);
X3DNodeElementBase* ne( nullptr ); X3DNodeElementBase *ne(nullptr);
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use); MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
XmlParser::getFloatAttribute(node, "ambientIntensity", ambientIntensity); XmlParser::getFloatAttribute(node, "ambientIntensity", ambientIntensity);
@ -189,33 +212,30 @@ void X3DImporter::readMaterial(XmlNode &node) {
X3DXmlHelper::getColor3DAttribute(node, "emissiveColor", emissiveColor); X3DXmlHelper::getColor3DAttribute(node, "emissiveColor", emissiveColor);
X3DXmlHelper::getColor3DAttribute(node, "specularColor", specularColor); X3DXmlHelper::getColor3DAttribute(node, "specularColor", specularColor);
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if(!use.empty()) if (!use.empty()) {
{ ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Material, ne);
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Material, ne); } else {
} // create and if needed - define new geometry object.
else ne = new X3DNodeElementMaterial(mNodeElementCur);
{ if (!def.empty()) ne->ID = def;
// create and if needed - define new geometry object.
ne = new X3DNodeElementMaterial(mNodeElementCur);
if(!def.empty()) ne->ID = def;
((X3DNodeElementMaterial *)ne)->AmbientIntensity = ambientIntensity; ((X3DNodeElementMaterial *)ne)->AmbientIntensity = ambientIntensity;
((X3DNodeElementMaterial *)ne)->Shininess = shininess; ((X3DNodeElementMaterial *)ne)->Shininess = shininess;
((X3DNodeElementMaterial *)ne)->Transparency = transparency; ((X3DNodeElementMaterial *)ne)->Transparency = transparency;
((X3DNodeElementMaterial *)ne)->DiffuseColor = diffuseColor; ((X3DNodeElementMaterial *)ne)->DiffuseColor = diffuseColor;
((X3DNodeElementMaterial *)ne)->EmissiveColor = emissiveColor; ((X3DNodeElementMaterial *)ne)->EmissiveColor = emissiveColor;
((X3DNodeElementMaterial *)ne)->SpecularColor = specularColor; ((X3DNodeElementMaterial *)ne)->SpecularColor = specularColor;
// check for child nodes // check for child nodes
if(!isNodeEmpty(node)) if (!isNodeEmpty(node))
childrenReadMetadata(node, ne, "Material"); childrenReadMetadata(node, ne, "Material");
else else
mNodeElementCur->Children.push_back(ne); // add made object as child to current element mNodeElementCur->Children.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 NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
}// if(!use.empty()) else } // if(!use.empty()) else
} }
}// namespace Assimp } // namespace Assimp
#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER

View File

@ -74,7 +74,7 @@ void X3DImporter::readImageTexture(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ImageTexture, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ImageTexture, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementImageTexture(mNodeElementCur); ne = new X3DNodeElementImageTexture(mNodeElementCur);
@ -113,7 +113,7 @@ void X3DImporter::readTextureCoordinate(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TextureCoordinate, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TextureCoordinate, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementTextureCoordinate(mNodeElementCur); ne = new X3DNodeElementTextureCoordinate(mNodeElementCur);
@ -154,7 +154,7 @@ void X3DImporter::readTextureTransform(XmlNode &node) {
// if "USE" defined then find already defined element. // if "USE" defined then find already defined element.
if (!use.empty()) { if (!use.empty()) {
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TextureTransform, ne); ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TextureTransform, ne);
} else { } else {
// create and if needed - define new geometry object. // create and if needed - define new geometry object.
ne = new X3DNodeElementTextureTransform(mNodeElementCur); ne = new X3DNodeElementTextureTransform(mNodeElementCur);

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "https://www.web3d.org/specifications/x3d-3.0.dtd">
<X3D profile='Immersive' version='3.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.0.xsd'>
<!-- X3D&#8482; is a trademark of the Web3D Consortium Incorporated, standing for Extensible 3D Graphics (X3D). -->
<head>
<meta content='HelloX3dTrademark.x3d' name='title'/>
<meta content='Don Brutzman' name='creator'/>
<meta content='6 June 2001' name='created'/>
<meta content='20 October 2019' name='modified'/>
<meta content='Simple example showing spinning globe and X3D&amp;#8482; trademark text. X3D (tm) is a trademark of the Web3D Consortium Inc. X3D stands for Extensible 3D Graphics (X3D), an encoding of VRML using XML. X3D has been defined since 1998. Trademark registration pending. VRML is the Virtual Reality Modeling Language (VRML), International Standard ISO/IEC 14772-1:1997. XML is the Extensible Markup Language (XML), a Recommendation of the World Wide Web Consortium (W3C).' name='description'/>
<meta content='HelloX3dTrademark.png' name='Image'/>
<meta content='https://www.web3d.org' name='reference'/>
<meta content='https://www.web3d.org/x3d' name='reference'/>
<meta content='https://www.web3d.org/Specifications/VRML97' name='reference'/>
<meta content='http://www.w3.org/XML' name='reference'/>
<meta content='https://www.web3d.org/x3d/content/examples/Basic/development/HelloX3dTrademark.x3d' name='identifier'/>
<meta content='X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit' name='generator'/>
<meta content='../license.html' name='license'/>
</head>
<Scene>
<WorldInfo info='"an introductory scene"' title='Hello X3D&amp;#8482; Trademark (tm)'/>
<Viewpoint description='Hello, world' orientation='0 1 0 3.14159' position='0 0 -8'/>
<Transform DEF='EarthCoordinateSystem'>
<Group DEF='MiniWorld'>
<Shape>
<Appearance>
<ImageTexture url='"earth-topo.png" "earth-topo.gif" "earth-topo-small.gif" "https://www.web3d.org/x3d/content/examples/Basic/development/earth-topo.png" "https://www.web3d.org/x3d/content/examples/Basic/development/earth-topo.gif" "https://www.web3d.org/x3d/content/examples/Basic/development/earth-topo-small.gif"'/>
</Appearance>
<Sphere DEF='GlobeNotToScale'/>
</Shape>
</Group>
<Transform DEF='SimpleGeoStationarySatellite' scale='0.1 0.3 0.1' translation='0 0 4'>
<Shape>
<Appearance>
<Material diffuseColor='0.9 0.1 0.1'/>
</Appearance>
<Text string='"Hello" "X3D Trademark (tm)"'>
<FontStyle justify='"MIDDLE" "MIDDLE"' size='3'/>
</Text>
</Shape>
</Transform>
</Transform>
<TimeSensor DEF='OrbitalTimeInterval' cycleInterval='12.0' loop='true'/>
<OrientationInterpolator DEF='SpinThoseThings' key='0.00 0.25 0.50 0.75 1.00' keyValue='0 1 0 0 0 1 0 1.57079 0 1 0 3.14159 0 1 0 4.7123889 0 1 0 6.2831852'/>
<ROUTE fromField='fraction_changed' fromNode='OrbitalTimeInterval' toField='set_fraction' toNode='SpinThoseThings'/>
<ROUTE fromField='value_changed' fromNode='SpinThoseThings' toField='rotation' toNode='EarthCoordinateSystem'/>
</Scene>
</X3D>

Binary file not shown.

View File

@ -49,7 +49,7 @@ using namespace Assimp;
class utX3DImportExport : public AbstractImportExportBase { class utX3DImportExport : public AbstractImportExportBase {
public: public:
virtual bool importerTest() { bool importerTest() override {
Assimp::Importer importer; Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X3D/ComputerKeyboard.x3d", aiProcess_ValidateDataStructure); const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X3D/ComputerKeyboard.x3d", aiProcess_ValidateDataStructure);
return nullptr != scene; return nullptr != scene;