// --------------------------------------------------------------------------- // Includes for all the program files to see // --------------------------------------------------------------------------- #include #include #include #include // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include #include "ObjectsParser.h" #include "ObjectsParserXerces.h" #include "Mesh.h" #include "ViewCellsManager.h" #include "GzFileInputSource.h" #include "BvHierarchy.h" using namespace std; namespace GtpVisibilityPreprocessor { // --------------------------------------------------------------------------- // 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; inline static bool ilt(Intersectable *obj1, Intersectable *obj2) { return obj1->mId < obj2->mId; } // --------------------------------------------------------------------------- // StdInParseHandlers: Constructors and Destructor // --------------------------------------------------------------------------- ObjectsParseHandlers::ObjectsParseHandlers(ObjectContainer &pvsObjects, const ObjectContainer &preprocessorObjects ): mElementCount(0) , mAttrCount(0) , mCharacterCount(0) , mSpaceCount(0) , mPvsObjects(pvsObjects) , mPreprocessorObjects(preprocessorObjects) , mIsObjectSpaceHierarchy(false) { } ObjectsParseHandlers::~ObjectsParseHandlers() { } // --------------------------------------------------------------------------- // StdInParseHandlers: Implementation of the SAX DocumentHandler interface // --------------------------------------------------------------------------- void ObjectsParseHandlers::endElement(const XMLCh* const name) { StrX lname(name); string element(lname.LocalForm()); if (element == "ObjectSpaceHierarchy") { EndObjectSpaceHierarchy(); } } void ObjectsParseHandlers::EndObjectSpaceHierarchy() { mIsObjectSpaceHierarchy = false; } inline static bool vlt(ViewCell *v1, ViewCell *v2) { return v1->mId < v2->mId; } void ObjectsParseHandlers::StartBvhElement(string element, AttributeList& attributes) { if (element == "Leaf") { StartBvhLeaf(attributes); } } void ObjectsParseHandlers::StartObjectSpaceHierarchyElement(const std::string &element, AttributeList& attributes) { //-- use cell type according to the chosen method StartBvhElement(element, attributes); } void ObjectsParseHandlers::startElement(const XMLCh* const name, AttributeList& attributes) { StrX lname(name); string element(lname.LocalForm()); // decides about the view cell hierarchy if (element == "ObjectSpaceHierarchy") { cout << "\nparsing object space hierarchy" << endl; Debug << "\nparsing object space hierarchy" << endl; mIsObjectSpaceHierarchy = true; } // parse view space hierarchy if (mIsObjectSpaceHierarchy) { StartObjectSpaceHierarchyElement(element, attributes); } ++ mElementCount; mAttrCount += attributes.getLength(); } void ObjectsParseHandlers::characters(const XMLCh* const chars, const unsigned int length) { mCharacterCount += length; } void ObjectsParseHandlers::ignorableWhitespace(const XMLCh* const chars, const unsigned int length) { mSpaceCount += length; } void ObjectsParseHandlers::resetDocument() { mAttrCount = 0; mCharacterCount = 0; mElementCount = 0; mSpaceCount = 0; } void ObjectsParseHandlers::StartBvhLeaf(AttributeList& attributes) { const int len = attributes.getLength(); Vector3 minBox, maxBox; ObjectContainer objects; for (int i = 0; i < len; ++ i) { string attrName(StrX(attributes.getName(i)).LocalForm()); StrX attrValue(attributes.getValue(i)); const char *ptr = attrValue.LocalForm(); if (attrName == "min") { sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z); } if (attrName == "max") { sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z); } if (attrName == "objects") { StartBvhLeafObjects(objects, ptr); } } AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox); BvhLeaf *leaf = new BvhLeaf(box, NULL, (int)objects.size()); leaf->mObjects = objects; BvHierarchy::AssociateObjectsWithLeaf(leaf); // new pvs object mPvsObjects.push_back(leaf); } void ObjectsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects, const char *ptr) { vector objIndices; char *endptr; while (1) { const int index = strtol(ptr, &endptr, 10); if (ptr == endptr) break; objIndices.push_back(index); ptr = endptr; } MeshInstance dummyInst(NULL); vector::const_iterator it, it_end = objIndices.end(); for (it = objIndices.begin(); it != it_end; ++ it) { const int objId = *it; #if 0 // assume there is is no id missing objects.push_back(mPreprocessorObjects[objId]); #else dummyInst.SetId(objId); ObjectContainer::const_iterator oit = lower_bound(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), (Intersectable *)&dummyInst, ilt); if ((oit != mPreprocessorObjects.end()) && ((*oit)->GetId() == objId)) { objects.push_back(*oit); } #endif } } // --------------------------------------------------------------------------- // StdInParseHandlers: Overrides of the SAX ErrorHandler interface // --------------------------------------------------------------------------- void ObjectsParseHandlers::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 ObjectsParseHandlers::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 ObjectsParseHandlers::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 ObjectsParser::ParseObjects(const string &filename, ObjectContainer &pvsObjects, const ObjectContainer &preprocessorObjects) { // 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; } // cout<<"parsing started"<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. // ObjectsParseHandlers handler(pvsObjects, preprocessorObjects); 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(); #if USE_GZLIB XMLCh *myFilePath = XMLString::transcode(filename.c_str()); GzFileInputSource isource(myFilePath); parser->parse(isource); #else parser->parse(filename.c_str()); #endif 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 cerr << filename << ": " << duration << " ms (" << handler.GetElementCount() << " elems, " << handler.GetAttrCount() << " attrs, " << handler.GetSpaceCount() << " spaces, " << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl; } } cout << "parsed - will delete the parser" << endl << flush; // // Delete the parser itself. Must be done prior to calling Terminate, below. // delete parser; XMLPlatformUtils::Terminate(); //-- assign new view cells manager //*viewCells = handler.mViewCellsManager; if (errorCount > 0) return false; else return true; } }