fix node collection for collada xml parsing

pull/2966/head
Kim Kulling 2020-09-01 07:51:17 +02:00
parent e62b4e5cce
commit 3c2133a3b9
3 changed files with 78 additions and 21 deletions

View File

@ -923,10 +923,10 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a light entry into the given light // Reads a light entry into the given light
void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) { void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
XmlNodeIterator xmlIt; XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node); xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode; XmlNode currentNode;
while (xmlIt.getNext(&currentNode)) { while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "spot") { if (currentName == "spot") {
pLight.mType = aiLightSource_SPOT; pLight.mType = aiLightSource_SPOT;
@ -985,7 +985,11 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a camera entry into the given light // Reads a camera entry into the given light
void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) { void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "orthographic") { if (currentName == "orthographic") {
camera.mOrtho = true; camera.mOrtho = true;
@ -1040,7 +1044,10 @@ void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an COMMON effect profile // Reads an COMMON effect profile
void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) { void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) {
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "newparam") { if (currentName == "newparam") {
// save ID // save ID
@ -1137,7 +1144,11 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
if (node.empty()) { if (node.empty()) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
// MAYA extensions // MAYA extensions
// ------------------------------------------------------- // -------------------------------------------------------
@ -1196,8 +1207,11 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
if (node.empty()) { if (node.empty()) {
return; return;
} }
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "color") { if (currentName == "color") {
// text content contains 4 floats // text content contains 4 floats
@ -1257,8 +1271,12 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
if (node.empty()) { if (node.empty()) {
return; return;
} }
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "surface") { if (currentName == "surface") {
// image ID given inside <init_from> tags // image ID given inside <init_from> tags
@ -1334,7 +1352,10 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "source") { if (currentName == "source") {
ReadSource(currentNode); ReadSource(currentNode);
@ -1355,7 +1376,10 @@ void ColladaParser::ReadSource(XmlNode &node) {
std::string sourceID; std::string sourceID;
XmlParser::getStdStrAttribute(node, "id", sourceID); XmlParser::getStdStrAttribute(node, "id", sourceID);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "float_array" || currentName == "IDREF_array" || currentName == "Name_array") { if (currentName == "float_array" || currentName == "IDREF_array" || currentName == "Name_array") {
ReadDataArray(currentNode); ReadDataArray(currentNode);
@ -1451,7 +1475,10 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
acc.mSource = source.c_str() + 1; // ignore the leading '#' acc.mSource = source.c_str() + 1; // ignore the leading '#'
acc.mSize = 0; // gets incremented with every param acc.mSize = 0; // gets incremented with every param
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "param") { if (currentName == "param") {
// read data param // read data param
@ -1576,7 +1603,10 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
ai_assert(primType != Prim_Invalid); ai_assert(primType != Prim_Invalid);
// also a number of <input> elements, but in addition a <p> primitive collection and probably index counts for all primitives // also a number of <input> elements, but in addition a <p> primitive collection and probably index counts for all primitives
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "input") { if (currentName == "input") {
ReadInputChannel(currentNode, perIndexData); ReadInputChannel(currentNode, perIndexData);
@ -1976,7 +2006,10 @@ void ColladaParser::ReadSceneLibrary(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "visual_scene") { if (currentName == "visual_scene") {
// read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then? // read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then?
@ -2008,7 +2041,10 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "node") { if (currentName == "node") {
Node *child = new Node; Node *child = new Node;
@ -2140,7 +2176,10 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Processes bind_vertex_input and bind elements // Processes bind_vertex_input and bind elements
void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) { void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) {
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "bind_vertex_input") { if (currentName == "bind_vertex_input") {
Collada::InputSemanticMapEntry vn; Collada::InputSemanticMapEntry vn;

View File

@ -231,14 +231,18 @@ using XmlParser = TXmlParser<pugi::xml_node>;
class XmlNodeIterator { class XmlNodeIterator {
public: public:
XmlNodeIterator() : XmlNodeIterator(XmlNode &parent) :
mParent(parent),
mNodes(), mNodes(),
mIndex(9999999) { mIndex(0) {
// empty // empty
} }
void collectChildrenPreOrder( XmlNode &node ) { void collectChildrenPreOrder( XmlNode &node ) {
mNodes.push_back(&node); if (node != mParent) {
std::string name = node.name();
mNodes.push_back(node);
}
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
collectChildrenPreOrder(currentNode); collectChildrenPreOrder(currentNode);
} }
@ -248,10 +252,12 @@ public:
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
collectChildrenPostOrder(currentNode); collectChildrenPostOrder(currentNode);
} }
mNodes.push_back(&node); if (node != mParent) {
mNodes.push_back(node);
}
} }
bool getNext(XmlNode *next) { bool getNext(XmlNode &next) {
if (mIndex == mNodes.size()) { if (mIndex == mNodes.size()) {
return false; return false;
} }
@ -268,10 +274,12 @@ public:
} }
mNodes.clear(); mNodes.clear();
mIndex = 0;
} }
private: private:
std::vector<XmlNode *> mNodes; XmlNode &mParent;
std::vector<XmlNode> mNodes;
size_t mIndex; size_t mIndex;
}; };

View File

@ -44,7 +44,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
class utXmlParser : public ::testing::Test { class utXmlParser : public ::testing::Test {
// empty public:
utXmlParser() :
Test(),
mIoSystem() {
// empty
}
protected:
DefaultIOSystem mIoSystem;
}; };
TEST_F(utXmlParser, parse_xml_test) { TEST_F(utXmlParser, parse_xml_test) {
@ -57,3 +65,5 @@ TEST_F(utXmlParser, parse_xml_test) {
EXPECT_TRUE(result); EXPECT_TRUE(result);
} }
TEST_F(utXmlParser, parse_xml_and_traverse_test) {
}