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

Revision 881, 17.9 KB checked in by mattausch, 18 years ago (diff)

changing concept of active view cells

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