source: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsParser.cpp @ 577

Revision 577, 15.3 KB checked in by mattausch, 18 years ago (diff)

fixed loading function: the view cell manager is chosen depending on
the type in the file. the view space box is saved with the file

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