// --------------------------------------------------------------------------- // Includes for all the program files to see // --------------------------------------------------------------------------- #include #include #include using namespace std; #include // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include #include "X3dParser.h" #include "X3dParserXerces.h" #include "Mesh.h" #include "SceneGraph.h" #include "Triangle3.h" #include "ViewCellsManager.h" // --------------------------------------------------------------------------- // Local data // // doNamespaces // Indicates whether namespace processing should be enabled or not. // The default is no, but -n overrides that. // // doSchema // Indicates whether schema processing should be enabled or not. // The default is no, but -s overrides that. // // schemaFullChecking // Indicates whether full schema constraint checking should be enabled or not. // The default is no, but -s overrides that. // // valScheme // Indicates what validation scheme to use. It defaults to 'auto', but // can be set via the -v= command. // --------------------------------------------------------------------------- static bool doNamespaces = false; static bool doSchema = false; static bool schemaFullChecking = false; static SAXParser::ValSchemes valScheme = SAXParser::Val_Auto; // --------------------------------------------------------------------------- // StdInParseHandlers: Constructors and Destructor // --------------------------------------------------------------------------- X3dParseHandlers::X3dParseHandlers(SceneGraphNode *root) : mElementCount(0) , mAttrCount(0) , mCharacterCount(0) , mSpaceCount(0) { mCurrentNode = root; } X3dParseHandlers::~X3dParseHandlers() { } // --------------------------------------------------------------------------- // StdInParseHandlers: Implementation of the SAX DocumentHandler interface // --------------------------------------------------------------------------- void X3dParseHandlers::endElement(const XMLCh* const name) { StrX lname(name); string element(lname.LocalForm()); if (element == "Shape") EndShape(); } void X3dParseHandlers::EndShape() { if (mCurrentMesh->mFaces.size()) { mCurrentMesh->Preprocess(); // make an instance of this mesh MeshInstance *mi = new MeshInstance(mCurrentMesh); mCurrentNode->mGeometry.push_back(mi); } else { cout<<"X"; delete mCurrentMesh; } mCurrentMesh = NULL; } void X3dParseHandlers::StartIndexedFaceSet( AttributeList& attributes) { int len = attributes.getLength(); int i; VertexIndexContainer vertices; for (i=0; i < len; i++) { string attrName(StrX(attributes.getName(i)).LocalForm()); if (attrName == "coordIndex") { StrX attrValue(attributes.getValue(i)); // handle coordIndex vertices.clear(); const char *ptr = attrValue.LocalForm(); char *endptr; while(1) { int index = strtol(ptr, &endptr, 10); if (ptr == endptr || index == -1) { if (vertices.size() > 2) { Face *face = new Face(vertices); mCurrentMesh->mFaces.push_back(face); } vertices.clear(); if (ptr == endptr) break; } else { vertices.push_back(index); } ptr = endptr; } } } } void X3dParseHandlers::StartMaterial( AttributeList& attributes) { int len = attributes.getLength(); int i; if (!mCurrentMesh->mMaterial) mCurrentMesh->mMaterial = new Material; for (i=0; i < len; i++) { string attrName(StrX(attributes.getName(i)).LocalForm()); StrX attrValue(attributes.getValue(i)); const char *ptr = attrValue.LocalForm(); if (attrName == "diffuseColor") { float r, g, b; if (sscanf(ptr, "%f %f %f", &r, &g, &b) == 3) mCurrentMesh->mMaterial->mDiffuseColor = RgbColor(r, g, b); } } } void X3dParseHandlers::StartCoordinate( AttributeList& attributes) { int len = attributes.getLength(); int i; VertexContainer vertices; for (i=0; i < len; i++) { string attrName(StrX(attributes.getName(i)).LocalForm()); if (attrName == "point") { StrX attrValue(attributes.getValue(i)); const char *ptr = attrValue.LocalForm(); char *endptr; while(1) { float x = strtod(ptr, &endptr); if (ptr == endptr) break; ptr = endptr; float y = strtod(ptr, &endptr); if (ptr == endptr) break; ptr = endptr; float z = strtod(ptr, &endptr); if (ptr == endptr) break; ptr = endptr; if (*ptr == ',') ptr++; Vector3 v(x, y, z); vertices.push_back(v); } mCurrentMesh->mVertices = vertices; } } } void X3dParseHandlers::startElement(const XMLCh* const name, AttributeList& attributes) { StrX lname(name); string element(lname.LocalForm()); if (element == "IndexedFaceSet") { // create a new mesh node in the scene graph StartIndexedFaceSet(attributes); } if (element == "Shape") { cout<<"+"; mCurrentMesh = new Mesh; } if (element == "Coordinate") { if (mCurrentMesh) StartCoordinate(attributes); } if (element == "Material") { StartMaterial(attributes); } mElementCount++; mAttrCount += attributes.getLength(); } void X3dParseHandlers::characters(const XMLCh* const chars, const unsigned int length) { mCharacterCount += length; } void X3dParseHandlers::ignorableWhitespace(const XMLCh* const chars, const unsigned int length) { mSpaceCount += length; } void X3dParseHandlers::resetDocument() { mAttrCount = 0; mCharacterCount = 0; mElementCount = 0; mSpaceCount = 0; } // --------------------------------------------------------------------------- // StdInParseHandlers: Overrides of the SAX ErrorHandler interface // --------------------------------------------------------------------------- void X3dParseHandlers::error(const SAXParseException& e) { XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; } void X3dParseHandlers::fatalError(const SAXParseException& e) { XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; } void X3dParseHandlers::warning(const SAXParseException& e) { XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; } bool X3dParser::ParseFile(const string filename, SceneGraphNode **root) { // Initialize the XML4C system try { XMLPlatformUtils::Initialize(); } catch (const XMLException& toCatch) { XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n" << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl; return false; } // // Create a SAX parser object. Then, according to what we were told on // the command line, set the options. // SAXParser* parser = new SAXParser; parser->setValidationScheme(valScheme); parser->setDoNamespaces(doNamespaces); parser->setDoSchema(doSchema); parser->setValidationSchemaFullChecking(schemaFullChecking); // // Create our SAX handler object and install it on the parser, as the // document and error handler. We are responsible for cleaning them // up, but since its just stack based here, there's nothing special // to do. // *root = new SceneGraphNode; X3dParseHandlers handler(*root); parser->setDocumentHandler(&handler); parser->setErrorHandler(&handler); unsigned long duration; int errorCount = 0; // create a faux scope so that 'src' destructor is called before // XMLPlatformUtils::Terminate { // // Kick off the parse and catch any exceptions. Create a standard // input input source and tell the parser to parse from that. // // StdInInputSource src; try { const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis(); parser->parse(filename.c_str()); const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis(); duration = endMillis - startMillis; errorCount = parser->getErrorCount(); } catch (const OutOfMemoryException&) { XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl; errorCount = 2; return false; } catch (const XMLException& e) { XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n" << StrX(e.getMessage()) << "\n" << XERCES_STD_QUALIFIER endl; errorCount = 1; return false; } // Print out the stats that we collected and time taken if (!errorCount) { XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms (" << handler.GetElementCount() << " elems, " << handler.GetAttrCount() << " attrs, " << handler.GetSpaceCount() << " spaces, " << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl; } } // // Delete the parser itself. Must be done prior to calling Terminate, below. // delete parser; XMLPlatformUtils::Terminate(); if (errorCount > 0) return false; else return true; } /*********************************************************** * class X3dViewCellsParseHandlers implemenation * ***********************************************************/ // --------------------------------------------------------------------------- // StdInParseHandlers: Constructors and Destructor // --------------------------------------------------------------------------- X3dViewCellsParseHandlers::X3dViewCellsParseHandlers(ViewCellsManager *viewCellsManager, float viewCellHeight) : mElementCount(0) , mAttrCount(0) , mCharacterCount(0) , mSpaceCount(0) , mViewCellsManager(viewCellsManager) , mViewCellHeight(viewCellHeight) { } X3dViewCellsParseHandlers::~X3dViewCellsParseHandlers() { } // --------------------------------------------------------------------------- // StdInParseHandlers: Implementation of the SAX DocumentHandler interface // --------------------------------------------------------------------------- void X3dViewCellsParseHandlers::endElement(const XMLCh* const name) { StrX lname(name); string element(lname.LocalForm()); if (element == "Shape") EndShape(); } void X3dViewCellsParseHandlers::EndShape() { } void X3dViewCellsParseHandlers::StartIndexedFaceSet( AttributeList& attributes) { int len = attributes.getLength(); int i; // clear previous vertex indices mCurrentVertexIndices.clear(); for (i=0; i < len; i++) { string attrName(StrX(attributes.getName(i)).LocalForm()); if (attrName == "coordIndex") { StrX attrValue(attributes.getValue(i)); // handle coordIndex const char *ptr = attrValue.LocalForm(); char *endptr; while (1) { int index = strtol(ptr, &endptr, 10); if (ptr == endptr) break; if (index != -1) { mCurrentVertexIndices.push_back(index); } ptr = endptr; } } } } void X3dViewCellsParseHandlers::StartCoordinate(AttributeList& attributes) { int len = attributes.getLength(); VertexContainer vertices; int i; for (i=0; i < len; i++) { string attrName(StrX(attributes.getName(i)).LocalForm()); if (attrName == "point") { StrX attrValue(attributes.getValue(i)); const char *ptr = attrValue.LocalForm(); char *endptr; while (1) { float x = strtod(ptr, &endptr); if (ptr == endptr) break; ptr = endptr; float y = (float)strtod(ptr, &endptr); if (ptr == endptr) break; ptr = endptr; float z = (float)strtod(ptr, &endptr); if (ptr == endptr) break; ptr = endptr; if (*ptr == ',') ptr++; Vector3 v(x, y, z); vertices.push_back(v); } } } for (i = 0; i < mCurrentVertexIndices.size(); i += 3) { Triangle3 baseTri(vertices[mCurrentVertexIndices[i + 0]], vertices[mCurrentVertexIndices[i + 1]], vertices[mCurrentVertexIndices[i + 2]]); // create view cell from base triangle mViewCellsManager->AddViewCell(mViewCellsManager->ExtrudeViewCell(baseTri, mViewCellHeight)); } } void X3dViewCellsParseHandlers::startElement(const XMLCh* const name, AttributeList& attributes) { StrX lname(name); string element(lname.LocalForm()); if (element == "IndexedFaceSet") { // create the viewcells from individual triangles StartIndexedFaceSet(attributes); } // do nothing //if (element == "Shape") {} if (element == "Coordinate") { // add coordinates to the triangles StartCoordinate(attributes); } // ignore material //if (element == "Material") {} mElementCount++; mAttrCount += attributes.getLength(); } void X3dViewCellsParseHandlers::characters(const XMLCh* const chars, const unsigned int length) { mCharacterCount += length; } void X3dViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars, const unsigned int length) { mSpaceCount += length; } void X3dViewCellsParseHandlers::resetDocument() { mAttrCount = 0; mCharacterCount = 0; mElementCount = 0; mSpaceCount = 0; } // --------------------------------------------------------------------------- // StdInParseHandlers: Overrides of the SAX ErrorHandler interface // --------------------------------------------------------------------------- void X3dViewCellsParseHandlers::error(const SAXParseException& e) { XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; } void X3dViewCellsParseHandlers::fatalError(const SAXParseException& e) { XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; } void X3dViewCellsParseHandlers::warning(const SAXParseException& e) { XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; } bool X3dParser::ParseFile(const string filename, ViewCellsManager &viewCells) { // Initialize the XML4C system try { XMLPlatformUtils::Initialize(); } catch (const XMLException& toCatch) { XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n" << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl; return false; } // // Create a SAX parser object. Then, according to what we were told on // the command line, set the options. // SAXParser* parser = new SAXParser; parser->setValidationScheme(valScheme); parser->setDoNamespaces(doNamespaces); parser->setDoSchema(doSchema); parser->setValidationSchemaFullChecking(schemaFullChecking); // // Create our SAX handler object and install it on the parser, as the // document and error handler. We are responsible for cleaning them // up, but since its just stack based here, there's nothing special // to do. // X3dViewCellsParseHandlers handler(&viewCells, mViewCellHeight); parser->setDocumentHandler(&handler); parser->setErrorHandler(&handler); unsigned long duration; int errorCount = 0; // create a faux scope so that 'src' destructor is called before // XMLPlatformUtils::Terminate { // // Kick off the parse and catch any exceptions. Create a standard // input input source and tell the parser to parse from that. // // StdInInputSource src; try { const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis(); parser->parse(filename.c_str()); const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis(); duration = endMillis - startMillis; errorCount = parser->getErrorCount(); } catch (const OutOfMemoryException&) { XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl; errorCount = 2; return false; } catch (const XMLException& e) { XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n" << StrX(e.getMessage()) << "\n" << XERCES_STD_QUALIFIER endl; errorCount = 1; return false; } // Print out the stats that we collected and time taken if (!errorCount) { XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms (" << handler.GetElementCount() << " elems, " << handler.GetAttrCount() << " attrs, " << handler.GetSpaceCount() << " spaces, " << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl; } } // // Delete the parser itself. Must be done prior to calling Terminate, below. // delete parser; XMLPlatformUtils::Terminate(); if (errorCount > 0) return false; else return true; }