Переглянути джерело

xml-migration amf - next steps.

Kim Kulling 5 роки тому
батько
коміт
03182c21b8

+ 334 - 369
code/AMF/AMFImporter.cpp

@@ -79,7 +79,7 @@ void AMFImporter::Clear() {
 	mTexture_Converted.clear();
 	// Delete all elements
 	if (!mNodeElement_List.empty()) {
-		for (CAMFImporter_NodeElement *ne : mNodeElement_List) {
+		for (AMFNodeElementBase *ne : mNodeElement_List) {
 			delete ne;
 		}
 
@@ -97,237 +97,6 @@ AMFImporter::~AMFImporter() {
 	Clear();
 }
 
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: find set ************************************************************/
-/*********************************************************************************************************************************************/
-
-bool AMFImporter::Find_NodeElement(const std::string &pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement **pNodeElement) const {
-	for (CAMFImporter_NodeElement *ne : mNodeElement_List) {
-		if ((ne->ID == pID) && (ne->Type == pType)) {
-			if (pNodeElement != nullptr) {
-				*pNodeElement = ne;
-			}
-
-			return true;
-		}
-	} // for(CAMFImporter_NodeElement* ne: mNodeElement_List)
-
-	return false;
-}
-
-bool AMFImporter::Find_ConvertedNode(const std::string &id, std::list<aiNode *> &nodeList, aiNode **pNode) const {
-	aiString node_name(id.c_str());
-
-	for (aiNode *node : nodeList) {
-		if (node->mName == node_name) {
-			if (pNode != nullptr) {
-				*pNode = node;
-			}
-
-			return true;
-		}
-	} // for(aiNode* node: pNodeList)
-
-	return false;
-}
-
-bool AMFImporter::Find_ConvertedMaterial(const std::string &id, const SPP_Material **pConvertedMaterial) const {
-	for (const SPP_Material &mat : mMaterial_Converted) {
-		if (mat.ID == id) {
-			if (pConvertedMaterial != nullptr) {
-				*pConvertedMaterial = &mat;
-			}
-
-			return true;
-		}
-	} // for(const SPP_Material& mat: mMaterial_Converted)
-
-	return false;
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: throw set ***********************************************************/
-/*********************************************************************************************************************************************/
-
-void AMFImporter::Throw_CloseNotFound(const std::string &pNode) {
-	throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt.");
-}
-
-void AMFImporter::Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) {
-	throw DeadlyImportError("Node <" + nodeName + "> has incorrect attribute \"" + pAttrName + "\".");
-}
-
-void AMFImporter::Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) {
-	throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + nodeName + "> has incorrect value.");
-}
-
-void AMFImporter::Throw_MoreThanOnceDefined(const std::string &nodeType, const std::string &nodeName, const std::string &pDescription) {
-	throw DeadlyImportError("\"" + nodeType + "\" node can be used only once in " + nodeName + ". Description: " + pDescription);
-}
-
-void AMFImporter::Throw_ID_NotFound(const std::string &pID) const {
-	throw DeadlyImportError("Not found node with name \"" + pID + "\".");
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************* Functions: XML set ************************************************************/
-/*********************************************************************************************************************************************/
-
-void AMFImporter::XML_CheckNode_MustHaveChildren( XmlNode &node ) {
-	if (node.children().begin() == node.children().end()) {
-		throw DeadlyImportError(std::string("Node <") + std::string(node.name()) + "> must have children.");
-    }
-}
-
-/*void AMFImporter::XML_CheckNode_SkipUnsupported(XmlNode *node, const std::string &pParentNodeName) {
-	static const size_t Uns_Skip_Len = 3;
-	const char *Uns_Skip[Uns_Skip_Len] = { "composite", "edge", "normal" };
-
-	static bool skipped_before[Uns_Skip_Len] = { false, false, false };
-
-	std::string nn(mReader->getNodeName());
-	bool found = false;
-	bool close_found = false;
-	size_t sk_idx;
-
-	for (sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++) {
-		if (nn != Uns_Skip[sk_idx]) continue;
-
-		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;
-			}
-		}
-	} // for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
-
-casu_cres:
-
-	if (!found) throw DeadlyImportError("Unknown node \"" + nn + "\" in " + pParentNodeName + ".");
-	if (!close_found) Throw_CloseNotFound(nn);
-
-	if (!skipped_before[sk_idx]) {
-		skipped_before[sk_idx] = true;
-		ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, ".");
-	}
-}
-*/
-bool AMFImporter::XML_SearchNode(const std::string &nodeName) {
-	XmlNode *root = mXmlParser->getRootNode();
-	if (nullptr == root) {
-		return false;
-    }
-
-    find_node_by_name_predicate predicate(nodeName);
-	XmlNode node = root->find_node(predicate);
-	if (node.empty()) {
-		return false;
-    }
-
-	return true;
-}
-
-bool AMFImporter::XML_ReadNode_GetAttrVal_AsBool (const int pAttrIdx) {
-	std::string val(mXmlParser->getAttributeValue(pAttrIdx));
-
-	if ((val == "false") || (val == "0"))
-		return false;
-	else if ((val == "true") || (val == "1"))
-		return true;
-	else
-		throw DeadlyImportError("Bool attribute value can contain \"false\"/\"0\" or \"true\"/\"1\" not the \"" + val + "\"");
-}
-
-float AMFImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx) {
-	std::string val;
-	float tvalf;
-
-	ParseHelper_FixTruncatedFloatString(mXmlParser->getAttributeValue(pAttrIdx), val);
-	fast_atoreal_move(val.c_str(), tvalf, false);
-
-	return tvalf;
-}
-
-uint32_t AMFImporter::XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx) {
-	return strtoul10(mXmlParser->getAttributeValue(pAttrIdx));
-}
-
-float AMFImporter::XML_ReadNode_GetVal_AsFloat() {
-	std::string val;
-	float tvalf;
-
-	if (!mXmlParser->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. No data, seems file is corrupt.");
-	if (mXmlParser->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. Invalid type of XML element, seems file is corrupt.");
-
-	ParseHelper_FixTruncatedFloatString(mXmlParser->getNodeData(), val);
-	fast_atoreal_move(val.c_str(), tvalf, false);
-
-	return tvalf;
-}
-
-uint32_t AMFImporter::XML_ReadNode_GetVal_AsU32() {
-	if (!mXmlParser->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. No data, seems file is corrupt.");
-	if (mXmlParser->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. Invalid type of XML element, seems file is corrupt.");
-
-	return strtoul10(mXmlParser->getNodeData());
-}
-
-void AMFImporter::XML_ReadNode_GetVal_AsString(std::string &pValue) {
-	if (!mXmlParser->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsString. No data, seems file is corrupt.");
-	if (mXmlParser->getNodeType() != irr::io::EXN_TEXT)
-		throw DeadlyImportError("XML_ReadNode_GetVal_AsString. Invalid type of XML element, seems file is corrupt.");
-
-	pValue = mXmlParser->getNodeData();
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: parse set ***********************************************************/
-/*********************************************************************************************************************************************/
-
-void AMFImporter::ParseHelper_Node_Enter(CAMFImporter_NodeElement *pNode) {
-	mNodeElement_Cur->Child.push_back(pNode); // add new element to current element child list.
-	mNodeElement_Cur = pNode; // switch current element to new one.
-}
-
-void AMFImporter::ParseHelper_Node_Exit() {
-	// check if we can walk up.
-	if (mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent;
-}
-
-void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString) {
-	size_t instr_len;
-
-	pOutString.clear();
-	instr_len = strlen(pInStr);
-	if (!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]);
-		}
-	}
-}
-
-static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
-	return (isalnum(pChar) || (pChar == '+') || (pChar == '/'));
-}
-
 void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const {
 	// With help from
 	// René Nyffenegger http://www.adp-gmbh.ch/cpp/common/base64.html
@@ -394,11 +163,11 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
 	// start reading
 	// search for root tag <amf>
 
-	if (!root->getNode()->find_child("amf")) {
+	if (!root->find_child("amf")) {
 		throw DeadlyImportError("Root node \"amf\" not found.");
 	}
 
-	ParseNode_Root(root);
+	ParseNode_Root(*root);
 
 	delete mXmlParser;
 	mXmlParser = nullptr;
@@ -411,13 +180,12 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
 // </amf>
 // Root XML element.
 // Multi elements - No.
-void AMFImporter::ParseNode_Root(XmlNode *root) {
+void AMFImporter::ParseNode_Root(XmlNode &root) {
 	std::string unit, version;
-	CAMFImporter_NodeElement *ne(nullptr);
+	AMFNodeElementBase *ne(nullptr);
 
 	// Read attributes for node <amf>.
-	pugi::xml_node *node(root->getNode());
-	for (pugi::xml_attribute_iterator ait = node->attributes_begin(); ait != node->attributes_end(); ++ait) {
+	for (pugi::xml_attribute_iterator ait = root.attributes_begin(); ait != root.attributes_end(); ++ait) {
 		if (ait->name() == "unit") {
 			unit = ait->as_string();
 		} else if (ait->name() == "version") {
@@ -425,69 +193,37 @@ void AMFImporter::ParseNode_Root(XmlNode *root) {
 		}
 	}
 
-	/*MACRO_ATTRREAD_LOOPBEG;
-	MACRO_ATTRREAD_CHECK_RET("unit", unit, mReader->getAttributeValue);
-	MACRO_ATTRREAD_CHECK_RET("version", version, mReader->getAttributeValue);
-	MACRO_ATTRREAD_LOOPEND_WSKIP;*/
-
 	// Check attributes
 	if (!mUnit.empty()) {
 		if ((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) {
-			Throw_IncorrectAttrValue("unit");
+			throw DeadlyImportError("Root node does not contain any units.");
 		}
 	}
 
 	// create root node element.
-	ne = new CAMFImporter_NodeElement_Root(nullptr);
+	ne = new AMFRoot(nullptr);
 
 	// set first "current" element
 	mNodeElement_Cur = ne;
 
 	// and assign attributes values
-	((CAMFImporter_NodeElement_Root *)ne)->Unit = unit;
-	((CAMFImporter_NodeElement_Root *)ne)->Version = version;
+	((AMFRoot *)ne)->Unit = unit;
+	((AMFRoot *)ne)->Version = version;
 
 	// Check for child nodes
 	for (pugi::xml_node child : node->children()) {
 		if (child.name() == "object") {
-			ParseNode_Object(&child);
+			ParseNode_Object(child);
 		} else if (child.name() == "material") {
-			ParseNode_Material();
+			ParseNode_Material(child);
 		} else if (child.name() == "texture") {
-			ParseNode_Texture();
+			ParseNode_Texture(child);
 		} else if (child.name() == "constellation") {
-			ParseNode_Constellation();
+			ParseNode_Constellation(child);
 		} else if (child.name() == "metadata") {
-			ParseNode_Metadata();
+			ParseNode_Metadata(child);
 		}
 	}
-
-	/*if (!mReader->isEmptyElement()) {
-		MACRO_NODECHECK_LOOPBEGIN("amf");
-		if (XML_CheckNode_NameEqual("object")) {
-			ParseNode_Object();
-			continue;
-		}
-		if (XML_CheckNode_NameEqual("material")) {
-			ParseNode_Material();
-			continue;
-		}
-		if (XML_CheckNode_NameEqual("texture")) {
-			ParseNode_Texture();
-			continue;
-		}
-		if (XML_CheckNode_NameEqual("constellation")) {
-			ParseNode_Constellation();
-			continue;
-		}
-		if (XML_CheckNode_NameEqual("metadata")) {
-			ParseNode_Metadata();
-			continue;
-		}
-		MACRO_NODECHECK_LOOPEND("amf");
-		mNodeElement_Cur = ne; // force restore "current" element
-	} // if(!mReader->isEmptyElement())*/
-
 	mNodeElement_List.push_back(ne); // add to node element list because its a new object in graph.
 }
 
@@ -498,39 +234,21 @@ void AMFImporter::ParseNode_Root(XmlNode *root) {
 // A collection of objects or constellations with specific relative locations.
 // Multi elements - Yes.
 // Parent element - <amf>.
-void AMFImporter::ParseNode_Constellation() {
-	std::string id;
-	CAMFImporter_NodeElement *ne(nullptr);
-
-	// Read attributes for node <constellation>.
-	MACRO_ATTRREAD_LOOPBEG;
-	MACRO_ATTRREAD_CHECK_RET("id", id, mXmlParser->getAttributeValue);
-	MACRO_ATTRREAD_LOOPEND;
+void AMFImporter::ParseNode_Constellation(XmlNode &root) {
+	std::string id = root.attribute("id").as_string();
 
 	// create and if needed - define new grouping object.
-	ne = new CAMFImporter_NodeElement_Constellation(mNodeElement_Cur);
+	AMFNodeElementBase *ne = new AMFConstellation(mNodeElement_Cur);
 
-	CAMFImporter_NodeElement_Constellation &als = *((CAMFImporter_NodeElement_Constellation *)ne); // alias for convenience
+	AMFConstellation &als = *((AMFConstellation *)ne); // alias for convenience
 
-	if (!id.empty()) als.ID = id;
-	// Check for child nodes
-	if (!mXmlParser->isEmptyElement()) {
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("constellation");
-		if (XML_CheckNode_NameEqual("instance")) {
-			ParseNode_Instance();
-			continue;
-		}
-		if (XML_CheckNode_NameEqual("metadata")) {
-			ParseNode_Metadata();
-			continue;
+	for (pugi::xml_node &child : root.children()) {
+		if (child.name() == "instance") {
+			ParseNode_Instance(child);
+		} else if (child.name() == "metadata") {
+			ParseNode_Metadata(child);
 		}
-		MACRO_NODECHECK_LOOPEND("constellation");
-		ParseHelper_Node_Exit();
-	} // if(!mReader->isEmptyElement())
-	else {
-		mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
-	} // if(!mReader->isEmptyElement()) else
+	}
 
 	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
 }
@@ -542,21 +260,17 @@ void AMFImporter::ParseNode_Constellation() {
 // A collection of objects or constellations with specific relative locations.
 // Multi elements - Yes.
 // Parent element - <amf>.
-void AMFImporter::ParseNode_Instance() {
-	std::string objectid;
-	CAMFImporter_NodeElement *ne(nullptr);
+void AMFImporter::ParseNode_Instance(XmlNode &root) {
+	std::string objectid = root.attribute("objectid").as_string();
 
-	// Read attributes for node <constellation>.
-	MACRO_ATTRREAD_LOOPBEG;
-	MACRO_ATTRREAD_CHECK_RET("objectid", objectid, mXmlParser->getAttributeValue);
-	MACRO_ATTRREAD_LOOPEND;
-
-	// used object id must be defined, check that.
-	if (objectid.empty()) throw DeadlyImportError("\"objectid\" in <instance> must be defined.");
+        // used object id must be defined, check that.
+	if (objectid.empty()) {
+		throw DeadlyImportError("\"objectid\" in <instance> must be defined.");
+	}
 	// create and define new grouping object.
-	ne = new CAMFImporter_NodeElement_Instance(mNodeElement_Cur);
+	AMFNodeElementBase *ne = new AMFInstance(mNodeElement_Cur);
 
-	CAMFImporter_NodeElement_Instance &als = *((CAMFImporter_NodeElement_Instance *)ne); // alias for convenience
+	AMFInstance &als = *((AMFInstance *)ne); // alias for convenience
 
 	als.ObjectID = objectid;
 	// Check for child nodes
@@ -594,70 +308,38 @@ void AMFImporter::ParseNode_Instance() {
 // An object definition.
 // Multi elements - Yes.
 // Parent element - <amf>.
-void AMFImporter::ParseNode_Object(XmlNode *nodeInst) {
+void AMFImporter::ParseNode_Object(XmlNode &node) {
+
 	std::string id;
-	CAMFImporter_NodeElement *ne(nullptr);
-	pugi::xml_node *node = nodeInst->getNode();
-	for (pugi::xml_attribute_iterator ait = node->attributes_begin(); ait != node->attributes_end(); ++ait) {
+	for (pugi::xml_attribute_iterator ait = node.attributes_begin(); ait != node.attributes_end(); ++ait) {
 		if (ait->name() == "id") {
 			id = ait->as_string();
 		}
 	}
 	// Read attributes for node <object>.
-	/*MACRO_ATTRREAD_LOOPBEG;
-	MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
-	MACRO_ATTRREAD_LOOPEND;*/
 
 	// create and if needed - define new geometry object.
-	ne = new CAMFImporter_NodeElement_Object(mNodeElement_Cur);
+	AMFNodeElementBase *ne = new AMFObject(mNodeElement_Cur);
 
-	CAMFImporter_NodeElement_Object &als = *((CAMFImporter_NodeElement_Object *)ne); // alias for convenience
+	AMFObject &als = *((AMFObject *)ne); // alias for convenience
 
 	if (!id.empty()) {
 		als.ID = id;
 	}
 
 	// Check for child nodes
-
-	for (pugi::xml_node_iterator it = node->children().begin(); it != node->children->end(); ++it) {
+	for (pugi::xml_node_iterator it = node.children().begin(); it != node.children->end(); ++it) {
 		bool col_read = false;
 		if (it->name() == "mesh") {
 			ParseNode_Mesh(*it);
 		} else if (it->name() == "metadata") {
 			ParseNode_Metadata(*it);
-        }
-	}
-	if (!mXmlParser->isEmptyElement()) {
-		bool col_read = false;
-
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("object");
-		if (XML_CheckNode_NameEqual("color")) {
-			// Check if color already defined for object.
-			if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <object>.");
-			// read data and set flag about it
-			ParseNode_Color();
-			col_read = true;
-
-			continue;
-		}
-
-		if (XML_CheckNode_NameEqual("mesh")) {
-			ParseNode_Mesh();
-			continue;
+		} else if (it->name() == "color") {
+			ParseNode_Color(*it);
 		}
-		if (XML_CheckNode_NameEqual("metadata")) {
-			ParseNode_Metadata();
-			continue;
-		}
-		MACRO_NODECHECK_LOOPEND("object");
-		ParseHelper_Node_Exit();
-	} // if(!mReader->isEmptyElement())
-	else {
-		mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
-	} // if(!mReader->isEmptyElement()) else
+	}
 
-	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
+	mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
 }
 
 // <metadata
@@ -680,7 +362,7 @@ void AMFImporter::ParseNode_Object(XmlNode *nodeInst) {
 // "Volume" - specifies the total volume of the entity, in the entity's unit system, to be used for verification (object and volume only)
 void AMFImporter::ParseNode_Metadata() {
 	std::string type, value;
-	CAMFImporter_NodeElement *ne(nullptr);
+	AMFNodeElementBase *ne(nullptr);
 
 	// read attribute
 	MACRO_ATTRREAD_LOOPBEG;
@@ -689,9 +371,9 @@ void AMFImporter::ParseNode_Metadata() {
 	// and value of node.
 	value = mXmlParser->getNodeData();
 	// Create node element and assign read data.
-	ne = new CAMFImporter_NodeElement_Metadata(mNodeElement_Cur);
-	((CAMFImporter_NodeElement_Metadata *)ne)->Type = type;
-	((CAMFImporter_NodeElement_Metadata *)ne)->Value = value;
+	ne = new AMFMetadata(mNodeElement_Cur);
+	((AMFMetadata *)ne)->Type = type;
+	((AMFMetadata *)ne)->Value = value;
 	mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
 	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
 }
@@ -716,8 +398,8 @@ bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool p
 	return false;
 }
 
-void AMFImporter::GetExtensionList(std::set<std::string> &pExtensionList) {
-	pExtensionList.insert("amf");
+void AMFImporter::GetExtensionList(std::set<std::string> &extensionList) {
+	extensionList.insert("amf");
 }
 
 const aiImporterDesc *AMFImporter::GetInfo() const {
@@ -725,10 +407,293 @@ const aiImporterDesc *AMFImporter::GetInfo() const {
 }
 
 void AMFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
-	Clear(); // delete old graph.
+	Clear();
+
 	ParseFile(pFile, pIOHandler);
+
 	Postprocess_BuildScene(pScene);
-	// scene graph is ready, exit.
+}
+
+void AMFImporter::ParseNode_Mesh(XmlNode &node) {
+	AMFNodeElementBase *ne;
+
+	if (node.empty()) {
+		return;
+	}
+
+	for (pugi::xml_node &child : node.children()) {
+		if (child.name() == "vertices") {
+			ParseNode_Vertices(child);
+		}
+	}
+	// create new mesh object.
+	ne = new AMFMesh(mNodeElement_Cur);
+	// Check for child nodes
+	if (!mXmlParser->isEmptyElement()) {
+		bool vert_read = false;
+
+		ParseHelper_Node_Enter(ne);
+		MACRO_NODECHECK_LOOPBEGIN("mesh");
+		if (XML_CheckNode_NameEqual("vertices")) {
+			// Check if data already defined.
+			if (vert_read) Throw_MoreThanOnceDefined("vertices", "Only one vertices set can be defined for <mesh>.");
+			// read data and set flag about it
+			vert_read = true;
+
+			continue;
+		}
+
+		if (XML_CheckNode_NameEqual("volume")) {
+			ParseNode_Volume();
+			continue;
+		}
+		MACRO_NODECHECK_LOOPEND("mesh");
+		ParseHelper_Node_Exit();
+	} // if(!mReader->isEmptyElement())
+	else {
+		mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
+	} // if(!mReader->isEmptyElement()) else
+
+	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
+}
+
+// <vertices>
+// </vertices>
+// The list of vertices to be used in defining triangles.
+// Multi elements - No.
+// Parent element - <mesh>.
+void AMFImporter::ParseNode_Vertices(XmlNode &node) {
+	AMFNodeElementBase *ne = new AMFVertices(mNodeElement_Cur);
+
+	for (pugi::xml_node &child : node.children()) {
+		if (child.name() == "vertices") {
+			ParseNode_Vertex(child);
+		}
+	}
+	// Check for child nodes
+
+	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
+}
+
+// <vertex>
+// </vertex>
+// A vertex to be referenced in triangles.
+// Multi elements - Yes.
+// Parent element - <vertices>.
+void AMFImporter::ParseNode_Vertex() {
+	AMFNodeElementBase *ne;
+
+	// create new mesh object.
+	ne = new AMFVertex(mNodeElement_Cur);
+	// Check for child nodes
+	if (!mXmlParser->isEmptyElement()) {
+		bool col_read = false;
+		bool coord_read = false;
+
+		ParseHelper_Node_Enter(ne);
+		MACRO_NODECHECK_LOOPBEGIN("vertex");
+		if (XML_CheckNode_NameEqual("color")) {
+			// Check if data already defined.
+			if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <vertex>.");
+			// read data and set flag about it
+			ParseNode_Color();
+			col_read = true;
+
+			continue;
+		}
+
+		if (XML_CheckNode_NameEqual("coordinates")) {
+			// Check if data already defined.
+			if (coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for <vertex>.");
+			// read data and set flag about it
+			ParseNode_Coordinates();
+			coord_read = true;
+
+			continue;
+		}
+
+		if (XML_CheckNode_NameEqual("metadata")) {
+			ParseNode_Metadata();
+			continue;
+		}
+		MACRO_NODECHECK_LOOPEND("vertex");
+		ParseHelper_Node_Exit();
+	} // if(!mReader->isEmptyElement())
+	else {
+		mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
+	} // if(!mReader->isEmptyElement()) else
+
+	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
+}
+
+// <coordinates>
+// </coordinates>
+// Specifies the 3D location of this vertex.
+// Multi elements - No.
+// Parent element - <vertex>.
+//
+// Children elements:
+//   <x>, <y>, <z>
+//   Multi elements - No.
+//   X, Y, or Z coordinate, respectively, of a vertex position in space.
+void AMFImporter::ParseNode_Coordinates() {
+	AMFNodeElementBase *ne;
+
+	// create new color object.
+	ne = new AMFCoordinates(mNodeElement_Cur);
+
+	AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
+
+	// Check for child nodes
+	if (!mXmlParser->isEmptyElement()) {
+		bool read_flag[3] = { false, false, false };
+
+		ParseHelper_Node_Enter(ne);
+		MACRO_NODECHECK_LOOPBEGIN("coordinates");
+		MACRO_NODECHECK_READCOMP_F("x", read_flag[0], als.Coordinate.x);
+		MACRO_NODECHECK_READCOMP_F("y", read_flag[1], als.Coordinate.y);
+		MACRO_NODECHECK_READCOMP_F("z", read_flag[2], als.Coordinate.z);
+		MACRO_NODECHECK_LOOPEND("coordinates");
+		ParseHelper_Node_Exit();
+		// check that all components was defined
+		if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined.");
+
+	} // if(!mReader->isEmptyElement())
+	else {
+		mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
+	} // if(!mReader->isEmptyElement()) else
+
+	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
+}
+
+// <volume
+// materialid="" - Which material to use.
+// type=""       - What this volume describes can be “region” or “support”. If none specified, “object” is assumed. If support, then the geometric
+//                 requirements 1-8 listed in section 5 do not need to be maintained.
+// >
+// </volume>
+// Defines a volume from the established vertex list.
+// Multi elements - Yes.
+// Parent element - <mesh>.
+void AMFImporter::ParseNode_Volume() {
+	std::string materialid;
+	std::string type;
+	AMFNodeElementBase *ne;
+
+	// Read attributes for node <color>.
+	MACRO_ATTRREAD_LOOPBEG;
+	MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mXmlParser->getAttributeValue);
+	MACRO_ATTRREAD_CHECK_RET("type", type, mXmlParser->getAttributeValue);
+	MACRO_ATTRREAD_LOOPEND;
+
+	// create new object.
+	ne = new AMFVolume(mNodeElement_Cur);
+	// and assign read data
+	((AMFVolume *)ne)->MaterialID = materialid;
+	((AMFVolume *)ne)->Type = type;
+	// Check for child nodes
+	if (!mXmlParser->isEmptyElement()) {
+		bool col_read = false;
+
+		ParseHelper_Node_Enter(ne);
+		MACRO_NODECHECK_LOOPBEGIN("volume");
+		if (XML_CheckNode_NameEqual("color")) {
+			// Check if data already defined.
+			if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <volume>.");
+			// read data and set flag about it
+			ParseNode_Color();
+			col_read = true;
+
+			continue;
+		}
+
+		if (XML_CheckNode_NameEqual("triangle")) {
+			ParseNode_Triangle();
+			continue;
+		}
+		if (XML_CheckNode_NameEqual("metadata")) {
+			ParseNode_Metadata();
+			continue;
+		}
+		MACRO_NODECHECK_LOOPEND("volume");
+		ParseHelper_Node_Exit();
+	} // if(!mReader->isEmptyElement())
+	else {
+		mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
+	} // if(!mReader->isEmptyElement()) else
+
+	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
+}
+
+// <triangle>
+// </triangle>
+// Defines a 3D triangle from three vertices, according to the right-hand rule (counter-clockwise when looking from the outside).
+// Multi elements - Yes.
+// Parent element - <volume>.
+//
+// Children elements:
+//   <v1>, <v2>, <v3>
+//   Multi elements - No.
+//   Index of the desired vertices in a triangle or edge.
+void AMFImporter::ParseNode_Triangle() {
+	AMFNodeElementBase *ne;
+
+	// create new color object.
+	ne = new AMFTriangle(mNodeElement_Cur);
+
+	AMFTriangle &als = *((AMFTriangle *)ne); // alias for convenience
+
+	// Check for child nodes
+	if (!mXmlParser->isEmptyElement()) {
+		bool col_read = false, tex_read = false;
+		bool read_flag[3] = { false, false, false };
+
+		ParseHelper_Node_Enter(ne);
+		MACRO_NODECHECK_LOOPBEGIN("triangle");
+		if (XML_CheckNode_NameEqual("color")) {
+			// Check if data already defined.
+			if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <triangle>.");
+			// read data and set flag about it
+			ParseNode_Color();
+			col_read = true;
+
+			continue;
+		}
+
+		if (XML_CheckNode_NameEqual("texmap")) // new name of node: "texmap".
+		{
+			// Check if data already defined.
+			if (tex_read) Throw_MoreThanOnceDefined("texmap", "Only one texture coordinate can be defined for <triangle>.");
+			// read data and set flag about it
+			ParseNode_TexMap();
+			tex_read = true;
+
+			continue;
+		} else if (XML_CheckNode_NameEqual("map")) // old name of node: "map".
+		{
+			// Check if data already defined.
+			if (tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for <triangle>.");
+			// read data and set flag about it
+			ParseNode_TexMap(true);
+			tex_read = true;
+
+			continue;
+		}
+
+		//		MACRO_NODECHECK_READCOMP_U32("v1", read_flag[0], als.V[0]);
+		//		MACRO_NODECHECK_READCOMP_U32("v2", read_flag[1], als.V[1]);
+		//		MACRO_NODECHECK_READCOMP_U32("v3", read_flag[2], als.V[2]);
+		//		MACRO_NODECHECK_LOOPEND("triangle");
+		ParseHelper_Node_Exit();
+		// check that all components was defined
+		if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined.");
+
+	} // if(!mReader->isEmptyElement())
+	else {
+		mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
+	} // if(!mReader->isEmptyElement()) else
+
+	mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
 }
 
 } // namespace Assimp

+ 15 - 147
code/AMF/AMFImporter.hpp

@@ -112,8 +112,8 @@ private:
     /// Data type for post-processing step. More suitable container for material.
     struct SPP_Material {
         std::string ID;///< Material ID.
-        std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
-        CAMFImporter_NodeElement_Color* Color;///< Color of material.
+        std::list<AMFMetadata*> Metadata;///< Metadata of material.
+        AMFColor* Color;///< Color of material.
         std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
 
         /// Return color calculated for specified coordinate.
@@ -136,56 +136,20 @@ private:
     /// Data type for post-processing step. Contain face data.
     struct SComplexFace {
         aiFace Face;///< Face vertices.
-        const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
-        const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
+        const AMFColor* Color;///< Face color. Equal to nullptr if color is not set for the face.
+        const AMFTexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
     };
 
 	/// Clear all temporary data.
 	void Clear();
 
-	/***********************************************/
-	/************* Functions: find set *************/
-	/***********************************************/
-
-	/// Find specified node element in node elements list ( \ref mNodeElement_List).
-	/// \param [in] pID - ID(name) of requested node element.
-	/// \param [in] pType - type of node element.
-	/// \param [out] pNode - pointer to pointer to item found.
-	/// \return true - if the node element is found, else - false.
-	bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const;
-
-	/// Find requested aiNode in node list.
-	/// \param [in] pID - ID(name) of requested node.
-	/// \param [in] pNodeList - list of nodes where to find the node.
-	/// \param [out] pNode - pointer to pointer to item found.
-	/// \return true - if the node is found, else - false.
-	bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const;
-
-	/// Find material in list for converted materials. Use at postprocessing step.
-	/// \param [in] pID - material ID.
-	/// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material).
-	/// \return true - if the material is found, else - false.
-	bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const;
-
-    /// Find texture in list of converted textures. Use at postprocessing step,
-	/// \param [in] pID_R - ID of source "red" texture.
-	/// \param [in] pID_G - ID of source "green" texture.
-	/// \param [in] pID_B - ID of source "blue" texture.
-	/// \param [in] pID_A - ID of source "alpha" texture. Use empty string to find RGB-texture.
-	/// \param [out] pConvertedTextureIndex - pointer where index in list of found texture will be written. If equivalent to nullptr then nothing will be
-	/// written.
-	/// \return true - if the texture is found, else - false.
-	bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A,
-								uint32_t* pConvertedTextureIndex = nullptr) const;
-
-
 	/// Get data stored in <vertices> and place it to arrays.
 	/// \param [in] pNodeElement - reference to node element which kept <object> data.
 	/// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>.
 	/// \param [in] pVertexColorArray - reference to vertices colors for all <vertex's. If color for vertex is not set then corresponding member of array
 	/// contain nullptr.
-	void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
-												std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const;
+	void PostprocessHelper_CreateMeshDataArray(const AMFMesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
+												std::vector<AMFColor*>& pVertexColorArray) const;
 
 	/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
 	/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
@@ -207,13 +171,13 @@ private:
 	/// Check if child elements of node element is metadata and add it to scene node.
 	/// \param [in] pMetadataList - reference to list with collected metadata.
 	/// \param [out] pSceneNode - scene node in which metadata will be added.
-	void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const;
+	void Postprocess_AddMetadata(const std::list<AMFMetadata*>& pMetadataList, aiNode& pSceneNode) const;
 
 	/// To create aiMesh and aiNode for it from <object>.
 	/// \param [in] pNodeElement - reference to node element which kept <object> data.
 	/// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
 	/// \param [out] pSceneNode - pointer to place where new aiNode will be created.
-	void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode);
+	void Postprocess_BuildNodeAndObject(const AMFObject& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode);
 
 	/// Create mesh for every <volume> in <mesh>.
 	/// \param [in] pNodeElement - reference to node element which kept <mesh> data.
@@ -224,119 +188,23 @@ private:
 	/// \param [in] pMaterialList - reference to a list with defined materials.
 	/// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
 	/// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's.
-	void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
-									const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor,
+	void Postprocess_BuildMeshSet(const AMFMesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
+									const std::vector<AMFColor*>& pVertexColorArray, const AMFColor* pObjectColor,
 									std::list<aiMesh*>& pMeshList, aiNode& pSceneNode);
 
 	/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
 	/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
-	void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial);
+	void Postprocess_BuildMaterial(const AMFMaterial& pMaterial);
 
 	/// Create and add to aiNode's list new part of scene graph defined by <constellation>.
 	/// \param [in] pConstellation - reference to <constellation> node.
 	/// \param [out] pNodeList - reference to aiNode's list.
-	void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const;
+	void Postprocess_BuildConstellation(AMFConstellation& pConstellation, std::list<aiNode*>& pNodeList) const;
 
 	/// Build Assimp scene graph in aiScene from collected data.
 	/// \param [out] pScene - pointer to aiScene where tree will be built.
 	void Postprocess_BuildScene(aiScene* pScene);
 
-
-	/// Call that function when close tag of node not found and exception must be raised.
-	/// E.g.:
-	/// <amf>
-	///     <object>
-	/// </amf> <!--- object not closed --->
-	/// \throw DeadlyImportError.
-	/// \param [in] pNode - node name in which exception happened.
-	void Throw_CloseNotFound(const std::string& pNode);
-
-	/// Call that function when attribute name is incorrect and exception must be raised.
-	/// \param [in] pAttrName - attribute name.
-	/// \throw DeadlyImportError.
-	void Throw_IncorrectAttr(const std::string &nodeName, const std::string& pAttrName);
-
-	/// Call that function when attribute value is incorrect and exception must be raised.
-	/// \param [in] pAttrName - attribute name.
-	/// \throw DeadlyImportError.
-	void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
-
-	/// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
-	/// E.g.:
-	/// <object>
-	///     <color>...    <!--- color defined --->
-	///     <color>...    <!--- color defined again --->
-	/// </object>
-	/// \throw DeadlyImportError.
-	/// \param [in] pNodeType - type of node which defined one more time.
-	/// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
-	void Throw_MoreThanOnceDefined(const std::string &nodeType, const std::string &nodeName, const std::string &pDescription);
-
-	/// Call that function when referenced element ID are not found in graph and exception must be raised.
-	/// \param [in] pID - ID of of element which not found.
-	/// \throw DeadlyImportError.
-	void Throw_ID_NotFound(const std::string& pID) const;
-
-	/// Check if current node have children: <node>...</node>. If not then exception will thrown.
-	void XML_CheckNode_MustHaveChildren( XmlNode &node);
-
-	/// 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;
-        //mReader->mDoc.
-    //}
-
-	/// 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(XmlNode *node, 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.
-	uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx);
-
-	/// Read node value.
-	/// \return read data.
-	float XML_ReadNode_GetVal_AsFloat();
-
-	/// Read node value.
-	/// \return read data.
-	uint32_t XML_ReadNode_GetVal_AsU32();
-
-	/// Read node value.
-	/// \return read data.
-	void XML_ReadNode_GetVal_AsString(std::string& pValue);
-
-	/// 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(CAMFImporter_NodeElement* pNode);
-
-	/// This function must be called when exiting from grouping node. \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);
-
 	/// Decode Base64-encoded data.
 	/// \param [in] pInputBase64 - reference to input Base64-encoded string.
 	/// \param [out] pOutputData - reference to output array for decoded data.
@@ -389,7 +257,7 @@ private:
 
 	/// Parse <texmap> of <map> node of the file.
 	/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
-	void ParseNode_TexMap(const bool pUseOldName = false);
+	void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false);
 
 public:
 	/// Default constructor.
@@ -419,8 +287,8 @@ public:
 private:
     static const aiImporterDesc Description;
 
-    CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
-    std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
+    AMFNodeElementBase* mNodeElement_Cur;///< Current element.
+    std::list<AMFNodeElementBase*> mNodeElement_List;///< All elements of scene graph.
 	XmlParser *mXmlParser;
     //irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
     std::string mUnit;

+ 0 - 357
code/AMF/AMFImporter_Geometry.cpp

@@ -1,357 +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 AMFImporter_Geometry.cpp
-/// \brief Parsing data from geometry nodes.
-/// \date 2016
-/// \author [email protected]
-
-#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
-
-#include "AMFImporter.hpp"
-#include "AMFImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-// <mesh>
-// </mesh>
-// A 3D mesh hull.
-// Multi elements - Yes.
-// Parent element - <object>.
-void AMFImporter::ParseNode_Mesh()
-{
-    CAMFImporter_NodeElement* ne;
-
-	// create new mesh object.
-	ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur);
-	// Check for child nodes
-	if(!mXmlParser->isEmptyElement())
-	{
-		bool vert_read = false;
-
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("mesh");
-			if(XML_CheckNode_NameEqual("vertices"))
-			{
-				// Check if data already defined.
-				if(vert_read) Throw_MoreThanOnceDefined("vertices", "Only one vertices set can be defined for <mesh>.");
-				// read data and set flag about it
-				ParseNode_Vertices();
-				vert_read = true;
-
-				continue;
-			}
-
-			if(XML_CheckNode_NameEqual("volume")) { ParseNode_Volume(); continue; }
-		MACRO_NODECHECK_LOOPEND("mesh");
-		ParseHelper_Node_Exit();
-	}// if(!mReader->isEmptyElement())
-	else
-	{
-		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
-	}// if(!mReader->isEmptyElement()) else
-
-	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <vertices>
-// </vertices>
-// The list of vertices to be used in defining triangles.
-// Multi elements - No.
-// Parent element - <mesh>.
-void AMFImporter::ParseNode_Vertices()
-{
-CAMFImporter_NodeElement* ne;
-
-	// create new mesh object.
-	ne = new CAMFImporter_NodeElement_Vertices(mNodeElement_Cur);
-	// Check for child nodes
-	if(!mXmlParser->isEmptyElement())
-	{
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("vertices");
-			if(XML_CheckNode_NameEqual("vertex")) { ParseNode_Vertex(); continue; }
-		MACRO_NODECHECK_LOOPEND("vertices");
-		ParseHelper_Node_Exit();
-	}// if(!mReader->isEmptyElement())
-	else
-	{
-		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
-	}// if(!mReader->isEmptyElement()) else
-
-	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <vertex>
-// </vertex>
-// A vertex to be referenced in triangles.
-// Multi elements - Yes.
-// Parent element - <vertices>.
-void AMFImporter::ParseNode_Vertex()
-{
-CAMFImporter_NodeElement* ne;
-
-	// create new mesh object.
-	ne = new CAMFImporter_NodeElement_Vertex(mNodeElement_Cur);
-	// Check for child nodes
-	if(!mXmlParser->isEmptyElement())
-	{
-		bool col_read = false;
-		bool coord_read = false;
-
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("vertex");
-			if(XML_CheckNode_NameEqual("color"))
-			{
-				// Check if data already defined.
-				if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <vertex>.");
-				// read data and set flag about it
-				ParseNode_Color();
-				col_read = true;
-
-				continue;
-			}
-
-			if(XML_CheckNode_NameEqual("coordinates"))
-			{
-				// Check if data already defined.
-				if(coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for <vertex>.");
-				// read data and set flag about it
-				ParseNode_Coordinates();
-				coord_read = true;
-
-				continue;
-			}
-
-			if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
-		MACRO_NODECHECK_LOOPEND("vertex");
-		ParseHelper_Node_Exit();
-	}// if(!mReader->isEmptyElement())
-	else
-	{
-		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
-	}// if(!mReader->isEmptyElement()) else
-
-	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <coordinates>
-// </coordinates>
-// Specifies the 3D location of this vertex.
-// Multi elements - No.
-// Parent element - <vertex>.
-//
-// Children elements:
-//   <x>, <y>, <z>
-//   Multi elements - No.
-//   X, Y, or Z coordinate, respectively, of a vertex position in space.
-void AMFImporter::ParseNode_Coordinates()
-{
-CAMFImporter_NodeElement* ne;
-
-	// create new color object.
-	ne = new CAMFImporter_NodeElement_Coordinates(mNodeElement_Cur);
-
-	CAMFImporter_NodeElement_Coordinates& als = *((CAMFImporter_NodeElement_Coordinates*)ne);// alias for convenience
-
-	// Check for child nodes
-	if(!mXmlParser->isEmptyElement())
-	{
-		bool read_flag[3] = { false, false, false };
-
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("coordinates");
-			MACRO_NODECHECK_READCOMP_F("x", read_flag[0], als.Coordinate.x);
-			MACRO_NODECHECK_READCOMP_F("y", read_flag[1], als.Coordinate.y);
-			MACRO_NODECHECK_READCOMP_F("z", read_flag[2], als.Coordinate.z);
-		MACRO_NODECHECK_LOOPEND("coordinates");
-		ParseHelper_Node_Exit();
-		// check that all components was defined
-		if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined.");
-
-	}// if(!mReader->isEmptyElement())
-	else
-	{
-		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
-	}// if(!mReader->isEmptyElement()) else
-
-	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <volume
-// materialid="" - Which material to use.
-// type=""       - What this volume describes can be “region” or “support”. If none specified, “object” is assumed. If support, then the geometric
-//                 requirements 1-8 listed in section 5 do not need to be maintained.
-// >
-// </volume>
-// Defines a volume from the established vertex list.
-// Multi elements - Yes.
-// Parent element - <mesh>.
-void AMFImporter::ParseNode_Volume()
-{
-std::string materialid;
-std::string type;
-CAMFImporter_NodeElement* ne;
-
-	// Read attributes for node <color>.
-	MACRO_ATTRREAD_LOOPBEG;
-		MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mXmlParser->getAttributeValue);
-		MACRO_ATTRREAD_CHECK_RET("type", type, mXmlParser->getAttributeValue);
-	MACRO_ATTRREAD_LOOPEND;
-
-	// create new object.
-	ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur);
-	// and assign read data
-	((CAMFImporter_NodeElement_Volume*)ne)->MaterialID = materialid;
-	((CAMFImporter_NodeElement_Volume*)ne)->Type = type;
-	// Check for child nodes
-	if(!mXmlParser->isEmptyElement())
-	{
-		bool col_read = false;
-
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("volume");
-			if(XML_CheckNode_NameEqual("color"))
-			{
-				// Check if data already defined.
-				if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <volume>.");
-				// read data and set flag about it
-				ParseNode_Color();
-				col_read = true;
-
-				continue;
-			}
-
-			if(XML_CheckNode_NameEqual("triangle")) { ParseNode_Triangle(); continue; }
-			if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
-		MACRO_NODECHECK_LOOPEND("volume");
-		ParseHelper_Node_Exit();
-	}// if(!mReader->isEmptyElement())
-	else
-	{
-		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
-	}// if(!mReader->isEmptyElement()) else
-
-	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <triangle>
-// </triangle>
-// Defines a 3D triangle from three vertices, according to the right-hand rule (counter-clockwise when looking from the outside).
-// Multi elements - Yes.
-// Parent element - <volume>.
-//
-// Children elements:
-//   <v1>, <v2>, <v3>
-//   Multi elements - No.
-//   Index of the desired vertices in a triangle or edge.
-void AMFImporter::ParseNode_Triangle()
-{
-CAMFImporter_NodeElement* ne;
-
-	// create new color object.
-	ne = new CAMFImporter_NodeElement_Triangle(mNodeElement_Cur);
-
-	CAMFImporter_NodeElement_Triangle& als = *((CAMFImporter_NodeElement_Triangle*)ne);// alias for convenience
-
-	// Check for child nodes
-	if(!mXmlParser->isEmptyElement())
-	{
-		bool col_read = false, tex_read = false;
-		bool read_flag[3] = { false, false, false };
-
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("triangle");
-			if(XML_CheckNode_NameEqual("color"))
-			{
-				// Check if data already defined.
-				if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <triangle>.");
-				// read data and set flag about it
-				ParseNode_Color();
-				col_read = true;
-
-				continue;
-			}
-
-			if(XML_CheckNode_NameEqual("texmap"))// new name of node: "texmap".
-			{
-				// Check if data already defined.
-				if(tex_read) Throw_MoreThanOnceDefined("texmap", "Only one texture coordinate can be defined for <triangle>.");
-				// read data and set flag about it
-				ParseNode_TexMap();
-				tex_read = true;
-
-				continue;
-			}
-			else if(XML_CheckNode_NameEqual("map"))// old name of node: "map".
-			{
-				// Check if data already defined.
-				if(tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for <triangle>.");
-				// read data and set flag about it
-				ParseNode_TexMap(true);
-				tex_read = true;
-
-				continue;
-			}
-
-			MACRO_NODECHECK_READCOMP_U32("v1", read_flag[0], als.V[0]);
-			MACRO_NODECHECK_READCOMP_U32("v2", read_flag[1], als.V[1]);
-			MACRO_NODECHECK_READCOMP_U32("v3", read_flag[2], als.V[2]);
-		MACRO_NODECHECK_LOOPEND("triangle");
-		ParseHelper_Node_Exit();
-		// check that all components was defined
-		if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined.");
-
-	}// if(!mReader->isEmptyElement())
-	else
-	{
-		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
-	}// if(!mReader->isEmptyElement()) else
-
-	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER

+ 0 - 166
code/AMF/AMFImporter_Macro.hpp

@@ -1,166 +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 AMFImporter_Macro.hpp
-/// \brief Useful macrodefines.
-/// \date 2016
-/// \author [email protected]
-
-#pragma once
-#ifndef AMFIMPORTER_MACRO_HPP_INCLUDED
-#define AMFIMPORTER_MACRO_HPP_INCLUDED
-
-/// \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_LOOPEND_WSKIP
-/// End of loop that read attributes values. Difference from \ref MACRO_ATTRREAD_LOOPEND in that: current macro skip unknown attributes, but
-/// \ref MACRO_ATTRREAD_LOOPEND throw an exception.
-#define MACRO_ATTRREAD_LOOPEND_WSKIP \
-		continue; \
-	}
-
-/// \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_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) \
-			XML_CheckNode_SkipUnsupported(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)
-
-/// \def MACRO_NODECHECK_READCOMP_F
-/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float".
-/// If result was read then  "continue" will called. Also check if node data already read then raise exception.
-/// \param [in] pNodeName - node name.
-/// \param [in, out] pReadFlag - read flag.
-/// \param [out] pVarName - output variable name.
-#define MACRO_NODECHECK_READCOMP_F(pNodeName, pReadFlag, pVarName) \
-	if(XML_CheckNode_NameEqual(pNodeName)) \
-	{ \
-		/* Check if field already read before. */ \
-		if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
-		/* Read color component and assign it to object. */ \
-		pVarName = XML_ReadNode_GetVal_AsFloat(); \
-		pReadFlag = true; \
-		continue; \
-	}
-
-/// \def MACRO_NODECHECK_READCOMP_U32
-/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
-/// If result was read then  "continue" will called. Also check if node data already read then raise exception.
-/// \param [in] pNodeName - node name.
-/// \param [in, out] pReadFlag - read flag.
-/// \param [out] pVarName - output variable name.
-#define MACRO_NODECHECK_READCOMP_U32(pNodeName, pReadFlag, pVarName) \
-	if(XML_CheckNode_NameEqual(pNodeName)) \
-	{ \
-		/* Check if field already read before. */ \
-		if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
-		/* Read color component and assign it to object. */ \
-		pVarName = XML_ReadNode_GetVal_AsU32(); \
-		pReadFlag = true; \
-		continue; \
-	}
-
-#endif // AMFIMPORTER_MACRO_HPP_INCLUDED

+ 123 - 121
code/AMF/AMFImporter_Material.cpp

@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
 
 #include "AMFImporter.hpp"
-#include "AMFImporter_Macro.hpp"
+//#include "AMFImporter_Macro.hpp"
 
 namespace Assimp
 {
@@ -68,46 +68,41 @@ namespace Assimp
 //   Multi elements - No.
 //   Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
 //   values can be specified as constants, or as a formula depending on the coordinates.
-void AMFImporter::ParseNode_Color() {
-    std::string profile;
-    CAMFImporter_NodeElement* ne;
-
-	// Read attributes for node <color>.
-	MACRO_ATTRREAD_LOOPBEG;
-		MACRO_ATTRREAD_CHECK_RET("profile", profile, mXmlParser->getAttributeValue);
-	MACRO_ATTRREAD_LOOPEND;
-
+void AMFImporter::ParseNode_Color(XmlNode &node) {
+    std::string profile = node.attribute("profile").as_string();
+    
 	// create new color object.
-	ne = new CAMFImporter_NodeElement_Color(mNodeElement_Cur);
-
-	CAMFImporter_NodeElement_Color& als = *((CAMFImporter_NodeElement_Color*)ne);// alias for convenience
+	AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur);
+	AMFColor& als = *((AMFColor*)ne);// alias for convenience
 
 	als.Profile = profile;
-	// Check for child nodes
-	if(!mXmlParser->isEmptyElement())
-	{
+	if (!node.empty()) {
 		bool read_flag[4] = { false, false, false, false };
-
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("color");
-			MACRO_NODECHECK_READCOMP_F("r", read_flag[0], als.Color.r);
-			MACRO_NODECHECK_READCOMP_F("g", read_flag[1], als.Color.g);
-			MACRO_NODECHECK_READCOMP_F("b", read_flag[2], als.Color.b);
-			MACRO_NODECHECK_READCOMP_F("a", read_flag[3], als.Color.a);
-		MACRO_NODECHECK_LOOPEND("color");
-		ParseHelper_Node_Exit();
-		// check that all components was defined
-        if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
-            throw DeadlyImportError("Not all color components are defined.");
-        }
-
-        // check if <a> is absent. Then manually add "a == 1".
-        if (!read_flag[3]) {
-            als.Color.a = 1;
+		for (pugi::xml_node &child : node.children()) {
+			if (child.name() == "r") {
+				read_flag[0] = true;
+				als.Color.r = atof(child.value());
+			} else if (child.name() == "g") {
+				read_flag[1] = true;
+				als.Color.g = atof(child.value());
+			} else if (child.name() == "b") {
+				read_flag[2] = true;
+				als.Color.b = atof(child.value());
+			} else if (child.name() == "g") {
+			    read_flag[3] = true;
+		    	als.Color.a = atof(child.value());
+		    }
         }
-	}
-	else
-	{
+		// check that all components was defined
+		if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
+			throw DeadlyImportError("Not all color components are defined.");
+		}
+
+		// check if <a> is absent. Then manually add "a == 1".
+		if (!read_flag[3]) {
+			als.Color.a = 1;
+		}
+	} else {
 		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
 	}
 
@@ -122,45 +117,24 @@ void AMFImporter::ParseNode_Color() {
 // An available material.
 // Multi elements - Yes.
 // Parent element - <amf>.
-void AMFImporter::ParseNode_Material() {
-    std::string id;
-    CAMFImporter_NodeElement* ne;
-
-	// Read attributes for node <color>.
-	MACRO_ATTRREAD_LOOPBEG;
-		MACRO_ATTRREAD_CHECK_RET("id", id, mXmlParser->getAttributeValue);
-	MACRO_ATTRREAD_LOOPEND;
-
-	// create new object.
-	ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur);
-
-    // and assign read data
-	((CAMFImporter_NodeElement_Material*)ne)->ID = id;
+void AMFImporter::ParseNode_Material(XmlNode &node) {
+    // create new object and assign read data
+	std::string id = node.attribute("id").as_string();
+	AMFNodeElementBase *ne = new AMFMaterial(mNodeElement_Cur);
+	((AMFMaterial*)ne)->ID = id;
 
     // Check for child nodes
-	if(!mXmlParser->isEmptyElement())
-	{
+	if (!node.empty()) {
 		bool col_read = false;
-
-		ParseHelper_Node_Enter(ne);
-		MACRO_NODECHECK_LOOPBEGIN("material");
-			if(XML_CheckNode_NameEqual("color"))
-			{
-				// Check if data already defined.
-				if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <material>.");
-				// read data and set flag about it
-				ParseNode_Color();
+        for (pugi::xml_node &child : node.children()) {
+			if (child.name() == "color") {
 				col_read = true;
-
-				continue;
+				ParseNode_Color(child);
+			} else if (child.name() == "metadata") {
+				ParseNode_Metadata(child);
 			}
-
-			if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
-		MACRO_NODECHECK_LOOPEND("material");
-		ParseHelper_Node_Exit();
-	}
-	else
-	{
+		}
+	} else {
 		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
 	}
 
@@ -192,30 +166,35 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
 	bool tiled = node.attribute("tiled").as_bool();
 
 	// create new texture object.
-    CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
+    AMFNodeElementBase *ne = new AMFTexture(mNodeElement_Cur);
 
-	CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience
+	AMFTexture& als = *((AMFTexture*)ne);// alias for convenience
 
-	// Check for child nodes
-    if (!mXmlParser->isEmptyElement()) {
-        XML_ReadNode_GetVal_AsString(enc64_data);
+    if (node.empty()) {
+		return;
     }
 
+    std::string enc64_data = node.value();
+	// Check for child nodes
+    //if (!mXmlParser->isEmptyElement()) {
+    //    XML_ReadNode_GetVal_AsString(enc64_data);
+    //}
+
 	// check that all components was defined
     if (id.empty()) {
-        throw DeadlyImportError("ID for texture must be defined.");
+		throw DeadlyImportError("ID for texture must be defined.");
     }
     if (width < 1) {
-        Throw_IncorrectAttrValue("width");
+		throw DeadlyImportError("INvalid width for texture.");
     }
     if (height < 1) {
-        Throw_IncorrectAttrValue("height");
-    }
+		throw DeadlyImportError("Invalid height for texture.");
+	}
     if (depth < 1) {
-        Throw_IncorrectAttrValue("depth");
+		throw DeadlyImportError("Invalid depth for texture.");
     }
     if (type != "grayscale") {
-        Throw_IncorrectAttrValue("type");
+		throw DeadlyImportError("Invalid type for texture.");
     }
     if (enc64_data.empty()) {
         throw DeadlyImportError("Texture data not defined.");
@@ -251,57 +230,80 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
 //   <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>. Old name: <u1>, <u2>, <u3>, <v1>, <v2>, <v3>.
 //   Multi elements - No.
 //   Texture coordinates for every vertex of triangle.
-void AMFImporter::ParseNode_TexMap(const bool pUseOldName) {
-    std::string rtexid, gtexid, btexid, atexid;
-
+void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
 	// Read attributes for node <color>.
-	MACRO_ATTRREAD_LOOPBEG;
-		MACRO_ATTRREAD_CHECK_RET("rtexid", rtexid, mXmlParser->getAttributeValue);
-		MACRO_ATTRREAD_CHECK_RET("gtexid", gtexid, mXmlParser->getAttributeValue);
-		MACRO_ATTRREAD_CHECK_RET("btexid", btexid, mXmlParser->getAttributeValue);
-		MACRO_ATTRREAD_CHECK_RET("atexid", atexid, mXmlParser->getAttributeValue);
-	MACRO_ATTRREAD_LOOPEND;
+	std::string rtexid = node.attribute("rtexid").as_string();
+	std::string gtexid = node.attribute("gtexid").as_string();
+	std::string btexid = node.attribute("btexid").as_string();
+	std::string atexid = node.attribute("atexid").as_string();
 
-	// create new texture coordinates object.
-    CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
 
-	CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience
+	// create new texture coordinates object, alias for convenience
+    AMFNodeElementBase *ne = new AMFTexMap(mNodeElement_Cur);
+	AMFTexMap& als = *((AMFTexMap*)ne);// 
 	// check data
-	if(rtexid.empty() && gtexid.empty() && btexid.empty()) throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined.");
+	if (rtexid.empty() && gtexid.empty() && btexid.empty()) {
+		throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined.");
+	}
+
 	// Check for children nodes
-	XML_CheckNode_MustHaveChildren();
+	//XML_CheckNode_MustHaveChildren();
+	if (node.children().begin() == node.children().end()) {
+		throw DeadlyImportError("Invalid children definition.");
+	}
 	// read children nodes
 	bool read_flag[6] = { false, false, false, false, false, false };
 
-	ParseHelper_Node_Enter(ne);
-	if(!pUseOldName)
-	{
-		MACRO_NODECHECK_LOOPBEGIN("texmap");
-			MACRO_NODECHECK_READCOMP_F("utex1", read_flag[0], als.TextureCoordinate[0].x);
-			MACRO_NODECHECK_READCOMP_F("utex2", read_flag[1], als.TextureCoordinate[1].x);
-			MACRO_NODECHECK_READCOMP_F("utex3", read_flag[2], als.TextureCoordinate[2].x);
-			MACRO_NODECHECK_READCOMP_F("vtex1", read_flag[3], als.TextureCoordinate[0].y);
-			MACRO_NODECHECK_READCOMP_F("vtex2", read_flag[4], als.TextureCoordinate[1].y);
-			MACRO_NODECHECK_READCOMP_F("vtex3", read_flag[5], als.TextureCoordinate[2].y);
-		MACRO_NODECHECK_LOOPEND("texmap");
+	if (!pUseOldName) {
+		for (pugi::xml_attribute &attr : node.attributes()) {
+			if (attr.name() == "utex1") {
+				read_flag[0] = true;
+				als.TextureCoordinate[0].x = attr.as_float();
+			} else if (attr.name() == "utex2") {
+				read_flag[1] = true;
+				als.TextureCoordinate[1].x = attr.as_float();
+			} else if (attr.name() == "utex3") {
+				read_flag[2] = true;
+				als.TextureCoordinate[2].x = attr.as_float();
+			} else if (attr.name() == "vtex1") {
+				read_flag[3] = true;
+				als.TextureCoordinate[0].y = attr.as_float();
+			} else if (attr.name() == "vtex2") {
+				read_flag[4] = true;
+				als.TextureCoordinate[1].y = attr.as_float();
+			} else if (attr.name() == "vtex3") {
+				read_flag[5] = true;
+				als.TextureCoordinate[0].y = attr.as_float();
+			}
+		}
+	} else {
+		for (pugi::xml_attribute &attr : node.attributes()) {
+			if (attr.name() == "u") {
+				read_flag[0] = true;
+				als.TextureCoordinate[0].x = attr.as_float();
+			} else if (attr.name() == "u2") {
+				read_flag[1] = true;
+				als.TextureCoordinate[1].x = attr.as_float();
+			} else if (attr.name() == "u3") {
+				read_flag[2] = true;
+				als.TextureCoordinate[2].x = attr.as_float();
+			} else if (attr.name() == "v1") {
+				read_flag[3] = true;
+				als.TextureCoordinate[0].y = attr.as_float();
+			} else if (attr.name() == "v2") {
+				read_flag[4] = true;
+				als.TextureCoordinate[1].y = attr.as_float();
+			} else if (attr.name() == "v3") {
+				read_flag[5] = true;
+				als.TextureCoordinate[0].y = attr.as_float();
+			}
+		}
 	}
-	else
-	{
-		MACRO_NODECHECK_LOOPBEGIN("map");
-			MACRO_NODECHECK_READCOMP_F("u1", read_flag[0], als.TextureCoordinate[0].x);
-			MACRO_NODECHECK_READCOMP_F("u2", read_flag[1], als.TextureCoordinate[1].x);
-			MACRO_NODECHECK_READCOMP_F("u3", read_flag[2], als.TextureCoordinate[2].x);
-			MACRO_NODECHECK_READCOMP_F("v1", read_flag[3], als.TextureCoordinate[0].y);
-			MACRO_NODECHECK_READCOMP_F("v2", read_flag[4], als.TextureCoordinate[1].y);
-			MACRO_NODECHECK_READCOMP_F("v3", read_flag[5], als.TextureCoordinate[2].y);
-		MACRO_NODECHECK_LOOPEND("map");
-	}// if(!pUseOldName) else
-
-	ParseHelper_Node_Exit();
 
 	// check that all components was defined
-	if(!(read_flag[0] && read_flag[1] && read_flag[2] && read_flag[3] && read_flag[4] && read_flag[5]))
+	if (!(read_flag[0] && read_flag[1] && read_flag[2] && read_flag[3] && read_flag[4] && read_flag[5])) {
 		throw DeadlyImportError("Not all texture coordinates are defined.");
+	}
 
 	// copy attributes data
 	als.TextureID_R = rtexid;
@@ -309,7 +311,7 @@ void AMFImporter::ParseNode_TexMap(const bool pUseOldName) {
 	als.TextureID_B = btexid;
 	als.TextureID_A = atexid;
 
-	mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph.
+	mNodeElement_List.push_back(ne);
 }
 
 }// namespace Assimp

+ 116 - 148
code/AMF/AMFImporter_Node.hpp

@@ -56,80 +56,76 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <vector>
 
 // Header files, Assimp.
-#include "assimp/types.h"
 #include "assimp/scene.h"
+#include "assimp/types.h"
 
 /// \class CAMFImporter_NodeElement
 /// Base class for elements of nodes.
-class CAMFImporter_NodeElement {
+class AMFNodeElementBase {
 public:
 	/// Define what data type contain node element.
 	enum EType {
-		ENET_Color,        ///< Color element: <color>.
-		ENET_Constellation,///< Grouping element: <constellation>.
-		ENET_Coordinates,  ///< Coordinates element: <coordinates>.
-		ENET_Edge,         ///< Edge element: <edge>.
-		ENET_Instance,     ///< Grouping element: <constellation>.
-		ENET_Material,     ///< Material element: <material>.
-		ENET_Metadata,     ///< Metadata element: <metadata>.
-		ENET_Mesh,         ///< Metadata element: <mesh>.
-		ENET_Object,       ///< Element which hold object: <object>.
-		ENET_Root,         ///< Root element: <amf>.
-		ENET_Triangle,     ///< Triangle element: <triangle>.
-		ENET_TexMap,       ///< Texture coordinates element: <texmap> or <map>.
-		ENET_Texture,      ///< Texture element: <texture>.
-		ENET_Vertex,       ///< Vertex element: <vertex>.
-		ENET_Vertices,     ///< Vertex element: <vertices>.
-		ENET_Volume,       ///< Volume element: <volume>.
-
-		ENET_Invalid       ///< Element has invalid type and possible contain invalid data.
+		ENET_Color, ///< Color element: <color>.
+		ENET_Constellation, ///< Grouping element: <constellation>.
+		ENET_Coordinates, ///< Coordinates element: <coordinates>.
+		ENET_Edge, ///< Edge element: <edge>.
+		ENET_Instance, ///< Grouping element: <constellation>.
+		ENET_Material, ///< Material element: <material>.
+		ENET_Metadata, ///< Metadata element: <metadata>.
+		ENET_Mesh, ///< Metadata element: <mesh>.
+		ENET_Object, ///< Element which hold object: <object>.
+		ENET_Root, ///< Root element: <amf>.
+		ENET_Triangle, ///< Triangle element: <triangle>.
+		ENET_TexMap, ///< Texture coordinates element: <texmap> or <map>.
+		ENET_Texture, ///< Texture element: <texture>.
+		ENET_Vertex, ///< Vertex element: <vertex>.
+		ENET_Vertices, ///< Vertex element: <vertices>.
+		ENET_Volume, ///< Volume element: <volume>.
+
+		ENET_Invalid ///< Element has invalid type and possible contain invalid data.
 	};
 
-	const EType Type;///< Type of element.
-	std::string ID;///< ID of element.
-	CAMFImporter_NodeElement* Parent;///< Parent element. If nullptr then this node is root.
-	std::list<CAMFImporter_NodeElement*> Child;///< Child elements.
+	const EType Type; ///< Type of element.
+	std::string ID; ///< ID of element.
+	AMFNodeElementBase *Parent; ///< Parent element. If nullptr then this node is root.
+	std::list<AMFNodeElementBase *> Child; ///< Child elements.
 
-public:                                               /// Destructor, virtual..
-    virtual ~CAMFImporter_NodeElement() {
-        // empty
-    }
+public: /// Destructor, virtual..
+	virtual ~AMFNodeElementBase() {
+		// empty
+	}
 
 	/// Disabled copy constructor and co.
-	CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement) = delete;
-    CAMFImporter_NodeElement(CAMFImporter_NodeElement&&) = delete;
-    CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement) = delete;
-	CAMFImporter_NodeElement() = delete;
+	AMFNodeElementBase(const AMFNodeElementBase &pNodeElement) = delete;
+	AMFNodeElementBase(AMFNodeElementBase &&) = delete;
+	AMFNodeElementBase &operator=(const AMFNodeElementBase &pNodeElement) = delete;
+	AMFNodeElementBase() = delete;
 
 protected:
 	/// In constructor inheritor must set element type.
 	/// \param [in] pType - element type.
 	/// \param [in] pParent - parent element.
-	CAMFImporter_NodeElement(const EType pType, CAMFImporter_NodeElement* pParent)
-	: Type(pType)
-    , ID()
-    , Parent(pParent)
-    , Child() {
-        // empty
-    }
-};// class IAMFImporter_NodeElement
+	AMFNodeElementBase(const EType pType, AMFNodeElementBase *pParent) :
+			Type(pType), ID(), Parent(pParent), Child() {
+		// empty
+	}
+}; // class IAMFImporter_NodeElement
 
 /// \struct CAMFImporter_NodeElement_Constellation
 /// A collection of objects or constellations with specific relative locations.
-struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement {
+struct AMFConstellation : public AMFNodeElementBase {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Constellation, pParent)
-	{}
+	AMFConstellation(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Constellation, pParent) {}
 
-};// struct CAMFImporter_NodeElement_Constellation
+}; // struct CAMFImporter_NodeElement_Constellation
 
 /// \struct CAMFImporter_NodeElement_Instance
 /// Part of constellation.
-struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement {
+struct AMFInstance : public AMFNodeElementBase {
 
-	std::string ObjectID;///< ID of object for instantiation.
+	std::string ObjectID; ///< ID of object for instantiation.
 	/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
 	/// create an instance of the object in the current constellation.
 	aiVector3D Delta;
@@ -140,201 +136,173 @@ struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement {
 
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Instance, pParent)
-	{}
+	AMFInstance(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Instance, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Metadata
 /// Structure that define metadata node.
-struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement {
+struct AMFMetadata : public AMFNodeElementBase {
 
-	std::string Type;///< Type of "Value". 
-	std::string Value;///< Value.
+	std::string Type; ///< Type of "Value".
+	std::string Value; ///< Value.
 
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Metadata, pParent)
-	{}
+	AMFMetadata(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Metadata, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Root
 /// Structure that define root node.
-struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement {
+struct AMFRoot : public AMFNodeElementBase {
 
-	std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
-	std::string Version;///< Version of format.
+	std::string Unit; ///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
+	std::string Version; ///< Version of format.
 
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Root, pParent)
-	{}
+	AMFRoot(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Root, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Color
 /// Structure that define object node.
-struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement {
-	bool Composed;                  ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
-	std::string Color_Composed[4];  ///< By components formulas of composed color. [0..3] - RGBA.
-	aiColor4D Color;                ///< Constant color.
-	std::string Profile;            ///< The ICC color space used to interpret the three color channels r, g and b..
+struct AMFColor : public AMFNodeElementBase {
+	bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
+	std::string Color_Composed[4]; ///< By components formulas of composed color. [0..3] - RGBA.
+	aiColor4D Color; ///< Constant color.
+	std::string Profile; ///< The ICC color space used to interpret the three color channels r, g and b..
 
 	/// @brief  Constructor.
 	/// @param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
-	: CAMFImporter_NodeElement(ENET_Color, pParent)
-    , Composed( false )
-    , Color()
-    , Profile() {
-        // empty
-    }
+	AMFColor(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color(), Profile() {
+		// empty
+	}
 };
 
 /// \struct CAMFImporter_NodeElement_Material
 /// Structure that define material node.
-struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement {
-	
+struct AMFMaterial : public AMFNodeElementBase {
+
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Material, pParent)
-	{}
-
+	AMFMaterial(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Material, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Object
 /// Structure that define object node.
-struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement {
+struct AMFObject : public AMFNodeElementBase {
 
-    /// Constructor.
+	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Object, pParent)
-	{}
+	AMFObject(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Object, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Mesh
 /// Structure that define mesh node.
-struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement {
+struct AMFMesh : public AMFNodeElementBase {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Mesh, pParent)
-	{}
+	AMFMesh(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Mesh, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Vertex
 /// Structure that define vertex node.
-struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement {
+struct AMFVertex : public AMFNodeElementBase {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Vertex, pParent)
-	{}
+	AMFVertex(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Vertex, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Edge
 /// Structure that define edge node.
-struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement {
+struct AMFEdge : public AMFNodeElementBase {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Edge, pParent)
-	{}
-
+	AMFEdge(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Edge, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Vertices
 /// Structure that define vertices node.
-struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement {
+struct AMFVertices : public AMFNodeElementBase {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Vertices, pParent)
-	{}
+	AMFVertices(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Vertices, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Volume
 /// Structure that define volume node.
-struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement {
-	std::string MaterialID;///< Which material to use.
-	std::string Type;///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed.
+struct AMFVolume : public AMFNodeElementBase {
+	std::string MaterialID; ///< Which material to use.
+	std::string Type; ///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed.
 
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Volume, pParent)
-	{}
+	AMFVolume(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Volume, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_Coordinates
 /// Structure that define coordinates node.
-struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement
-{
-	aiVector3D Coordinate;///< Coordinate.
+struct AMFCoordinates : public AMFNodeElementBase {
+	aiVector3D Coordinate; ///< Coordinate.
 
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Coordinates, pParent)
-	{}
-
+	AMFCoordinates(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Coordinates, pParent) {}
 };
 
 /// \struct CAMFImporter_NodeElement_TexMap
 /// Structure that define texture coordinates node.
-struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement {
-	aiVector3D TextureCoordinate[3];///< Texture coordinates.
-	std::string TextureID_R;///< Texture ID for red color component.
-	std::string TextureID_G;///< Texture ID for green color component.
-	std::string TextureID_B;///< Texture ID for blue color component.
-	std::string TextureID_A;///< Texture ID for alpha color component.
+struct AMFTexMap : public AMFNodeElementBase {
+	aiVector3D TextureCoordinate[3]; ///< Texture coordinates.
+	std::string TextureID_R; ///< Texture ID for red color component.
+	std::string TextureID_G; ///< Texture ID for green color component.
+	std::string TextureID_B; ///< Texture ID for blue color component.
+	std::string TextureID_A; ///< Texture ID for alpha color component.
 
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
-	: CAMFImporter_NodeElement(ENET_TexMap, pParent)
-    , TextureCoordinate{}
-    , TextureID_R()
-    , TextureID_G()
-    , TextureID_B()
-    , TextureID_A()	{
-        // empty
-    }
+	AMFTexMap(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{}, TextureID_R(), TextureID_G(), TextureID_B(), TextureID_A() {
+		// empty
+	}
 };
 
 /// \struct CAMFImporter_NodeElement_Triangle
 /// Structure that define triangle node.
-struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement {
-	size_t V[3];///< Triangle vertices.
+struct AMFTriangle : public AMFNodeElementBase {
+	size_t V[3]; ///< Triangle vertices.
 
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
-	: CAMFImporter_NodeElement(ENET_Triangle, pParent) {
-        // empty
-    }
+	AMFTriangle(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Triangle, pParent) {
+		// empty
+	}
 };
 
 /// Structure that define texture node.
-struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
-	size_t Width, Height, Depth;///< Size of the texture.
-	std::vector<uint8_t> Data;///< Data of the texture.
+struct AMFTexture : public AMFNodeElementBase {
+	size_t Width, Height, Depth; ///< Size of the texture.
+	std::vector<uint8_t> Data; ///< Data of the texture.
 	bool Tiled;
 
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
-	CAMFImporter_NodeElement_Texture(CAMFImporter_NodeElement* pParent)
-	: CAMFImporter_NodeElement(ENET_Texture, pParent)
-    , Width( 0 )
-    , Height( 0 )
-    , Depth( 0 )
-    , Data()
-    , Tiled( false ){
-        // empty
-    }
+	AMFTexture(AMFNodeElementBase *pParent) :
+			AMFNodeElementBase(ENET_Texture, pParent), Width(0), Height(0), Depth(0), Data(), Tiled(false) {
+		// empty
+	}
 };
 
 #endif // INCLUDED_AI_AMF_IMPORTER_NODE_H

+ 80 - 80
code/AMF/AMFImporter_Postprocess.cpp

@@ -91,16 +91,16 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
 	return tcol;
 }
 
-void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
-														std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
+void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
+														std::vector<AMFColor*>& pVertexColorArray) const
 {
-    CAMFImporter_NodeElement_Vertices* vn = nullptr;
+    AMFVertices* vn = nullptr;
     size_t col_idx;
 
 	// All data stored in "vertices", search for it.
-	for(CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
+	for(AMFNodeElementBase* ne_child: pNodeElement.Child)
 	{
-		if(ne_child->Type == CAMFImporter_NodeElement::ENET_Vertices) vn = (CAMFImporter_NodeElement_Vertices*)ne_child;
+		if(ne_child->Type == AMFNodeElementBase::ENET_Vertices) vn = (AMFVertices*)ne_child;
 	}
 
 	// If "vertices" not found then no work for us.
@@ -110,26 +110,26 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeE
 	pVertexColorArray.resize(vn->Child.size());// colors count equal vertices count.
 	col_idx = 0;
 	// Inside vertices collect all data and place to arrays
-	for(CAMFImporter_NodeElement* vn_child: vn->Child)
+	for(AMFNodeElementBase* vn_child: vn->Child)
 	{
 		// vertices, colors
-		if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex)
+		if(vn_child->Type == AMFNodeElementBase::ENET_Vertex)
 		{
 			// by default clear color for current vertex
 			pVertexColorArray[col_idx] = nullptr;
 
-			for(CAMFImporter_NodeElement* vtx: vn_child->Child)
+			for(AMFNodeElementBase* vtx: vn_child->Child)
 			{
-				if(vtx->Type == CAMFImporter_NodeElement::ENET_Coordinates)
+				if(vtx->Type == AMFNodeElementBase::ENET_Coordinates)
 				{
-					pVertexCoordinateArray.push_back(((CAMFImporter_NodeElement_Coordinates*)vtx)->Coordinate);
+					pVertexCoordinateArray.push_back(((AMFCoordinates*)vtx)->Coordinate);
 
 					continue;
 				}
 
-				if(vtx->Type == CAMFImporter_NodeElement::ENET_Color)
+				if(vtx->Type == AMFNodeElementBase::ENET_Color)
 				{
-					pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color*)vtx;
+					pVertexColorArray[col_idx] = (AMFColor*)vtx;
 
 					continue;
 				}
@@ -166,20 +166,20 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
 	//
 	// Converted texture not found, create it.
 	//
-	CAMFImporter_NodeElement_Texture* src_texture[4]{nullptr};
-	std::vector<CAMFImporter_NodeElement_Texture*> src_texture_4check;
+	AMFTexture* src_texture[4]{nullptr};
+	std::vector<AMFTexture*> src_texture_4check;
 	SPP_Texture converted_texture;
 
 	{// find all specified source textures
-		CAMFImporter_NodeElement* t_tex;
+		AMFNodeElementBase* t_tex;
 
 		// R
 		if(!pID_R.empty())
 		{
-			if(!Find_NodeElement(pID_R, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R);
+			if(!Find_NodeElement(pID_R, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R);
 
-			src_texture[0] = (CAMFImporter_NodeElement_Texture*)t_tex;
-			src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
+			src_texture[0] = (AMFTexture*)t_tex;
+			src_texture_4check.push_back((AMFTexture*)t_tex);
 		}
 		else
 		{
@@ -189,10 +189,10 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
 		// G
 		if(!pID_G.empty())
 		{
-			if(!Find_NodeElement(pID_G, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G);
+			if(!Find_NodeElement(pID_G, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G);
 
-			src_texture[1] = (CAMFImporter_NodeElement_Texture*)t_tex;
-			src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
+			src_texture[1] = (AMFTexture*)t_tex;
+			src_texture_4check.push_back((AMFTexture*)t_tex);
 		}
 		else
 		{
@@ -202,10 +202,10 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
 		// B
 		if(!pID_B.empty())
 		{
-			if(!Find_NodeElement(pID_B, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B);
+			if(!Find_NodeElement(pID_B, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B);
 
-			src_texture[2] = (CAMFImporter_NodeElement_Texture*)t_tex;
-			src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
+			src_texture[2] = (AMFTexture*)t_tex;
+			src_texture_4check.push_back((AMFTexture*)t_tex);
 		}
 		else
 		{
@@ -215,10 +215,10 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
 		// A
 		if(!pID_A.empty())
 		{
-			if(!Find_NodeElement(pID_A, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A);
+			if(!Find_NodeElement(pID_A, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A);
 
-			src_texture[3] = (CAMFImporter_NodeElement_Texture*)t_tex;
-			src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
+			src_texture[3] = (AMFTexture*)t_tex;
+			src_texture_4check.push_back((AMFTexture*)t_tex);
 		}
 		else
 		{
@@ -284,7 +284,7 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
 		if(!pID.empty())
 		{
 			for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) {
-				CAMFImporter_NodeElement_Texture* tex = src_texture[pSrcTexNum];
+				AMFTexture* tex = src_texture[pSrcTexNum];
 				ai_assert(tex);
 				converted_texture.Data[idx_target] = tex->Data.at(idx_src);
 			}
@@ -306,7 +306,7 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
 
 void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated)
 {
-    auto texmap_is_equal = [](const CAMFImporter_NodeElement_TexMap* pTexMap1, const CAMFImporter_NodeElement_TexMap* pTexMap2) -> bool
+    auto texmap_is_equal = [](const AMFTexMap* pTexMap1, const AMFTexMap* pTexMap2) -> bool
     {
 	    if((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true;
 	    if(pTexMap1 == nullptr) return false;
@@ -349,7 +349,7 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
 	} while(!pInputList.empty());
 }
 
-void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
+void AMFImporter::Postprocess_AddMetadata(const std::list<AMFMetadata*>& metadataList, aiNode& sceneNode) const
 {
 	if ( !metadataList.empty() )
 	{
@@ -359,55 +359,55 @@ void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeEleme
         sceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(metadataList.size()) );
 		size_t meta_idx( 0 );
 
-		for(const CAMFImporter_NodeElement_Metadata& metadata: metadataList)
+		for(const AMFMetadata& metadata: metadataList)
 		{
 			sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value));
 		}
 	}// if(!metadataList.empty())
 }
 
-void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
+void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
 {
-CAMFImporter_NodeElement_Color* object_color = nullptr;
+AMFColor* object_color = nullptr;
 
 	// create new aiNode and set name as <object> has.
 	*pSceneNode = new aiNode;
 	(*pSceneNode)->mName = pNodeElement.ID;
 	// read mesh and color
-	for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
+	for(const AMFNodeElementBase* ne_child: pNodeElement.Child)
 	{
 		std::vector<aiVector3D> vertex_arr;
-		std::vector<CAMFImporter_NodeElement_Color*> color_arr;
+		std::vector<AMFColor*> color_arr;
 
 		// color for object
-		if(ne_child->Type == CAMFImporter_NodeElement::ENET_Color) object_color = (CAMFImporter_NodeElement_Color*)ne_child;
+		if(ne_child->Type == AMFNodeElementBase::ENET_Color) object_color = (AMFColor*)ne_child;
 
-		if(ne_child->Type == CAMFImporter_NodeElement::ENET_Mesh)
+		if(ne_child->Type == AMFNodeElementBase::ENET_Mesh)
 		{
 			// Create arrays from children of mesh: vertices.
-			PostprocessHelper_CreateMeshDataArray(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr);
+			PostprocessHelper_CreateMeshDataArray(*((AMFMesh*)ne_child), vertex_arr, color_arr);
 			// Use this arrays as a source when creating every aiMesh
-			Postprocess_BuildMeshSet(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode);
+			Postprocess_BuildMeshSet(*((AMFMesh*)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode);
 		}
 	}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement)
 }
 
-void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
-											const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray,
-											const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
+void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
+											const std::vector<AMFColor*>& pVertexColorArray,
+											const AMFColor* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
 {
 std::list<unsigned int> mesh_idx;
 
 	// all data stored in "volume", search for it.
-	for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
+	for(const AMFNodeElementBase* ne_child: pNodeElement.Child)
 	{
-		const CAMFImporter_NodeElement_Color* ne_volume_color = nullptr;
+		const AMFColor* ne_volume_color = nullptr;
 		const SPP_Material* cur_mat = nullptr;
 
-		if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume)
+		if(ne_child->Type == AMFNodeElementBase::ENET_Volume)
 		{
 			/******************* Get faces *******************/
-			const CAMFImporter_NodeElement_Volume* ne_volume = reinterpret_cast<const CAMFImporter_NodeElement_Volume*>(ne_child);
+			const AMFVolume* ne_volume = reinterpret_cast<const AMFVolume*>(ne_child);
 
 			std::list<SComplexFace> complex_faces_list;// List of the faces of the volume.
 			std::list<std::list<SComplexFace> > complex_faces_toplist;// List of the face list for every mesh.
@@ -419,16 +419,16 @@ std::list<unsigned int> mesh_idx;
 			}
 
 			// inside "volume" collect all data and place to arrays or create new objects
-			for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child)
+			for(const AMFNodeElementBase* ne_volume_child: ne_volume->Child)
 			{
 				// color for volume
-				if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Color)
+				if(ne_volume_child->Type == AMFNodeElementBase::ENET_Color)
 				{
-					ne_volume_color = reinterpret_cast<const CAMFImporter_NodeElement_Color*>(ne_volume_child);
+					ne_volume_color = reinterpret_cast<const AMFColor*>(ne_volume_child);
 				}
-				else if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Triangle)// triangles, triangles colors
+				else if(ne_volume_child->Type == AMFNodeElementBase::ENET_Triangle)// triangles, triangles colors
 				{
-					const CAMFImporter_NodeElement_Triangle& tri_al = *reinterpret_cast<const CAMFImporter_NodeElement_Triangle*>(ne_volume_child);
+					const AMFTriangle& tri_al = *reinterpret_cast<const AMFTriangle*>(ne_volume_child);
 
 					SComplexFace complex_face;
 
@@ -438,12 +438,12 @@ std::list<unsigned int> mesh_idx;
 					// get data from triangle children: color, texture coordinates.
 					if(tri_al.Child.size())
 					{
-						for(const CAMFImporter_NodeElement* ne_triangle_child: tri_al.Child)
+						for(const AMFNodeElementBase* ne_triangle_child: tri_al.Child)
 						{
-							if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_Color)
-								complex_face.Color = reinterpret_cast<const CAMFImporter_NodeElement_Color*>(ne_triangle_child);
-							else if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_TexMap)
-								complex_face.TexMap = reinterpret_cast<const CAMFImporter_NodeElement_TexMap*>(ne_triangle_child);
+							if(ne_triangle_child->Type == AMFNodeElementBase::ENET_Color)
+								complex_face.Color = reinterpret_cast<const AMFColor*>(ne_triangle_child);
+							else if(ne_triangle_child->Type == AMFNodeElementBase::ENET_TexMap)
+								complex_face.TexMap = reinterpret_cast<const AMFTexMap*>(ne_triangle_child);
 						}
 					}// if(tri_al.Child.size())
 
@@ -722,20 +722,20 @@ std::list<unsigned int> mesh_idx;
 	}// if(mesh_idx.size() > 0)
 }
 
-void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
+void AMFImporter::Postprocess_BuildMaterial(const AMFMaterial& pMaterial)
 {
 SPP_Material new_mat;
 
 	new_mat.ID = pMaterial.ID;
-	for(const CAMFImporter_NodeElement* mat_child: pMaterial.Child)
+	for(const AMFNodeElementBase* mat_child: pMaterial.Child)
 	{
-		if(mat_child->Type == CAMFImporter_NodeElement::ENET_Color)
+		if(mat_child->Type == AMFNodeElementBase::ENET_Color)
 		{
-			new_mat.Color = (CAMFImporter_NodeElement_Color*)mat_child;
+			new_mat.Color = (AMFColor*)mat_child;
 		}
-		else if(mat_child->Type == CAMFImporter_NodeElement::ENET_Metadata)
+		else if(mat_child->Type == AMFNodeElementBase::ENET_Metadata)
 		{
-			new_mat.Metadata.push_back((CAMFImporter_NodeElement_Metadata*)mat_child);
+			new_mat.Metadata.push_back((AMFMetadata*)mat_child);
 		}
 	}// for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child)
 
@@ -743,7 +743,7 @@ SPP_Material new_mat;
 	mMaterial_Converted.push_back(new_mat);
 }
 
-void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
+void AMFImporter::Postprocess_BuildConstellation(AMFConstellation& pConstellation, std::list<aiNode*>& pNodeList) const
 {
 aiNode* con_node;
 std::list<aiNode*> ch_node;
@@ -756,17 +756,17 @@ std::list<aiNode*> ch_node;
 	con_node = new aiNode;
 	con_node->mName = pConstellation.ID;
 	// Walk through children and search for instances of another objects, constellations.
-	for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
+	for(const AMFNodeElementBase* ne: pConstellation.Child)
 	{
 		aiMatrix4x4 tmat;
 		aiNode* t_node;
 		aiNode* found_node;
 
-		if(ne->Type == CAMFImporter_NodeElement::ENET_Metadata) continue;
-		if(ne->Type != CAMFImporter_NodeElement::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
+		if(ne->Type == AMFNodeElementBase::ENET_Metadata) continue;
+		if(ne->Type != AMFNodeElementBase::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
 
 		// create alias for conveniance
-		CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);
+		AMFInstance& als = *((AMFInstance*)ne);
 		// find referenced object
 		if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
 
@@ -803,7 +803,7 @@ void AMFImporter::Postprocess_BuildScene(aiScene* pScene)
 {
 std::list<aiNode*> node_list;
 std::list<aiMesh*> mesh_list;
-std::list<CAMFImporter_NodeElement_Metadata*> meta_list;
+std::list<AMFMetadata*> meta_list;
 
 	//
 	// Because for AMF "material" is just complex colors mixing so aiMaterial will not be used.
@@ -813,11 +813,11 @@ std::list<CAMFImporter_NodeElement_Metadata*> meta_list;
 	pScene->mRootNode->mParent = nullptr;
 	pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
 	// search for root(<amf>) element
-	CAMFImporter_NodeElement* root_el = nullptr;
+	AMFNodeElementBase* root_el = nullptr;
 
-	for(CAMFImporter_NodeElement* ne: mNodeElement_List)
+	for(AMFNodeElementBase* ne: mNodeElement_List)
 	{
-		if(ne->Type != CAMFImporter_NodeElement::ENET_Root) continue;
+		if(ne->Type != AMFNodeElementBase::ENET_Root) continue;
 
 		root_el = ne;
 
@@ -833,22 +833,22 @@ std::list<CAMFImporter_NodeElement_Metadata*> meta_list;
 	//
 	// 1. <material>
 	// 2. <texture> will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet
-	for(const CAMFImporter_NodeElement* root_child: root_el->Child)
+	for(const AMFNodeElementBase* root_child: root_el->Child)
 	{
-		if(root_child->Type == CAMFImporter_NodeElement::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material*)root_child));
+		if(root_child->Type == AMFNodeElementBase::ENET_Material) Postprocess_BuildMaterial(*((AMFMaterial*)root_child));
 	}
 
 	// After "appearance" nodes we must read <object> because it will be used in <constellation> -> <instance>.
 	//
 	// 3. <object>
-	for(const CAMFImporter_NodeElement* root_child: root_el->Child)
+	for(const AMFNodeElementBase* root_child: root_el->Child)
 	{
-		if(root_child->Type == CAMFImporter_NodeElement::ENET_Object)
+		if(root_child->Type == AMFNodeElementBase::ENET_Object)
 		{
 			aiNode* tnode = nullptr;
 
 			// for <object> mesh and node must be built: object ID assigned to aiNode name and will be used in future for <instance>
-			Postprocess_BuildNodeAndObject(*((CAMFImporter_NodeElement_Object*)root_child), mesh_list, &tnode);
+			Postprocess_BuildNodeAndObject(*((AMFObject*)root_child), mesh_list, &tnode);
 			if(tnode != nullptr) node_list.push_back(tnode);
 
 		}
@@ -856,17 +856,17 @@ std::list<CAMFImporter_NodeElement_Metadata*> meta_list;
 
 	// And finally read rest of nodes.
 	//
-	for(const CAMFImporter_NodeElement* root_child: root_el->Child)
+	for(const AMFNodeElementBase* root_child: root_el->Child)
 	{
 		// 4. <constellation>
-		if(root_child->Type == CAMFImporter_NodeElement::ENET_Constellation)
+		if(root_child->Type == AMFNodeElementBase::ENET_Constellation)
 		{
 			// <object> and <constellation> at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's.
-			Postprocess_BuildConstellation(*((CAMFImporter_NodeElement_Constellation*)root_child), node_list);
+			Postprocess_BuildConstellation(*((AMFConstellation*)root_child), node_list);
 		}
 
 		// 5, <metadata>
-		if(root_child->Type == CAMFImporter_NodeElement::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata*)root_child);
+		if(root_child->Type == AMFNodeElementBase::ENET_Metadata) meta_list.push_back((AMFMetadata*)root_child);
 	}// for(const CAMFImporter_NodeElement* root_child: root_el->Child)
 
 	// at now we can add collected metadata to root node

+ 0 - 2
code/CMakeLists.txt

@@ -291,10 +291,8 @@ SET(ASSIMP_EXPORTERS_DISABLED "") # disabled exporters list (used to print)
 
 ADD_ASSIMP_IMPORTER( AMF
   AMF/AMFImporter.hpp
-  AMF/AMFImporter_Macro.hpp
   AMF/AMFImporter_Node.hpp
   AMF/AMFImporter.cpp
-  AMF/AMFImporter_Geometry.cpp
   AMF/AMFImporter_Material.cpp
   AMF/AMFImporter_Postprocess.cpp
 )

+ 115 - 52
code/X3D/FIReader.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,
@@ -59,7 +58,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/IOStream.hpp>
 #include <assimp/types.h>
 #include <assimp/MemoryIOWrapper.h>
-#include <assimp/irrXMLWrapper.h>
 #ifdef ASSIMP_USE_HUNTER
 #  include <utf8/utf8.h>
 #else
@@ -140,8 +138,13 @@ static std::string parseUTF16String(const uint8_t *data, size_t len) {
 }
 
 struct FIStringValueImpl: public FIStringValue {
-    inline FIStringValueImpl(std::string &&value_) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ { return value; }
+    FIStringValueImpl(std::string &&value_) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
+        return value;
+    }
 };
 
 std::shared_ptr<FIStringValue> FIStringValue::create(std::string &&value) {
@@ -151,8 +154,13 @@ std::shared_ptr<FIStringValue> FIStringValue::create(std::string &&value) {
 struct FIHexValueImpl: public FIHexValue {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FIHexValueImpl(std::vector<uint8_t> &&value_):  strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FIHexValueImpl(std::vector<uint8_t> &&value_)
+    : strValueValid( false ) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
         if (!strValueValid) {
             strValueValid = true;
             std::ostringstream os;
@@ -160,8 +168,9 @@ struct FIHexValueImpl: public FIHexValue {
             std::for_each(value.begin(), value.end(), [&](uint8_t c) { os << std::setw(2) << static_cast<int>(c); });
             strValue = os.str();
         }
+
         return strValue;
-    };
+    }
 };
 
 std::shared_ptr<FIHexValue> FIHexValue::create(std::vector<uint8_t> &&value) {
@@ -171,8 +180,13 @@ std::shared_ptr<FIHexValue> FIHexValue::create(std::vector<uint8_t> &&value) {
 struct FIBase64ValueImpl: public FIBase64Value {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FIBase64ValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FIBase64ValueImpl(std::vector<uint8_t> &&value_)
+            : strValueValid(false) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
         if (!strValueValid) {
             strValueValid = true;
             std::ostringstream os;
@@ -182,33 +196,35 @@ struct FIBase64ValueImpl: public FIBase64Value {
             for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
                 c2 = value[i];
                 switch (imod3) {
-                case 0:
-                    os << basis_64[c2 >> 2];
-                    imod3 = 1;
-                    break;
+                    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) | ((c2 & 0xf0) >> 4)];
-                    imod3 = 2;
+                    os << basis_64[(c1 & 0x03) << 4] << "==";
                     break;
                 case 2:
-                    os << basis_64[((c1 & 0x0f) << 2) | ((c2 & 0xc0) >> 6)] << basis_64[c2 & 0x3f];
-                    imod3 = 0;
+                    os << basis_64[(c1 & 0x0f) << 2] << '=';
                     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[];
 };
 
@@ -221,8 +237,13 @@ std::shared_ptr<FIBase64Value> FIBase64Value::create(std::vector<uint8_t> &&valu
 struct FIShortValueImpl: public FIShortValue {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FIShortValueImpl(std::vector<int16_t> &&value_): strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FIShortValueImpl(std::vector<int16_t> &&value_)
+            : strValueValid(false) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
         if (!strValueValid) {
             strValueValid = true;
             std::ostringstream os;
@@ -230,6 +251,7 @@ struct FIShortValueImpl: public FIShortValue {
             std::for_each(value.begin(), value.end(), [&](int16_t s) { if (++n > 1) os << ' '; os << s; });
             strValue = os.str();
         }
+
         return strValue;
     }
 };
@@ -241,8 +263,13 @@ std::shared_ptr<FIShortValue> FIShortValue::create(std::vector<int16_t> &&value)
 struct FIIntValueImpl: public FIIntValue {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FIIntValueImpl(std::vector<int32_t> &&value_): strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FIIntValueImpl(std::vector<int32_t> &&value_)
+            : strValueValid(false) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
         if (!strValueValid) {
             strValueValid = true;
             std::ostringstream os;
@@ -250,8 +277,9 @@ struct FIIntValueImpl: public FIIntValue {
             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> FIIntValue::create(std::vector<int32_t> &&value) {
@@ -261,8 +289,13 @@ std::shared_ptr<FIIntValue> FIIntValue::create(std::vector<int32_t> &&value) {
 struct FILongValueImpl: public FILongValue {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FILongValueImpl(std::vector<int64_t> &&value_): strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FILongValueImpl(std::vector<int64_t> &&value_)
+            : strValueValid(false) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
         if (!strValueValid) {
             strValueValid = true;
             std::ostringstream os;
@@ -270,8 +303,9 @@ struct FILongValueImpl: public FILongValue {
             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> FILongValue::create(std::vector<int64_t> &&value) {
@@ -281,16 +315,24 @@ std::shared_ptr<FILongValue> FILongValue::create(std::vector<int64_t> &&value) {
 struct FIBoolValueImpl: public FIBoolValue {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FIBoolValueImpl(std::vector<bool> &&value_): strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FIBoolValueImpl(std::vector<bool> &&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; });
+            std::for_each(value.begin(), value.end(), [&](bool b) {
+                if (++n > 1) os << ' '; os << b;
+            });
             strValue = os.str();
         }
+
         return strValue;
     };
 };
@@ -302,8 +344,13 @@ std::shared_ptr<FIBoolValue> FIBoolValue::create(std::vector<bool> &&value) {
 struct FIFloatValueImpl: public FIFloatValue {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FIFloatValueImpl(std::vector<float> &&value_): strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FIFloatValueImpl(std::vector<float> &&value_)
+            : strValueValid(false) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
         if (!strValueValid) {
             strValueValid = true;
             std::ostringstream os;
@@ -311,6 +358,7 @@ struct FIFloatValueImpl: public FIFloatValue {
             std::for_each(value.begin(), value.end(), [&](float f) { if (++n > 1) os << ' '; os << f; });
             strValue = os.str();
         }
+
         return strValue;
     }
 };
@@ -322,8 +370,13 @@ std::shared_ptr<FIFloatValue> FIFloatValue::create(std::vector<float> &&value) {
 struct FIDoubleValueImpl: public FIDoubleValue {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FIDoubleValueImpl(std::vector<double> &&value_): strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FIDoubleValueImpl(std::vector<double> &&value_)
+            : strValueValid(false) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
         if (!strValueValid) {
             strValueValid = true;
             std::ostringstream os;
@@ -342,8 +395,13 @@ std::shared_ptr<FIDoubleValue> FIDoubleValue::create(std::vector<double> &&value
 struct FIUUIDValueImpl: public FIUUIDValue {
     mutable std::string strValue;
     mutable bool strValueValid;
-    inline FIUUIDValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ {
+
+    FIUUIDValueImpl(std::vector<uint8_t> &&value_)
+                : strValueValid(false) {
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
         if (!strValueValid) {
             strValueValid = true;
             std::ostringstream os;
@@ -381,7 +439,7 @@ struct FIUUIDValueImpl: public FIUUIDValue {
             strValue = os.str();
         }
         return strValue;
-    };
+    }
 };
 
 std::shared_ptr<FIUUIDValue> FIUUIDValue::create(std::vector<uint8_t> &&value) {
@@ -389,8 +447,13 @@ std::shared_ptr<FIUUIDValue> FIUUIDValue::create(std::vector<uint8_t> &&value) {
 }
 
 struct FICDATAValueImpl: public FICDATAValue {
-    inline FICDATAValueImpl(std::string &&value_) { value = std::move(value_); }
-    virtual const std::string &toString() const /*override*/ { return value; }
+    FICDATAValueImpl(std::string &&value_){
+        value = std::move(value_);
+    }
+
+    const std::string &toString() const override {
+        return value;
+    }
 };
 
 std::shared_ptr<FICDATAValue> FICDATAValue::create(std::string &&value) {
@@ -398,19 +461,19 @@ std::shared_ptr<FICDATAValue> FICDATAValue::create(std::string &&value) {
 }
 
 struct FIHexDecoder: public FIDecoder {
-    virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
+    std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) override {
         return FIHexValue::create(std::vector<uint8_t>(data, data + len));
     }
 };
 
 struct FIBase64Decoder: public FIDecoder {
-    virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
+    std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) override {
         return FIBase64Value::create(std::vector<uint8_t>(data, data + len));
     }
 };
 
 struct FIShortDecoder: public FIDecoder {
-    virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
+    std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) override {
         if (len & 1) {
             throw DeadlyImportError(parseErrorMessage);
         }
@@ -427,7 +490,7 @@ struct FIShortDecoder: public FIDecoder {
 };
 
 struct FIIntDecoder: public FIDecoder {
-    virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
+    std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) override {
         if (len & 3) {
             throw DeadlyImportError(parseErrorMessage);
         }
@@ -444,7 +507,7 @@ struct FIIntDecoder: public FIDecoder {
 };
 
 struct FILongDecoder: public FIDecoder {
-    virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
+    std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) override {
         if (len & 7) {
             throw DeadlyImportError(parseErrorMessage);
         }

+ 4 - 9
code/X3D/FIReader.hpp

@@ -49,19 +49,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
 
-//#include <wchar.h>
 #include <string>
 #include <memory>
 #include <cerrno>
 #include <cwchar>
 #include <vector>
-//#include <stdio.h>
-//#include <cstdint>
-#ifdef ASSIMP_USE_HUNTER
-#  include <irrXML/irrXML.h>
-#else
-#  include <assimp/XmlParser.h>
-#endif
+
+#include <assimp/XmlParser.h>
 
 namespace Assimp {
 
@@ -165,9 +159,10 @@ struct FIVocabulary {
 
 class IOStream;
 
-class FIReader: public irr::io::IIrrXMLReader<char, irr::io::IXMLBase> {
+class FIReader {
 public:
 	virtual ~FIReader();
+
     virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const = 0;
 
     virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char *name) const = 0;