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

Revision 556, 12.4 KB checked in by bittner, 18 years ago (diff)

debug version looking for glrenderer bug...

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(VspBspTree *tree,
64                                                                                           ViewCellsManager *viewCells,
65                                                                                           ObjectContainer *objects):
66  mElementCount(0)
67  , mAttrCount(0)
68  , mCharacterCount(0)
69  , mSpaceCount(0)
70{
71        mVspBspTree = tree;
72        mCurrentNode = tree->GetRoot();
73        mViewCellsManager = viewCells;
74        mObjects = objects;
75}
76
77ViewCellsParseHandlers::~ViewCellsParseHandlers()
78{
79}
80
81
82// ---------------------------------------------------------------------------
83//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
84// ---------------------------------------------------------------------------
85
86
87void ViewCellsParseHandlers::endElement(const XMLCh* const name)
88{
89  StrX lname(name);
90  string element(lname.LocalForm());
91  if (element == "Interior")
92          EndInterior();
93  if (element == "ViewCells")
94          EndViewCells();
95}
96
97
98void ViewCellsParseHandlers::EndInterior()
99{
100        // go one up in the tree
101        if (mCurrentNode->GetParent())
102        {       cout << "]";
103                mCurrentNode = mCurrentNode->GetParent();
104        }
105}
106
107
108inline bool vlt(ViewCell *v1, ViewCell *v2)
109{
110        return v1->mId < v2->mId;
111}
112
113
114void ViewCellsParseHandlers::EndViewCells()
115{
116        // sort view cells for easily finding id
117        stable_sort(mViewCells.begin(), mViewCells.end(), vlt);
118}
119
120
121void ViewCellsParseHandlers::startElement(const XMLCh* const name,
122                                                                                  AttributeList& attributes)
123{
124        StrX lname(name);
125        string element(lname.LocalForm());
126       
127        if (element == "ViewCell")
128        {
129                cout << "v";
130                StartViewCell(attributes);
131        }
132
133        if (element == "Interior")
134        {
135                cout << "[";
136                StartInterior(attributes);
137        }
138
139        if (element == "Leaf")
140        {
141                StartLeaf(attributes);
142        }
143
144        ++ mElementCount;
145        mAttrCount += attributes.getLength();
146}
147
148
149inline bool ilt(Intersectable *obj1, Intersectable *obj2)
150{
151        return obj1->mId < obj2->mId;
152}
153
154
155void ViewCellsParseHandlers::StartViewCell(AttributeList&  attributes)
156{
157        int len = attributes.getLength();
158        vector<int> objIndices;
159 
160        ViewCell *viewCell = mViewCellsManager->GenerateViewCell();
161        mViewCells.push_back(viewCell);
162
163        for (int i = 0; i < len; ++ i)
164        {
165                string attrName(StrX(attributes.getName(i)).LocalForm());
166               
167                if (attrName == "pvs")
168                {
169                        StrX attrValue(attributes.getValue(i));
170                       
171                        // handle coordIndex
172                        objIndices.clear();
173                        const char *ptr = attrValue.LocalForm();
174                        char *endptr;
175                       
176                        while (1)
177                        {
178                                int index = strtol(ptr, &endptr, 10);
179
180                                if (ptr == endptr)
181                                        break;
182
183                                objIndices.push_back(index);
184
185                                ptr = endptr;
186                        }
187
188                        //TODO: find objects and add them to pvs
189                        // TODO: get view cell with specified id
190                        MeshInstance dummyInst(NULL);
191
192                        vector<int>::const_iterator it, it_end = objIndices.end();
193                        for (it = objIndices.begin(); it != it_end; ++ it)
194                        {
195                                const int objId = *it; 
196                                dummyInst.SetId(objId);
197
198                                ObjectContainer::iterator oit =
199                                  lower_bound(mObjects->begin(), mObjects->end(), &dummyInst, ilt);
200                               
201                                Intersectable *obj = *oit;
202                               
203                                if (obj->GetId() == objId)
204                                {
205                                  // $$JB we should store a float a per object which corresponds
206                                  // to sumof pdfs, i.e. its relative visibility
207                                  // temporarily set to 1.0f
208                                        viewCell->GetPvs().AddSample(obj, 1.0f);
209                                }
210                                else
211                                {
212                                        Debug << "error: object does not exist" << endl;
213                                }
214                        }
215                }
216                else if (attrName == "id")
217                {
218                        StrX attrValue(attributes.getValue(i));
219                       
220                        const char *ptr = attrValue.LocalForm();
221                        char *endptr = NULL;
222                        const int id = strtol(ptr, &endptr, 10);
223
224                        viewCell->SetId(id);
225                }
226        }
227}
228
229
230void ViewCellsParseHandlers::StartLeaf(AttributeList& attributes)
231{
232        BspLeaf * leaf =
233                new BspLeaf(dynamic_cast<BspInterior *>(mCurrentNode), NULL);
234
235        if (mCurrentNode) // replace front or (if not NULL) back child
236        {
237                dynamic_cast<BspInterior *>(mCurrentNode)->ReplaceChildLink(NULL, leaf);
238        }
239        else
240        {
241                mVspBspTree->mRoot = leaf;
242        }
243
244        //-- find associated view cell
245        int viewCellId;
246       
247        int len = attributes.getLength();
248         
249        for (int i = 0; i < len; ++ i)
250        {
251                string attrName(StrX(attributes.getName(i)).LocalForm());
252                StrX attrValue(attributes.getValue(i));
253
254                const char *ptr = attrValue.LocalForm();
255                char *endptr = NULL;
256
257                if (attrName == "viewCellId")
258                {
259                        viewCellId = strtol(ptr, &endptr, 10);
260                }
261        }
262
263        if (viewCellId >= 0) // valid view cell
264        {
265                // TODO: get view cell with specified id
266                ViewCell dummyVc;
267                dummyVc.SetId(viewCellId);
268
269                ViewCellContainer::iterator vit =
270                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
271                       
272                BspViewCell *viewCell = dynamic_cast<BspViewCell *>(*vit);
273                if (viewCell->GetId() == viewCellId)
274                {
275                        leaf->SetViewCell(viewCell);
276                }
277                else
278                {
279                        Debug << "error: view cell does not exist" << endl;
280                }
281        }
282        else
283        {
284                leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
285                leaf->SetTreeValid(false);
286                mVspBspTree->PropagateUpValidity(leaf);
287        }
288}
289
290
291void ViewCellsParseHandlers::StartInterior(AttributeList& attributes)
292{
293        Plane3 plane;
294        int len = attributes.getLength();
295
296        for (int i = 0; i < len; ++ i)
297        {
298                string attrName(StrX(attributes.getName(i)).LocalForm());
299                StrX attrValue(attributes.getValue(i));
300                const char *ptr = attrValue.LocalForm();
301
302                if (attrName == "plane")
303                {
304                        sscanf(ptr, "%f %f %f %f",
305                                   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
306                }
307        }
308
309        BspInterior* interior = new BspInterior(plane);
310       
311        if (mCurrentNode) // replace NULL child of parent with current node
312        {
313                BspInterior *current = dynamic_cast<BspInterior *>(mCurrentNode);
314
315                current->ReplaceChildLink(NULL, interior);
316                interior->SetParent(current);
317        }
318        else
319        {
320                mVspBspTree->mRoot = interior;
321        }
322
323        mCurrentNode = interior;
324}
325
326
327void ViewCellsParseHandlers::characters(const XMLCh* const chars,
328                                                                                const unsigned int length)
329{
330        mCharacterCount += length;
331}
332
333
334void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
335                                                                                                 const unsigned int length)
336{
337        mSpaceCount += length;
338}
339
340
341void ViewCellsParseHandlers::resetDocument()
342{
343        mAttrCount = 0;
344        mCharacterCount = 0;
345        mElementCount = 0;
346        mSpaceCount = 0;
347}
348
349
350// ---------------------------------------------------------------------------
351//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
352// ---------------------------------------------------------------------------
353void
354ViewCellsParseHandlers::error(const SAXParseException& e)
355{
356  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
357                            << ", line " << e.getLineNumber()
358                            << ", char " << e.getColumnNumber()
359                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
360}
361
362void
363ViewCellsParseHandlers::fatalError(const SAXParseException& e)
364{
365  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
366                            << ", line " << e.getLineNumber()
367                            << ", char " << e.getColumnNumber()
368                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
369}
370
371void
372ViewCellsParseHandlers::warning(const SAXParseException& e)
373{
374  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
375                            << ", line " << e.getLineNumber()
376                            << ", char " << e.getColumnNumber()
377                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
378}
379
380
381bool ViewCellsParser::ParseFile(const string filename,
382                                                                VspBspTree *tree,
383                                                                ViewCellsManager *viewCells,
384                                                                ObjectContainer *objects)
385{
386  // Initialize the XML4C system
387  try {
388    XMLPlatformUtils::Initialize();
389  }
390 
391  catch (const XMLException& toCatch)
392    {
393      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
394                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
395      return false;
396    }
397 
398 
399  //
400  //  Create a SAX parser object. Then, according to what we were told on
401  //  the command line, set the options.
402  //
403  SAXParser* parser = new SAXParser;
404  parser->setValidationScheme(valScheme);
405  parser->setDoNamespaces(doNamespaces);
406  parser->setDoSchema(doSchema);
407  parser->setValidationSchemaFullChecking(schemaFullChecking);
408 
409
410  //
411  //  Create our SAX handler object and install it on the parser, as the
412  //  document and error handler. We are responsible for cleaning them
413  //  up, but since its just stack based here, there's nothing special
414  //  to do.
415  //
416  ViewCellsParseHandlers handler(tree, viewCells, objects);
417  parser->setDocumentHandler(&handler);
418  parser->setErrorHandler(&handler);
419 
420  unsigned long duration;
421  int errorCount = 0;
422  // create a faux scope so that 'src' destructor is called before
423  // XMLPlatformUtils::Terminate
424  {
425    //
426    //  Kick off the parse and catch any exceptions. Create a standard
427    //  input input source and tell the parser to parse from that.
428    //
429    //    StdInInputSource src;
430    try
431      {
432        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
433        parser->parse(filename.c_str());
434        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
435        duration = endMillis - startMillis;
436        errorCount = parser->getErrorCount();
437      }
438    catch (const OutOfMemoryException&)
439      {
440        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
441        errorCount = 2;
442        return false;
443      }
444    catch (const XMLException& e)
445      {
446        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
447                                  << StrX(e.getMessage())
448                                  << "\n" << XERCES_STD_QUALIFIER endl;
449        errorCount = 1;
450        return false;
451      }
452
453   
454    // Print out the stats that we collected and time taken
455    if (!errorCount) {
456      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
457                                << handler.GetElementCount() << " elems, "
458                                << handler.GetAttrCount() << " attrs, "
459                                << handler.GetSpaceCount() << " spaces, "
460                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
461    }
462  }
463 
464  //
465  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
466  //
467  delete parser;
468 
469  XMLPlatformUtils::Terminate();
470 
471  if (errorCount > 0)
472    return false;
473  else
474    return true;
475}
Note: See TracBrowser for help on using the repository browser.