Merge branch 'pugi_xml' of https://github.com/assimp/assimp into pugi_xml
commit
c2f0bf68af
|
@ -115,10 +115,9 @@ bool AMFImporter::Find_NodeElement(const std::string &pID, const AMFNodeElementB
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list<aiNode *> &pNodeList, aiNode **pNode) const {
|
||||
bool AMFImporter::Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const {
|
||||
aiString node_name(pID.c_str());
|
||||
|
||||
for (aiNode *node : pNodeList) {
|
||||
for (aiNode *node : nodeArray) {
|
||||
if (node->mName == node_name) {
|
||||
if (pNode != nullptr) {
|
||||
*pNode = node;
|
||||
|
@ -267,7 +266,7 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
|
|||
}
|
||||
|
||||
mXmlParser = new XmlParser();
|
||||
if (!mXmlParser->parse( file.get() )) {
|
||||
if (!mXmlParser->parse(file.get())) {
|
||||
delete mXmlParser;
|
||||
throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
|
||||
}
|
||||
|
@ -279,6 +278,15 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
|
|||
ParseNode_Root();
|
||||
} // namespace Assimp
|
||||
|
||||
void AMFImporter::ParseHelper_Node_Enter(AMFNodeElementBase *node) {
|
||||
mNodeElement_Cur->Child.push_back(node); // add new element to current element child list.
|
||||
mNodeElement_Cur = node;
|
||||
}
|
||||
|
||||
void AMFImporter::ParseHelper_Node_Exit() {
|
||||
if (mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent;
|
||||
}
|
||||
|
||||
// <amf
|
||||
// unit="" - The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
|
||||
// version="" - Version of file format.
|
||||
|
@ -327,9 +335,8 @@ void AMFImporter::ParseNode_Root() {
|
|||
} else if (currentName == "metadata") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
}
|
||||
mNodeElement_Cur = ne; // force restore "current" element
|
||||
}
|
||||
|
||||
mNodeElement_Cur = ne; // force restore "current" element
|
||||
mNodeElement_List.push_back(ne); // add to node element list because its a new object in graph.
|
||||
}
|
||||
|
||||
|
@ -354,15 +361,18 @@ void AMFImporter::ParseNode_Constellation(XmlNode &node) {
|
|||
}
|
||||
|
||||
// Check for child nodes
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
std::string name = currentNode.name();
|
||||
if (name == "instance") {
|
||||
ParseNode_Instance(currentNode);
|
||||
} else if (name == "metadata") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
std::string name = currentNode.name();
|
||||
if (name == "instance") {
|
||||
ParseNode_Instance(currentNode);
|
||||
} else if (name == "metadata") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.empty()) {
|
||||
ParseHelper_Node_Exit();
|
||||
} else {
|
||||
mNodeElement_Cur->Child.push_back(ne);
|
||||
}
|
||||
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
|
||||
|
@ -390,31 +400,34 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
|
|||
AMFInstance &als = *((AMFInstance *)ne);
|
||||
als.ObjectID = objectid;
|
||||
|
||||
if (node.empty()) {
|
||||
mNodeElement_Cur->Child.push_back(ne);
|
||||
}
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
bool read_flag[6] = { false, false, false, false, false, false };
|
||||
std::string currentName = currentNode.name();
|
||||
if (currentName == "deltax") {
|
||||
read_flag[0] = true;
|
||||
als.Delta.x = (ai_real) std::atof(currentNode.value());
|
||||
} else if (currentName == "deltay") {
|
||||
read_flag[1] = true;
|
||||
als.Delta.y = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "deltaz") {
|
||||
read_flag[2] = true;
|
||||
als.Delta.z = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "rx") {
|
||||
read_flag[3] = true;
|
||||
als.Delta.x = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "ry") {
|
||||
read_flag[4] = true;
|
||||
als.Delta.y = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "rz") {
|
||||
read_flag[5] = true;
|
||||
als.Delta.z = (ai_real)std::atof(currentNode.value());
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
bool read_flag[6] = { false, false, false, false, false, false };
|
||||
std::string currentName = currentNode.name();
|
||||
if (currentName == "deltax") {
|
||||
read_flag[0] = true;
|
||||
als.Delta.x = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "deltay") {
|
||||
read_flag[1] = true;
|
||||
als.Delta.y = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "deltaz") {
|
||||
read_flag[2] = true;
|
||||
als.Delta.z = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "rx") {
|
||||
read_flag[3] = true;
|
||||
als.Delta.x = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "ry") {
|
||||
read_flag[4] = true;
|
||||
als.Delta.y = (ai_real)std::atof(currentNode.value());
|
||||
} else if (currentName == "rz") {
|
||||
read_flag[5] = true;
|
||||
als.Delta.z = (ai_real)std::atof(currentNode.value());
|
||||
}
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
} else {
|
||||
mNodeElement_Cur->Child.push_back(ne);
|
||||
}
|
||||
|
||||
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
|
||||
|
@ -428,7 +441,7 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
|
|||
// Multi elements - Yes.
|
||||
// Parent element - <amf>.
|
||||
void AMFImporter::ParseNode_Object(XmlNode &node) {
|
||||
|
||||
|
||||
AMFNodeElementBase *ne(nullptr);
|
||||
|
||||
// Read attributes for node <object>.
|
||||
|
@ -445,19 +458,22 @@ void AMFImporter::ParseNode_Object(XmlNode &node) {
|
|||
|
||||
// Check for child nodes
|
||||
bool col_read = false;
|
||||
if (node.empty()) {
|
||||
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
|
||||
}
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == "color") {
|
||||
ParseNode_Color(currentNode);
|
||||
col_read = true;
|
||||
} else if (currentName == "mesh") {
|
||||
ParseNode_Mesh(currentNode);
|
||||
} else if (currentName == "metadata") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == "color") {
|
||||
ParseNode_Color(currentNode);
|
||||
col_read = true;
|
||||
} else if (currentName == "mesh") {
|
||||
ParseNode_Mesh(currentNode);
|
||||
} else if (currentName == "metadata") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
}
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
} else {
|
||||
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.
|
||||
|
|
|
@ -139,6 +139,10 @@ private:
|
|||
const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
|
||||
};
|
||||
|
||||
using AMFMetaDataArray = std::vector<AMFMetadata*>;
|
||||
using MeshArray = std::vector<aiMesh*>;
|
||||
using NodeArray = std::vector<aiNode*>;
|
||||
|
||||
/// Clear all temporary data.
|
||||
void Clear();
|
||||
|
||||
|
@ -170,13 +174,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<AMFMetadata *> &pMetadataList, aiNode &pSceneNode) const;
|
||||
void Postprocess_AddMetadata(const AMFMetaDataArray &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 AMFObject &pNodeElement, std::list<aiMesh *> &pMeshList, aiNode **pSceneNode);
|
||||
/// \param [out] meshList - 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 AMFObject &pNodeElement, MeshArray &meshList, aiNode **pSceneNode);
|
||||
|
||||
/// Create mesh for every <volume> in <mesh>.
|
||||
/// \param [in] pNodeElement - reference to node element which kept <mesh> data.
|
||||
|
@ -189,7 +193,7 @@ private:
|
|||
/// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's.
|
||||
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);
|
||||
MeshArray &pMeshList, aiNode &pSceneNode);
|
||||
|
||||
/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
|
||||
/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
|
||||
|
@ -197,8 +201,8 @@ private:
|
|||
|
||||
/// 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(AMFConstellation &pConstellation, std::list<aiNode *> &pNodeList) const;
|
||||
/// \param [out] nodeArray - reference to aiNode's list.
|
||||
void Postprocess_BuildConstellation(AMFConstellation &pConstellation, NodeArray &nodeArray) const;
|
||||
|
||||
/// Build Assimp scene graph in aiScene from collected data.
|
||||
/// \param [out] pScene - pointer to aiScene where tree will be built.
|
||||
|
@ -270,13 +274,14 @@ public:
|
|||
/// \param [in] pFile - name of file to be parsed.
|
||||
/// \param [in] pIOHandler - pointer to IO helper object.
|
||||
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
|
||||
|
||||
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
|
||||
void ParseHelper_Node_Exit();
|
||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
|
||||
void GetExtensionList(std::set<std::string> &pExtensionList);
|
||||
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
||||
const aiImporterDesc *GetInfo() const;
|
||||
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
||||
bool Find_ConvertedNode(const std::string &pID, std::list<aiNode *> &pNodeList, aiNode **pNode) const;
|
||||
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
||||
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
||||
void Throw_CloseNotFound(const std::string &nodeName);
|
||||
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
|
||||
|
|
|
@ -67,19 +67,22 @@ void AMFImporter::ParseNode_Mesh(XmlNode &node) {
|
|||
if (0 != ASSIMP_stricmp(node.name(), "mesh")) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool found_verts = false, found_volumes = false;
|
||||
pugi::xml_node vertNode = node.child("vertices");
|
||||
if (!vertNode.empty()) {
|
||||
ParseNode_Vertices(vertNode);
|
||||
found_verts = true;
|
||||
}
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
pugi::xml_node vertNode = node.child("vertices");
|
||||
if (!vertNode.empty()) {
|
||||
ParseNode_Vertices(vertNode);
|
||||
found_verts = true;
|
||||
}
|
||||
|
||||
pugi::xml_node volumeNode = node.child("volume");
|
||||
if (!volumeNode.empty()) {
|
||||
ParseNode_Volume(volumeNode);
|
||||
found_volumes = true;
|
||||
}
|
||||
pugi::xml_node volumeNode = node.child("volume");
|
||||
if (!volumeNode.empty()) {
|
||||
ParseNode_Volume(volumeNode);
|
||||
found_volumes = true;
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
}
|
||||
|
||||
if (!found_verts && !found_volumes) {
|
||||
mNodeElement_Cur->Child.push_back(ne);
|
||||
|
@ -102,7 +105,12 @@ void AMFImporter::ParseNode_Vertices(XmlNode &node) {
|
|||
// Check for child nodes
|
||||
pugi::xml_node vertexNode = node.child("vertex");
|
||||
if (!vertexNode.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
|
||||
ParseNode_Vertex(vertexNode);
|
||||
|
||||
ParseHelper_Node_Exit();
|
||||
|
||||
} else {
|
||||
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
|
||||
} // if(!mReader->isEmptyElement()) else
|
||||
|
@ -125,16 +133,21 @@ void AMFImporter::ParseNode_Vertex(XmlNode &node) {
|
|||
pugi::xml_node colorNode = node.child("color");
|
||||
bool col_read = false;
|
||||
bool coord_read = false;
|
||||
if (!colorNode.empty()) {
|
||||
ParseNode_Color(colorNode);
|
||||
col_read = true;
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
if (!colorNode.empty()) {
|
||||
ParseNode_Color(colorNode);
|
||||
col_read = true;
|
||||
}
|
||||
pugi::xml_node coordNode = node.child("coordinates");
|
||||
if (!coordNode.empty()) {
|
||||
ParseNode_Coordinates(coordNode);
|
||||
coord_read = true;
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
}
|
||||
pugi::xml_node coordNode = node.child("coordinates");
|
||||
if (!coordNode.empty()) {
|
||||
ParseNode_Coordinates(coordNode);
|
||||
coord_read = true;
|
||||
}
|
||||
if (!coord_read && !coord_read) {
|
||||
|
||||
if (!coord_read && !col_read) {
|
||||
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
|
||||
}
|
||||
|
||||
|
@ -158,11 +171,23 @@ void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
|
|||
ne = new AMFCoordinates(mNodeElement_Cur);
|
||||
|
||||
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "X") {
|
||||
XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
|
||||
} else if (currentName == "Y") {
|
||||
XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
|
||||
} else if (currentName == "Z") {
|
||||
XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
|
||||
}
|
||||
}
|
||||
|
||||
als.Coordinate.x = (ai_real)node.attribute("x").as_float();
|
||||
als.Coordinate.y = (ai_real)node.attribute("y").as_float();
|
||||
als.Coordinate.z = (ai_real)node.attribute("z").as_float();
|
||||
mNodeElement_Cur->Child.push_back(ne);
|
||||
ParseHelper_Node_Exit();
|
||||
} else {
|
||||
mNodeElement_Cur->Child.push_back(ne);
|
||||
}
|
||||
|
||||
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
|
||||
}
|
||||
|
@ -188,24 +213,26 @@ void AMFImporter::ParseNode_Volume(XmlNode &node) {
|
|||
|
||||
((AMFVolume *)ne)->Type = type;
|
||||
// Check for child nodes
|
||||
if (node.empty()) {
|
||||
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
|
||||
}
|
||||
|
||||
bool col_read = false;
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == "color") {
|
||||
if (col_read) Throw_MoreThanOnceDefined(currentName ,"color", "Only one color can be defined for <volume>.");
|
||||
ParseNode_Color(currentNode);
|
||||
col_read = true;
|
||||
} else if (currentName == "triangle") {
|
||||
ParseNode_Triangle(currentNode);
|
||||
} else if (currentName == "metadata") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
} else if (currentName == "volume") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == "color") {
|
||||
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <volume>.");
|
||||
ParseNode_Color(currentNode);
|
||||
col_read = true;
|
||||
} else if (currentName == "triangle") {
|
||||
ParseNode_Triangle(currentNode);
|
||||
} else if (currentName == "metadata") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
} else if (currentName == "volume") {
|
||||
ParseNode_Metadata(currentNode);
|
||||
}
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
} else {
|
||||
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.
|
||||
|
@ -228,36 +255,39 @@ void AMFImporter::ParseNode_Triangle(XmlNode &node) {
|
|||
|
||||
AMFTriangle &als = *((AMFTriangle *)ne); // alias for convenience
|
||||
|
||||
if (node.empty()) {
|
||||
bool col_read = false, tex_read = false;
|
||||
bool read_flag[3] = { false, false, false };
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == "color") {
|
||||
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <triangle>.");
|
||||
ParseNode_Color(currentNode);
|
||||
col_read = true;
|
||||
} else if (currentName == "texmap") {
|
||||
ParseNode_TexMap(currentNode);
|
||||
tex_read = true;
|
||||
} else if (currentName == "map") {
|
||||
ParseNode_TexMap(currentNode, true);
|
||||
tex_read = true;
|
||||
} else if (currentName == "v1") {
|
||||
als.V[0] = std::atoi(currentNode.value());
|
||||
read_flag[0] = true;
|
||||
} else if (currentName == "v2") {
|
||||
als.V[1] = std::atoi(currentNode.value());
|
||||
read_flag[1] = true;
|
||||
} else if (currentName == "v3") {
|
||||
als.V[2] = std::atoi(currentNode.value());
|
||||
read_flag[2] = true;
|
||||
}
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
} else {
|
||||
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
|
||||
}
|
||||
|
||||
// Check for child nodes
|
||||
bool col_read = false, tex_read = false;
|
||||
bool read_flag[3] = { false, false, false };
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == "color") {
|
||||
if (col_read) Throw_MoreThanOnceDefined(currentName , "color", "Only one color can be defined for <triangle>.");
|
||||
ParseNode_Color(currentNode);
|
||||
col_read = true;
|
||||
} else if (currentName == "texmap") {
|
||||
ParseNode_TexMap(currentNode);
|
||||
tex_read = true;
|
||||
} else if (currentName == "map") {
|
||||
ParseNode_TexMap(currentNode, true);
|
||||
tex_read = true;
|
||||
} else if (currentName == "v1") {
|
||||
als.V[0] = std::atoi(currentNode.value());
|
||||
read_flag[0] = true;
|
||||
} else if (currentName == "v2") {
|
||||
als.V[1] = std::atoi(currentNode.value());
|
||||
read_flag[1] = true;
|
||||
} else if (currentName == "v3") {
|
||||
als.V[2] = std::atoi(currentNode.value());
|
||||
read_flag[2] = true;
|
||||
}
|
||||
}
|
||||
if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) {
|
||||
throw DeadlyImportError("Not all vertices of the triangle are defined.");
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@ 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"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
|
@ -76,22 +75,24 @@ void AMFImporter::ParseNode_Color(XmlNode &node) {
|
|||
|
||||
als.Profile = profile;
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
bool read_flag[4] = { false, false, false, false };
|
||||
for (pugi::xml_node &child : node.children()) {
|
||||
std::string name = child.name();
|
||||
if ( name == "r") {
|
||||
read_flag[0] = true;
|
||||
als.Color.r = (ai_real)::atof(child.value());
|
||||
XmlParser::getValueAsFloat(child, als.Color.r);
|
||||
} else if (name == "g") {
|
||||
read_flag[1] = true;
|
||||
als.Color.g = (ai_real)::atof(child.value());
|
||||
XmlParser::getValueAsFloat(child, als.Color.g);
|
||||
} else if (name == "b") {
|
||||
read_flag[2] = true;
|
||||
als.Color.b = (ai_real)::atof(child.value());
|
||||
} else if (name == "g") {
|
||||
XmlParser::getValueAsFloat(child, als.Color.b);
|
||||
} else if (name == "a") {
|
||||
read_flag[3] = true;
|
||||
als.Color.a = (ai_real) ::atof(child.value());
|
||||
}
|
||||
XmlParser::getValueAsFloat(child, als.Color.a);
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
}
|
||||
// check that all components was defined
|
||||
if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
|
||||
|
@ -126,6 +127,7 @@ void AMFImporter::ParseNode_Material(XmlNode &node) {
|
|||
// Check for child nodes
|
||||
if (!node.empty()) {
|
||||
bool col_read = false;
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (pugi::xml_node &child : node.children()) {
|
||||
const std::string name = child.name();
|
||||
if (name == "color") {
|
||||
|
@ -135,6 +137,7 @@ void AMFImporter::ParseNode_Material(XmlNode &node) {
|
|||
ParseNode_Metadata(child);
|
||||
}
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
} else {
|
||||
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||
}
|
||||
|
@ -230,15 +233,27 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
|
|||
// Texture coordinates for every vertex of triangle.
|
||||
void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
|
||||
// Read attributes for node <color>.
|
||||
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();
|
||||
|
||||
AMFNodeElementBase *ne = new AMFTexMap(mNodeElement_Cur);
|
||||
AMFTexMap &als = *((AMFTexMap *)ne); //
|
||||
std::string rtexid, gtexid, btexid, atexid;
|
||||
if (!node.empty()) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "rtexid") {
|
||||
XmlParser::getValueAsString(node, rtexid);
|
||||
} else if (currentName == "gtexid") {
|
||||
XmlParser::getValueAsString(node, gtexid);
|
||||
} else if (currentName == "btexid") {
|
||||
XmlParser::getValueAsString(node, btexid);
|
||||
} else if (currentName == "atexid") {
|
||||
XmlParser::getValueAsString(node, atexid);
|
||||
}
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
}
|
||||
|
||||
// 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.");
|
||||
|
|
|
@ -124,7 +124,7 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElem
|
|||
}
|
||||
}
|
||||
|
||||
col_idx++;
|
||||
++col_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
|
|||
|
||||
// R
|
||||
if (!r.empty()) {
|
||||
if (!Find_NodeElement(r, AMFNodeElementBase::EType::ENET_Texture, &t_tex)) Throw_ID_NotFound(r);
|
||||
if (!Find_NodeElement(r, AMFNodeElementBase::EType::ENET_Texture, &t_tex)) {
|
||||
Throw_ID_NotFound(r);
|
||||
}
|
||||
|
||||
src_texture[0] = (AMFTexture *)t_tex;
|
||||
src_texture_4check.push_back((AMFTexture *)t_tex);
|
||||
|
@ -166,7 +168,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
|
|||
|
||||
// G
|
||||
if (!g.empty()) {
|
||||
if (!Find_NodeElement(g, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(g);
|
||||
if (!Find_NodeElement(g, AMFNodeElementBase::ENET_Texture, &t_tex)) {
|
||||
Throw_ID_NotFound(g);
|
||||
}
|
||||
|
||||
src_texture[1] = (AMFTexture *)t_tex;
|
||||
src_texture_4check.push_back((AMFTexture *)t_tex);
|
||||
|
@ -176,7 +180,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
|
|||
|
||||
// B
|
||||
if (!b.empty()) {
|
||||
if (!Find_NodeElement(b, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(b);
|
||||
if (!Find_NodeElement(b, AMFNodeElementBase::ENET_Texture, &t_tex)) {
|
||||
Throw_ID_NotFound(b);
|
||||
}
|
||||
|
||||
src_texture[2] = (AMFTexture *)t_tex;
|
||||
src_texture_4check.push_back((AMFTexture *)t_tex);
|
||||
|
@ -186,7 +192,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
|
|||
|
||||
// A
|
||||
if (!a.empty()) {
|
||||
if (!Find_NodeElement(a, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(a);
|
||||
if (!Find_NodeElement(a, AMFNodeElementBase::ENET_Texture, &t_tex)) {
|
||||
Throw_ID_NotFound(a);
|
||||
}
|
||||
|
||||
src_texture[3] = (AMFTexture *)t_tex;
|
||||
src_texture_4check.push_back((AMFTexture *)t_tex);
|
||||
|
@ -211,8 +219,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
|
|||
converted_texture.Depth = src_texture_4check[0]->Depth;
|
||||
// if one of source texture is tiled then converted texture is tiled too.
|
||||
converted_texture.Tiled = false;
|
||||
for (uint8_t i = 0; i < src_texture_4check.size(); i++)
|
||||
for (uint8_t i = 0; i < src_texture_4check.size(); ++i) {
|
||||
converted_texture.Tiled |= src_texture_4check[i]->Tiled;
|
||||
}
|
||||
|
||||
// Create format hint.
|
||||
strcpy(converted_texture.FormatHint, "rgba0000"); // copy initial string.
|
||||
|
@ -309,10 +318,11 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
|
|||
} while (!pInputList.empty());
|
||||
}
|
||||
|
||||
void AMFImporter::Postprocess_AddMetadata(const std::list<AMFMetadata *> &metadataList, aiNode &sceneNode) const {
|
||||
void AMFImporter::Postprocess_AddMetadata(const AMFMetaDataArray &metadataList, aiNode &sceneNode) const {
|
||||
if (metadataList.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sceneNode.mMetaData != nullptr) {
|
||||
throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");
|
||||
}
|
||||
|
@ -326,7 +336,7 @@ void AMFImporter::Postprocess_AddMetadata(const std::list<AMFMetadata *> &metada
|
|||
}
|
||||
}
|
||||
|
||||
void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, std::list<aiMesh *> &pMeshList, aiNode **pSceneNode) {
|
||||
void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, MeshArray &meshList, aiNode **pSceneNode) {
|
||||
AMFColor *object_color = nullptr;
|
||||
|
||||
// create new aiNode and set name as <object> has.
|
||||
|
@ -346,14 +356,13 @@ void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement,
|
|||
// Create arrays from children of mesh: vertices.
|
||||
PostprocessHelper_CreateMeshDataArray(*((AMFMesh *)ne_child), vertex_arr, color_arr);
|
||||
// Use this arrays as a source when creating every aiMesh
|
||||
Postprocess_BuildMeshSet(*((AMFMesh *)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode);
|
||||
Postprocess_BuildMeshSet(*((AMFMesh *)ne_child), vertex_arr, color_arr, object_color, meshList, **pSceneNode);
|
||||
}
|
||||
} // for(const CAMFImporter_NodeElement* ne_child: pNodeElement)
|
||||
}
|
||||
|
||||
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) {
|
||||
const std::vector<AMFColor *> &pVertexColorArray, const AMFColor *pObjectColor, MeshArray &pMeshList, aiNode &pSceneNode) {
|
||||
std::list<unsigned int> mesh_idx;
|
||||
|
||||
// all data stored in "volume", search for it.
|
||||
|
@ -659,7 +668,7 @@ void AMFImporter::Postprocess_BuildMaterial(const AMFMaterial &pMaterial) {
|
|||
mMaterial_Converted.push_back(new_mat);
|
||||
}
|
||||
|
||||
void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellation, std::list<aiNode *> &pNodeList) const {
|
||||
void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellation, NodeArray &nodeArray) const {
|
||||
aiNode *con_node;
|
||||
std::list<aiNode *> ch_node;
|
||||
|
||||
|
@ -682,7 +691,7 @@ void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellatio
|
|||
// create alias for conveniance
|
||||
AMFInstance &als = *((AMFInstance *)ne);
|
||||
// find referenced object
|
||||
if (!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
|
||||
if (!Find_ConvertedNode(als.ObjectID, nodeArray, &found_node)) Throw_ID_NotFound(als.ObjectID);
|
||||
|
||||
// create node for applying transformation
|
||||
t_node = new aiNode;
|
||||
|
@ -711,13 +720,13 @@ void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellatio
|
|||
con_node->mChildren[ch_idx++] = node;
|
||||
|
||||
// and place "root" of <constellation> node to node list
|
||||
pNodeList.push_back(con_node);
|
||||
nodeArray.push_back(con_node);
|
||||
}
|
||||
|
||||
void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
|
||||
std::list<aiNode *> node_list;
|
||||
std::list<aiMesh *> mesh_list;
|
||||
std::list<AMFMetadata *> meta_list;
|
||||
NodeArray nodeArray;
|
||||
MeshArray mesh_list;
|
||||
AMFMetaDataArray meta_list;
|
||||
|
||||
//
|
||||
// Because for AMF "material" is just complex colors mixing so aiMaterial will not be used.
|
||||
|
@ -739,7 +748,9 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
|
|||
} // for(const CAMFImporter_NodeElement* ne: mNodeElement_List)
|
||||
|
||||
// Check if root element are found.
|
||||
if (root_el == nullptr) throw DeadlyImportError("Root(<amf>) element not found.");
|
||||
if (root_el == nullptr) {
|
||||
throw DeadlyImportError("Root(<amf>) element not found.");
|
||||
}
|
||||
|
||||
// after that walk through children of root and collect data. Five types of nodes can be placed at top level - in <amf>: <object>, <material>, <texture>,
|
||||
// <constellation> and <metadata>. But at first we must read <material> and <texture> because they will be used in <object>. <metadata> can be read
|
||||
|
@ -748,7 +759,9 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
|
|||
// 1. <material>
|
||||
// 2. <texture> will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet
|
||||
for (const AMFNodeElementBase *root_child : root_el->Child) {
|
||||
if (root_child->Type == AMFNodeElementBase::ENET_Material) Postprocess_BuildMaterial(*((AMFMaterial *)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>.
|
||||
|
@ -760,7 +773,9 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
|
|||
|
||||
// for <object> mesh and node must be built: object ID assigned to aiNode name and will be used in future for <instance>
|
||||
Postprocess_BuildNodeAndObject(*((AMFObject *)root_child), mesh_list, &tnode);
|
||||
if (tnode != nullptr) node_list.push_back(tnode);
|
||||
if (tnode != nullptr) {
|
||||
nodeArray.push_back(tnode);
|
||||
}
|
||||
}
|
||||
} // for(const CAMFImporter_NodeElement* root_child: root_el->Child)
|
||||
|
||||
|
@ -770,7 +785,7 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
|
|||
// 4. <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(*((AMFConstellation *)root_child), node_list);
|
||||
Postprocess_BuildConstellation(*((AMFConstellation *)root_child), nodeArray);
|
||||
}
|
||||
|
||||
// 5, <metadata>
|
||||
|
@ -788,17 +803,17 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
|
|||
// And at this step we are checking that relations.
|
||||
nl_clean_loop:
|
||||
|
||||
if (node_list.size() > 1) {
|
||||
if (nodeArray.size() > 1) {
|
||||
// walk through all nodes
|
||||
for (std::list<aiNode *>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it) {
|
||||
for (NodeArray::iterator nl_it = nodeArray.begin(); nl_it != nodeArray.end(); ++nl_it) {
|
||||
// and try to find them in another top nodes.
|
||||
std::list<aiNode *>::const_iterator next_it = nl_it;
|
||||
NodeArray::const_iterator next_it = nl_it;
|
||||
|
||||
++next_it;
|
||||
for (; next_it != node_list.end(); ++next_it) {
|
||||
for (; next_it != nodeArray.end(); ++next_it) {
|
||||
if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
|
||||
// if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
|
||||
node_list.erase(nl_it);
|
||||
nodeArray.erase(nl_it);
|
||||
|
||||
goto nl_clean_loop;
|
||||
}
|
||||
|
@ -811,10 +826,10 @@ nl_clean_loop:
|
|||
//
|
||||
//
|
||||
// Nodes
|
||||
if (!node_list.empty()) {
|
||||
std::list<aiNode *>::const_iterator nl_it = node_list.begin();
|
||||
if (!nodeArray.empty()) {
|
||||
NodeArray::const_iterator nl_it = nodeArray.begin();
|
||||
|
||||
pScene->mRootNode->mNumChildren = static_cast<unsigned int>(node_list.size());
|
||||
pScene->mRootNode->mNumChildren = static_cast<unsigned int>(nodeArray.size());
|
||||
pScene->mRootNode->mChildren = new aiNode *[pScene->mRootNode->mNumChildren];
|
||||
for (size_t i = 0; i < pScene->mRootNode->mNumChildren; i++) {
|
||||
// Objects and constellation that must be showed placed at top of hierarchy in <amf> node. So all aiNode's in node_list must have
|
||||
|
@ -827,7 +842,7 @@ nl_clean_loop:
|
|||
//
|
||||
// Meshes
|
||||
if (!mesh_list.empty()) {
|
||||
std::list<aiMesh *>::const_iterator ml_it = mesh_list.begin();
|
||||
MeshArray::const_iterator ml_it = mesh_list.begin();
|
||||
|
||||
pScene->mNumMeshes = static_cast<unsigned int>(mesh_list.size());
|
||||
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
|
||||
|
|
|
@ -621,7 +621,9 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
|
|||
} else if (currentName == "skin") {
|
||||
pController.mMeshId = currentNode.attribute("source").as_string();
|
||||
} else if (currentName == "bind_shape_matrix") {
|
||||
const char *content = currentNode.value();
|
||||
std::string v;
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
for (unsigned int a = 0; a < 16; a++) {
|
||||
// read a number
|
||||
content = fast_atoreal_move<ai_real>(content, pController.mBindShapeMatrix[a]);
|
||||
|
@ -2163,7 +2165,9 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
|
|||
|
||||
// how many parameters to read per transformation type
|
||||
static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
|
||||
const char *content = node.value();
|
||||
std::string value;
|
||||
XmlParser::getValueAsString(node, value);
|
||||
const char *content = value.c_str();
|
||||
|
||||
// read as many parameters and store in the transformation
|
||||
for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
|
||||
|
|
Loading…
Reference in New Issue