source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp @ 664

Revision 664, 17.7 KB checked in by mattausch, 18 years ago (diff)
RevLine 
[508]1// ---------------------------------------------------------------------------
2//  Includes for all the program files to see
3// ---------------------------------------------------------------------------
4#include <string.h>
5#include <stdlib.h>
6#include <iostream>
7using namespace std;
8#include <xercesc/util/PlatformUtils.hpp>
9
10// ---------------------------------------------------------------------------
11//  Includes
12// ---------------------------------------------------------------------------
13#include <xercesc/framework/StdInInputSource.hpp>
14#include <xercesc/parsers/SAXParser.hpp>
15#include <xercesc/util/OutOfMemoryException.hpp>
16
17// ---------------------------------------------------------------------------
18//  Includes
19// ---------------------------------------------------------------------------
20#include <xercesc/sax/AttributeList.hpp>
21#include <xercesc/sax/SAXParseException.hpp>
22#include <xercesc/sax/SAXException.hpp>
23
24#include "ViewCellsParser.h"
25
26#include "ViewCellsParserXerces.h"
27#include "Mesh.h"
28#include "VspBspTree.h"
29#include "ViewCellBsp.h"
[590]30#include "VspKdTree.h"
[508]31#include "ViewCellsManager.h"
32
33// ---------------------------------------------------------------------------
34//  Local data
35//
36//  doNamespaces
37//      Indicates whether namespace processing should be enabled or not.
38//      The default is no, but -n overrides that.
39//
40//  doSchema
41//      Indicates whether schema processing should be enabled or not.
42//      The default is no, but -s overrides that.
43//
44//  schemaFullChecking
45//      Indicates whether full schema constraint checking should be enabled or not.
46//      The default is no, but -s overrides that.
47//
48//  valScheme
49//      Indicates what validation scheme to use. It defaults to 'auto', but
50//      can be set via the -v= command.
51// ---------------------------------------------------------------------------
52static bool     doNamespaces       = false;
53static bool     doSchema           = false;
54static bool     schemaFullChecking = false;
55static SAXParser::ValSchemes    valScheme       = SAXParser::Val_Auto;
56
57
58
59
60
61// ---------------------------------------------------------------------------
62//  StdInParseHandlers: Constructors and Destructor
63// ---------------------------------------------------------------------------
[577]64ViewCellsParseHandlers::ViewCellsParseHandlers(ObjectContainer *objects):
[508]65  mElementCount(0)
66  , mAttrCount(0)
67  , mCharacterCount(0)
68  , mSpaceCount(0)
[577]69  , mViewCellsManager(NULL)
70  , mVspBspTree(NULL)
71  , mBspTree(NULL)
[651]72  , mViewCellsTree(NULL)
73  , mParseViewCells(true)
74  , mCurrentViewCell(NULL)
75  , mCurrentBspNode(NULL)
[508]76{
77        mObjects = objects;
78}
79
[575]80
[508]81ViewCellsParseHandlers::~ViewCellsParseHandlers()
82{
83}
84
85
86// ---------------------------------------------------------------------------
87//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
88// ---------------------------------------------------------------------------
89
90
91void ViewCellsParseHandlers::endElement(const XMLCh* const name)
92{
93  StrX lname(name);
94  string element(lname.LocalForm());
[651]95
[508]96  if (element == "ViewCells")
97          EndViewCells();
[651]98
99  if (mParseViewCells)
100  {
101          if (element == "Interior")
102                  EndViewCellInterior();
103  }
104  else
105  {
106        if (element == "Interior")
107                  EndBspInterior();
108  }
[508]109}
110
111
[575]112void ViewCellsParseHandlers::EndBspInterior()
[508]113{
114        // go one up in the tree
[590]115        if (mCurrentBspNode->GetParent())
[508]116        {       cout << "]";
[590]117                mCurrentBspNode = mCurrentBspNode->GetParent();
[508]118        }
119}
120
121
[651]122void ViewCellsParseHandlers::EndViewCellInterior()
123{
124        // go one up in the tree
125        if (mCurrentViewCell->GetParent())
126        {       cout << "]";
127                mCurrentViewCell = mCurrentViewCell->GetParent();
128        }
129}
130
[508]131inline bool vlt(ViewCell *v1, ViewCell *v2)
132{
133        return v1->mId < v2->mId;
134}
135
136
137void ViewCellsParseHandlers::EndViewCells()
138{
[575]139        // sort view cells to help associating view cells according to their id
[508]140        stable_sort(mViewCells.begin(), mViewCells.end(), vlt);
141}
142
143
[575]144
145void ViewCellsParseHandlers::StartHierarchy(AttributeList&  attributes)
[508]146{
[575]147        int len = attributes.getLength();
148 
149        for (int i = 0; i < len; ++ i)
150        {
151                string attrName(StrX(attributes.getName(i)).LocalForm());
152               
153                if (attrName == "name")
154                {
155                        StrX attrValue(attributes.getValue(i));
156                       
157                        const char *ptr = attrValue.LocalForm();
158                       
159                        CreateViewCellsManager(ptr);
160                }
161        }
162}
163
164
165void ViewCellsParseHandlers::startBspElement(string element,
166                                                                                         AttributeList& attributes)
167{
[508]168        if (element == "Interior")
169        {
170                cout << "[";
[575]171                StartBspInterior(attributes);
[508]172        }
173
174        if (element == "Leaf")
175        {
[651]176                cout << "l";
177                Debug << "leaf" << endl;
[575]178                StartBspLeaf(attributes);
[508]179        }
[575]180}
[508]181
[575]182
183void ViewCellsParseHandlers::startElement(const XMLCh* const name,
184                                                                                  AttributeList& attributes)
185{
186        StrX lname(name);
187        string element(lname.LocalForm());
[577]188
189        // decides the used view cell hierarchy
[651]190        if (element == "ViewCells")
191        {
192                cout << "parsing view cells" << endl;
193                mParseViewCells = true;
194        }
195
[575]196        if (element == "Hierarchy")
197        {
[651]198                cout << "parsing spatial hierarchy" << endl;
199                mParseViewCells = false;
[575]200                StartHierarchy(attributes);
201        }
[577]202       
203        // decides the used view cell hierarchy
204        if (element == "ViewSpaceBox")
205        {
[651]206                cout << "b";
[577]207                StartViewSpaceBox(attributes);
208        }
[575]209
[577]210
211        // use different methods for the given view cell hierarchy types
[651]212        if (!mParseViewCells)
[577]213        {
[651]214                if (mViewCellsManager)
[577]215                {
[651]216                        switch (mViewCellsManager->GetType())
217                        {
218                        case ViewCellsManager::BSP:
219                        case ViewCellsManager::VSP_BSP:
220                                startBspElement(element, attributes);
221                                break;
[575]222       
[651]223                        default:
224                                Debug << "not implemented" << endl;
225                                break;
226                        }
[577]227                }
228        }
[651]229        else
230        {
231                if (element == "Interior")
232                {
233                        cout << "[";
234                        StartViewCellInterior(attributes);
235                }
[575]236
[651]237                if (element == "Leaf")
238                {
239                        cout << "l";
240                        StartViewCellLeaf(attributes);
241                }
242        }
243
[508]244        ++ mElementCount;
245        mAttrCount += attributes.getLength();
246}
247
248
249inline bool ilt(Intersectable *obj1, Intersectable *obj2)
250{
251        return obj1->mId < obj2->mId;
252}
253
254
[651]255void ViewCellsParseHandlers::StartViewCell(ViewCell *viewCell, AttributeList&  attributes)
[508]256{
257        int len = attributes.getLength();
258        vector<int> objIndices;
[590]259
[508]260        for (int i = 0; i < len; ++ i)
261        {
262                string attrName(StrX(attributes.getName(i)).LocalForm());
263               
264                if (attrName == "pvs")
265                {
266                        StrX attrValue(attributes.getValue(i));
267                       
268                        // handle coordIndex
269                        objIndices.clear();
270                        const char *ptr = attrValue.LocalForm();
271                        char *endptr;
272                       
273                        while (1)
274                        {
275                                int index = strtol(ptr, &endptr, 10);
276
277                                if (ptr == endptr)
278                                        break;
279
280                                objIndices.push_back(index);
281
282                                ptr = endptr;
283                        }
284
285                        //TODO: find objects and add them to pvs
286                        // TODO: get view cell with specified id
287                        MeshInstance dummyInst(NULL);
288
289                        vector<int>::const_iterator it, it_end = objIndices.end();
290                        for (it = objIndices.begin(); it != it_end; ++ it)
291                        {
292                                const int objId = *it; 
293                                dummyInst.SetId(objId);
294
295                                ObjectContainer::iterator oit =
[556]296                                  lower_bound(mObjects->begin(), mObjects->end(), &dummyInst, ilt);
297                               
[508]298                                Intersectable *obj = *oit;
299                               
300                                if (obj->GetId() == objId)
301                                {
[556]302                                  // $$JB we should store a float a per object which corresponds
303                                  // to sumof pdfs, i.e. its relative visibility
304                                  // temporarily set to 1.0f
305                                        viewCell->GetPvs().AddSample(obj, 1.0f);
[508]306                                }
307                                else
308                                {
309                                        Debug << "error: object does not exist" << endl;
310                                }
311                        }
312                }
313                else if (attrName == "id")
314                {
315                        StrX attrValue(attributes.getValue(i));
316                       
317                        const char *ptr = attrValue.LocalForm();
318                        char *endptr = NULL;
319                        const int id = strtol(ptr, &endptr, 10);
320
321                        viewCell->SetId(id);
322                }
[651]323                else if (attrName == "active")
324                {
325                        StrX attrValue(attributes.getValue(i));
326                       
327                        const char *ptr = attrValue.LocalForm();
328                        char *endptr = NULL;
329                        const bool isActive = (bool)strtol(ptr, &endptr, 10);
330
[660]331                        if (isActive)
332                                viewCell->SetActive();
[651]333                }
334                else if (attrName == "mergecost")
335                {
336                        StrX attrValue(attributes.getValue(i));
337                       
338                        const char *ptr = attrValue.LocalForm();
339                        char *endptr = NULL;
340                        const float cost = (float)strtod(ptr, &endptr);
341
342                        viewCell->SetMergeCost(cost);
343                }
[508]344        }
345}
346
347
[577]348void ViewCellsParseHandlers::StartViewSpaceBox(AttributeList& attributes)
349{
350        int len = attributes.getLength();
351
352        Vector3 bmin, bmax;
353
354        for (int i = 0; i < len; ++ i)
355        {
356                string attrName(StrX(attributes.getName(i)).LocalForm());
357                StrX attrValue(attributes.getValue(i));
358                const char *ptr = attrValue.LocalForm();
359
360                if (attrName == "min")
361                {
362                        sscanf(ptr, "%f %f %f",
363                                   &bmin.x, &bmin.y, &bmin.z);
364                }
365                else if (attrName == "max")
366                {
367                        sscanf(ptr, "%f %f %f",
368                                   &bmax.x, &bmax.y, &bmax.z);
369                }
370        }
371
372        mViewSpaceBox = AxisAlignedBox3(bmin, bmax);
373
374        Debug << "view space box: " << mViewSpaceBox << endl;
375}
376
377
[575]378void ViewCellsParseHandlers::StartBspLeaf(AttributeList& attributes)
[508]379{
380        BspLeaf * leaf =
[590]381                new BspLeaf(dynamic_cast<BspInterior *>(mCurrentBspNode), NULL);
[508]382
[590]383        if (mCurrentBspNode) // replace front or (if not NULL) back child
[508]384        {
[590]385                dynamic_cast<BspInterior *>(mCurrentBspNode)->ReplaceChildLink(NULL, leaf);
[508]386        }
387        else
388        {
[575]389                if (mViewCellsManager->GetType() == ViewCellsManager::BSP)
[577]390                {
[575]391                        mBspTree->mRoot = leaf;
[577]392                }
393                else if (mViewCellsManager->GetType() == ViewCellsManager::VSP_BSP)
394                {
[575]395                        mVspBspTree->mRoot = leaf;
[577]396                }
[508]397        }
398
399        //-- find associated view cell
400        int viewCellId;
401       
402        int len = attributes.getLength();
403         
404        for (int i = 0; i < len; ++ i)
405        {
406                string attrName(StrX(attributes.getName(i)).LocalForm());
407                StrX attrValue(attributes.getValue(i));
408
409                const char *ptr = attrValue.LocalForm();
410                char *endptr = NULL;
411
412                if (attrName == "viewCellId")
413                {
414                        viewCellId = strtol(ptr, &endptr, 10);
415                }
416        }
[654]417
[590]418       
[508]419        if (viewCellId >= 0) // valid view cell
420        {
421                // TODO: get view cell with specified id
[590]422                ViewCellInterior dummyVc;
[508]423                dummyVc.SetId(viewCellId);
424
425                ViewCellContainer::iterator vit =
426                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
427                       
[651]428                BspViewCell *viewCell = dynamic_cast<BspViewCell *>(*vit);
[580]429
[654]430       
[508]431                if (viewCell->GetId() == viewCellId)
432                {
[651]433                        leaf->SetViewCell(viewCell);
434                        viewCell->mLeaf = leaf;
[508]435                }
436                else
437                {
438                        Debug << "error: view cell does not exist" << endl;
439                }
440        }
441        else
442        {
[575]443                if (mViewCellsManager->GetType() == ViewCellsManager::VSP_BSP)
444                {
445                        leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
446                        leaf->SetTreeValid(false);
447                        mVspBspTree->PropagateUpValidity(leaf);
448                }
[654]449        }
[508]450}
451
452
[575]453void ViewCellsParseHandlers::StartBspInterior(AttributeList& attributes)
[508]454{
455        Plane3 plane;
456        int len = attributes.getLength();
457
458        for (int i = 0; i < len; ++ i)
459        {
460                string attrName(StrX(attributes.getName(i)).LocalForm());
461                StrX attrValue(attributes.getValue(i));
462                const char *ptr = attrValue.LocalForm();
463
464                if (attrName == "plane")
465                {
466                        sscanf(ptr, "%f %f %f %f",
467                                   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
468                }
469        }
470
471        BspInterior* interior = new BspInterior(plane);
472       
[590]473        if (mCurrentBspNode) // replace NULL child of parent with current node
[508]474        {
[590]475                BspInterior *current = dynamic_cast<BspInterior *>(mCurrentBspNode);
[508]476
477                current->ReplaceChildLink(NULL, interior);
478                interior->SetParent(current);
479        }
480        else
481        {
[575]482                if (mViewCellsManager->GetType() == ViewCellsManager::BSP)
[577]483                {
[575]484                        mBspTree->mRoot = interior;
[577]485                }
[575]486                else
[577]487                {
[575]488                        mVspBspTree->mRoot = interior;
[577]489                }
[508]490        }
491
[590]492        mCurrentBspNode = interior;
[508]493}
494
495
[651]496void ViewCellsParseHandlers::StartViewCellLeaf(AttributeList& attributes)
497{
498        BspViewCell *viewCell = new BspViewCell();
[575]499
[651]500        if (mCurrentViewCell) // replace front or (if not NULL) back child
501        {
502                ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(mCurrentViewCell);
503                interior->SetupChildLink(viewCell);
504        }
505        else // root
506        {
507                mViewCellsTree->SetRoot(viewCell);
508        }
509
510        StartViewCell(viewCell, attributes);
511
512        // collect leaves
513        mViewCells.push_back(viewCell);
514}
515
516
517void ViewCellsParseHandlers::StartViewCellInterior(AttributeList& attributes)
518{
519        ViewCellInterior* interior = new ViewCellInterior();
520       
521        if (mCurrentViewCell) // replace NULL child of parent with current node
522        {
523                ViewCellInterior *current = dynamic_cast<ViewCellInterior *>(mCurrentViewCell);
524
525                current->SetupChildLink(interior);
526        }
527        else
528        {
529                mViewCellsTree->SetRoot(interior);
530        }
531
532        mCurrentViewCell = interior;
533
534        StartViewCell(interior, attributes);
535}
536
537
538
[575]539void ViewCellsParseHandlers::CreateViewCellsManager(const char *name)
540{
541        if (strcmp(name, "bspTree") == 0)
542        {
543                Debug << "view cell type: Bsp" << endl;
544
[577]545                mBspTree = new BspTree();
[590]546                mBspTree->mBox = mViewSpaceBox;
[651]547                //mCurrentBspNode = mBspTree->GetRoot();
[575]548
549                mViewCellsManager = new BspViewCellsManager(mBspTree);
550        }
551        else if (strcmp(name, "vspBspTree") == 0)
552        {
[577]553                Debug << "view cell type: VspBsp" << endl;
554
[575]555                mVspBspTree = new VspBspTree();
[651]556                //mCurrentBspNode = mVspBspTree->GetRoot();
[575]557
558                mViewCellsManager = new VspBspViewCellsManager(mVspBspTree);
[577]559
[590]560                mVspBspTree->mBox = mViewSpaceBox;
[577]561                Debug << "creating vsp bsp view cells manager" << endl;
[575]562        }
[590]563        else if (strcmp(name, "vspKdTree") == 0)
[575]564        {
[590]565                // TODO
566                mVspKdTree = new VspKdTree();   
567                mViewCellsManager = new VspKdViewCellsManager(mVspKdTree);
568        }
[575]569        else
570        {
[664]571                cerr<<"Wrong view cells type " << name << "!!!" << endl;
[575]572                exit(1);
573        }
[577]574
[651]575        mViewCellsTree = mViewCellsManager->GetViewCellsTree();
[577]576        mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
[575]577}
578
579
[508]580void ViewCellsParseHandlers::characters(const XMLCh* const chars,
581                                                                                const unsigned int length)
582{
583        mCharacterCount += length;
584}
585
586
587void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
588                                                                                                 const unsigned int length)
589{
590        mSpaceCount += length;
591}
592
593
594void ViewCellsParseHandlers::resetDocument()
595{
596        mAttrCount = 0;
597        mCharacterCount = 0;
598        mElementCount = 0;
599        mSpaceCount = 0;
600}
601
602
603// ---------------------------------------------------------------------------
604//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
605// ---------------------------------------------------------------------------
606void
607ViewCellsParseHandlers::error(const SAXParseException& e)
608{
609  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
610                            << ", line " << e.getLineNumber()
611                            << ", char " << e.getColumnNumber()
612                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
613}
614
615void
616ViewCellsParseHandlers::fatalError(const SAXParseException& e)
617{
618  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
619                            << ", line " << e.getLineNumber()
620                            << ", char " << e.getColumnNumber()
621                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
622}
623
624void
625ViewCellsParseHandlers::warning(const SAXParseException& e)
626{
627  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
628                            << ", line " << e.getLineNumber()
629                            << ", char " << e.getColumnNumber()
630                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
631}
632
633
634bool ViewCellsParser::ParseFile(const string filename,
[575]635                                                                ViewCellsManager **viewCells,
[508]636                                                                ObjectContainer *objects)
637{
638  // Initialize the XML4C system
639  try {
640    XMLPlatformUtils::Initialize();
641  }
642 
643  catch (const XMLException& toCatch)
644    {
645      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
646                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
647      return false;
648    }
649 
650 
651  //
652  //  Create a SAX parser object. Then, according to what we were told on
653  //  the command line, set the options.
654  //
655  SAXParser* parser = new SAXParser;
656  parser->setValidationScheme(valScheme);
657  parser->setDoNamespaces(doNamespaces);
658  parser->setDoSchema(doSchema);
659  parser->setValidationSchemaFullChecking(schemaFullChecking);
660 
661
662  //
663  //  Create our SAX handler object and install it on the parser, as the
664  //  document and error handler. We are responsible for cleaning them
665  //  up, but since its just stack based here, there's nothing special
666  //  to do.
667  //
[577]668  ViewCellsParseHandlers handler(objects);
[508]669  parser->setDocumentHandler(&handler);
670  parser->setErrorHandler(&handler);
671 
672  unsigned long duration;
673  int errorCount = 0;
674  // create a faux scope so that 'src' destructor is called before
675  // XMLPlatformUtils::Terminate
676  {
677    //
678    //  Kick off the parse and catch any exceptions. Create a standard
679    //  input input source and tell the parser to parse from that.
680    //
681    //    StdInInputSource src;
682    try
683      {
684        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
685        parser->parse(filename.c_str());
686        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
687        duration = endMillis - startMillis;
688        errorCount = parser->getErrorCount();
689      }
690    catch (const OutOfMemoryException&)
691      {
692        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
693        errorCount = 2;
694        return false;
695      }
696    catch (const XMLException& e)
697      {
698        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
699                                  << StrX(e.getMessage())
700                                  << "\n" << XERCES_STD_QUALIFIER endl;
701        errorCount = 1;
702        return false;
703      }
704
705   
706    // Print out the stats that we collected and time taken
707    if (!errorCount) {
708      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
709                                << handler.GetElementCount() << " elems, "
710                                << handler.GetAttrCount() << " attrs, "
711                                << handler.GetSpaceCount() << " spaces, "
712                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
713    }
714  }
715 
716  //
717  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
718  //
719  delete parser;
720 
721  XMLPlatformUtils::Terminate();
722 
[577]723   // assign new view cells manager
724  *viewCells = handler.mViewCellsManager;
[651]725 
[508]726  if (errorCount > 0)
727    return false;
728  else
729    return true;
[556]730}
Note: See TracBrowser for help on using the repository browser.