|
From: Mike D. <o3d...@us...> - 2004-07-21 19:35:01
|
Update of /cvsroot/grappelmann/spaceplane In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9108 Added Files: model_loader.cpp model_loader.h Log Message: - model loader initial import - loads models from various type of files --- NEW FILE: model_loader.h --- #ifndef MODEL_LOADER_H #define MODEL_LOADER_H #include <iostream> #include <xercesc/parsers/XercesDOMParser.hpp> #include <xercesc/dom/DOM.hpp> #include <xercesc/sax/HandlerBase.hpp> #include <xercesc/util/XMLString.hpp> #include <xercesc/util/PlatformUtils.hpp> #include <xercesc/dom/DOMElement.hpp> #include "scene_object.h" #include "mesh.h" #include <assert.h> #include <vector> XERCES_CPP_NAMESPACE_USE using namespace std; class ModelLoader { public: ModelLoader(); virtual SceneObject* loadModel(const string filename) = 0; private: }; class X3DLoader : public ModelLoader { public: X3DLoader(); virtual SceneObject* loadModel(const string filename); private: bool _parseX3DFile(const char* filename); SceneObject* _convertDOMNode(DOMNode* domNode, SceneObject* parent = NULL, long curLevel = 0); SceneObject* _createSceneObjectFromDOMNode(DOMNode* domNode); bool _convertCharToIntVector(vector<int>& intVector, string intString); }; /* $Log: model_loader.h,v $ Revision 1.1 2004/07/21 19:34:51 o3dozone - model loader initial import - loads models from various type of files */ #endif --- NEW FILE: model_loader.cpp --- /* $Id: model_loader.cpp,v 1.1 2004/07/21 19:34:51 o3dozone Exp $ */ #include "model_loader.h" ModelLoader::ModelLoader() { } X3DLoader::X3DLoader() { } SceneObject* X3DLoader::loadModel(const string filename) { if(!_parseX3DFile(filename.c_str())) { cout << "error parsing x3d file" << endl; abort(); } cout << "stopping now" << endl; abort(); return NULL; } bool X3DLoader::_parseX3DFile(const char* filename) { try { XMLPlatformUtils::Initialize(); } catch (const XMLException& toCatch) { char* message = XMLString::transcode(toCatch.getMessage()); cout << "Error during initialization [" << message << "]" << endl; XMLString::release(&message); return false; } XercesDOMParser* parser = new XercesDOMParser(); parser->setValidationScheme(XercesDOMParser::Val_Always); // optional. parser->setDoNamespaces(true); // optional ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase(); parser->setErrorHandler(errHandler); try { parser->parse(filename); DOMDocument* domDocument = parser->getDocument(); if(domDocument->getDocumentElement() == NULL) { cout << "empty document" << endl; return false; } else if(!_convertDOMNode(domDocument->getDocumentElement())) { cout << "couldn't dump dom document" << endl; return false; } } catch (const XMLException& toCatch) { char* message = XMLString::transcode(toCatch.getMessage()); cout << "Exception message is [" << message << "]" << endl; XMLString::release(&message); return false; } catch (const DOMException& toCatch) { char* message = XMLString::transcode(toCatch.msg); cout << "Exception message is [" << message << "]" << endl; XMLString::release(&message); return false; } catch (...) { cout << "Unexpected Exception \n" ; return false; } delete parser; delete errHandler; return true; } SceneObject* X3DLoader::_convertDOMNode(DOMNode* domNode, SceneObject* parent, long curLevel) { if(domNode == NULL) { cout << "<X3DLoader::_convertDOMNode>\tempty DOM node" << endl; return NULL; } // some sensible defaults SceneObject* scene = NULL; // if we don't have a parent, make one // normally used for the root node, but right now we're not parsing everything, // so we could land up with a sparse tree if(parent == NULL) { parent = new SceneObject(); } try { if(domNode->getNodeType() == DOMNode::ELEMENT_NODE) { cout << "[" << curLevel << "] node type [" << domNode->getNodeType() << "] node name [" << XMLString::transcode(domNode->getNodeName()) << "]" << endl; // value [" << XMLString::transcode(domNode->getNodeValue()) << "]" << endl; if(domNode->getNodeValue() != NULL) { cout << "[" << curLevel << "] value [" << XMLString::transcode(domNode->getNodeValue()) << "]" << endl; } // find the dom node attributes DOMNamedNodeMap* attributes = domNode->getAttributes(); if(attributes != NULL) { cout << "[" << curLevel << "] dumping attributes" << endl; // get a scene object from the DOM Node scene = _createSceneObjectFromDOMNode(domNode); if(scene == NULL) { cout << "<X3DLoader::_convertDOMNode>\tempty scene" << endl; return NULL; } cout << "[" << curLevel << "] dumping attributes complete" << endl; // dump this element's children first DOMNode* curChild = domNode->getFirstChild(); while(curChild != NULL) { // dump the child SceneObject* child = _convertDOMNode(curChild, scene, curLevel + 1); if(child != NULL) { scene->addChild(child); } // now get the child's sibling DOMNode* nextChild = curChild->getNextSibling(); curChild = nextChild; } } else { cout << "<X3DLoader::_convertDOMNode>\tignoring scene without attributes" << endl; scene = new SceneObject(); } } else if(domNode->getNodeType() == DOMNode::ATTRIBUTE_NODE) { cout << "<X3DLoader::_convertDOMNode>\tignoring attribute node" << endl; } else if(domNode->getNodeType() == DOMNode::TEXT_NODE) { //cout << "<X3DLoader::_convertDOMNode>\tignoring text node" << endl; return NULL; } } catch (const XMLException& toCatch) { char* message = XMLString::transcode(toCatch.getMessage()); cout << "Exception message is [" << message << "]" << endl; XMLString::release(&message); return NULL; } catch (const DOMException& toCatch) { char* message = XMLString::transcode(toCatch.msg); cout << "Exception message is [" << message << "]" << endl; XMLString::release(&message); return NULL; } catch (...) { cout << "Unexpected Exception \n" ; return NULL; } return scene; } SceneObject* X3DLoader::_createSceneObjectFromDOMNode(DOMNode* domNode) { assert(domNode != NULL); assert(domNode->getNodeType() == DOMNode::ELEMENT_NODE); // get a usefull version of this node's name char* nodeName = XMLString::transcode(domNode->getNodeName()); // This is the only node we are going to handle for the moment if(strcmp(nodeName, "IndexedFaceSet") == 0) { // this is a mesh Mesh* mesh = new Mesh(); // get the attributes (containing the coord/normal indexes) DOMNamedNodeMap* attributes = domNode->getAttributes(); if(attributes != NULL) { // get the coord indices DOMNode* coordIndexesNode = attributes->getNamedItem(XMLString::transcode("coordIndex")); vector<int> coordIndexes; if(coordIndexesNode->getNodeValue() != NULL) { //cout << "coordIndexes [" << XMLString::transcode(coordIndexesNode->getNodeValue()) << "]" << endl; _convertCharToIntVector(coordIndexes, XMLString::transcode(coordIndexesNode->getNodeValue())); } // get the normal indices DOMNode* normalIndexesNode = attributes->getNamedItem(XMLString::transcode("normalIndex")); vector<int> normalIndexes; if(normalIndexesNode->getNodeValue() != NULL) { //cout << "normalIndexes [" << XMLString::transcode(normalIndexesNode->getNodeValue()) << "]" << endl; _convertCharToIntVector(normalIndexes, XMLString::transcode(normalIndexesNode->getNodeValue())); } } // now we need to get the coord/normal objects nodes // done, return return mesh; } else { SceneObject* dummy = new SceneObject(); return dummy; } return NULL; } bool X3DLoader::_convertCharToIntVector(vector<int>& intVector, string intString) { string piece; string::size_type startPos = 0; string::size_type endPos = 0; while(endPos != string::npos) { endPos = intString.find(' ', startPos); if(endPos == string::npos) { break; } string::size_type pieceLength = endPos - startPos; piece = intString.substr(startPos, pieceLength); intVector.push_back(atoi(piece.c_str())); //cout << "piece [" << piece.c_str() << "]" << endl; startPos += pieceLength; while((intString[startPos] == ' ') && (startPos != string::npos)) { startPos++; } endPos = startPos; } cout << "<X3DLoader::_convertCharToIntVector>\tvector size [" << intVector.size() << "]" << endl; return true; } /* $Log: model_loader.cpp,v $ Revision 1.1 2004/07/21 19:34:51 o3dozone - model loader initial import - loads models from various type of files */ |