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

Revision 508, 12.2 KB checked in by mattausch, 19 years ago (diff)

implemented view cells exporting / loading
improved vsp bsp tree (only axis aligbed until a level), reuse results from Plane
testing, collectmergeneighbors
implemented view cell meshes

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                                        viewCell->GetPvs().AddSample(obj);
206                                }
207                                else
208                                {
209                                        Debug << "error: object does not exist" << endl;
210                                }
211                        }
212                }
213                else if (attrName == "id")
214                {
215                        StrX attrValue(attributes.getValue(i));
216                       
217                        const char *ptr = attrValue.LocalForm();
218                        char *endptr = NULL;
219                        const int id = strtol(ptr, &endptr, 10);
220
221                        viewCell->SetId(id);
222                }
223        }
224}
225
226
227void ViewCellsParseHandlers::StartLeaf(AttributeList& attributes)
228{
229        BspLeaf * leaf =
230                new BspLeaf(dynamic_cast<BspInterior *>(mCurrentNode), NULL);
231
232        if (mCurrentNode) // replace front or (if not NULL) back child
233        {
234                dynamic_cast<BspInterior *>(mCurrentNode)->ReplaceChildLink(NULL, leaf);
235        }
236        else
237        {
238                mVspBspTree->mRoot = leaf;
239        }
240
241        //-- find associated view cell
242        int viewCellId;
243       
244        int len = attributes.getLength();
245         
246        for (int i = 0; i < len; ++ i)
247        {
248                string attrName(StrX(attributes.getName(i)).LocalForm());
249                StrX attrValue(attributes.getValue(i));
250
251                const char *ptr = attrValue.LocalForm();
252                char *endptr = NULL;
253
254                if (attrName == "viewCellId")
255                {
256                        viewCellId = strtol(ptr, &endptr, 10);
257                }
258        }
259
260        if (viewCellId >= 0) // valid view cell
261        {
262                // TODO: get view cell with specified id
263                ViewCell dummyVc;
264                dummyVc.SetId(viewCellId);
265
266                ViewCellContainer::iterator vit =
267                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
268                       
269                BspViewCell *viewCell = dynamic_cast<BspViewCell *>(*vit);
270                if (viewCell->GetId() == viewCellId)
271                {
272                        leaf->SetViewCell(viewCell);
273                }
274                else
275                {
276                        Debug << "error: view cell does not exist" << endl;
277                }
278        }
279        else
280        {
281                leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
282                leaf->SetTreeValid(false);
283                mVspBspTree->PropagateUpValidity(leaf);
284        }
285}
286
287
288void ViewCellsParseHandlers::StartInterior(AttributeList& attributes)
289{
290        Plane3 plane;
291        int len = attributes.getLength();
292
293        for (int i = 0; i < len; ++ i)
294        {
295                string attrName(StrX(attributes.getName(i)).LocalForm());
296                StrX attrValue(attributes.getValue(i));
297                const char *ptr = attrValue.LocalForm();
298
299                if (attrName == "plane")
300                {
301                        sscanf(ptr, "%f %f %f %f",
302                                   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
303                }
304        }
305
306        BspInterior* interior = new BspInterior(plane);
307       
308        if (mCurrentNode) // replace NULL child of parent with current node
309        {
310                BspInterior *current = dynamic_cast<BspInterior *>(mCurrentNode);
311
312                current->ReplaceChildLink(NULL, interior);
313                interior->SetParent(current);
314        }
315        else
316        {
317                mVspBspTree->mRoot = interior;
318        }
319
320        mCurrentNode = interior;
321}
322
323
324void ViewCellsParseHandlers::characters(const XMLCh* const chars,
325                                                                                const unsigned int length)
326{
327        mCharacterCount += length;
328}
329
330
331void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
332                                                                                                 const unsigned int length)
333{
334        mSpaceCount += length;
335}
336
337
338void ViewCellsParseHandlers::resetDocument()
339{
340        mAttrCount = 0;
341        mCharacterCount = 0;
342        mElementCount = 0;
343        mSpaceCount = 0;
344}
345
346
347// ---------------------------------------------------------------------------
348//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
349// ---------------------------------------------------------------------------
350void
351ViewCellsParseHandlers::error(const SAXParseException& e)
352{
353  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
354                            << ", line " << e.getLineNumber()
355                            << ", char " << e.getColumnNumber()
356                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
357}
358
359void
360ViewCellsParseHandlers::fatalError(const SAXParseException& e)
361{
362  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
363                            << ", line " << e.getLineNumber()
364                            << ", char " << e.getColumnNumber()
365                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
366}
367
368void
369ViewCellsParseHandlers::warning(const SAXParseException& e)
370{
371  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
372                            << ", line " << e.getLineNumber()
373                            << ", char " << e.getColumnNumber()
374                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
375}
376
377
378bool ViewCellsParser::ParseFile(const string filename,
379                                                                VspBspTree *tree,
380                                                                ViewCellsManager *viewCells,
381                                                                ObjectContainer *objects)
382{
383  // Initialize the XML4C system
384  try {
385    XMLPlatformUtils::Initialize();
386  }
387 
388  catch (const XMLException& toCatch)
389    {
390      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
391                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
392      return false;
393    }
394 
395 
396  //
397  //  Create a SAX parser object. Then, according to what we were told on
398  //  the command line, set the options.
399  //
400  SAXParser* parser = new SAXParser;
401  parser->setValidationScheme(valScheme);
402  parser->setDoNamespaces(doNamespaces);
403  parser->setDoSchema(doSchema);
404  parser->setValidationSchemaFullChecking(schemaFullChecking);
405 
406
407  //
408  //  Create our SAX handler object and install it on the parser, as the
409  //  document and error handler. We are responsible for cleaning them
410  //  up, but since its just stack based here, there's nothing special
411  //  to do.
412  //
413  ViewCellsParseHandlers handler(tree, viewCells, objects);
414  parser->setDocumentHandler(&handler);
415  parser->setErrorHandler(&handler);
416 
417  unsigned long duration;
418  int errorCount = 0;
419  // create a faux scope so that 'src' destructor is called before
420  // XMLPlatformUtils::Terminate
421  {
422    //
423    //  Kick off the parse and catch any exceptions. Create a standard
424    //  input input source and tell the parser to parse from that.
425    //
426    //    StdInInputSource src;
427    try
428      {
429        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
430        parser->parse(filename.c_str());
431        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
432        duration = endMillis - startMillis;
433        errorCount = parser->getErrorCount();
434      }
435    catch (const OutOfMemoryException&)
436      {
437        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
438        errorCount = 2;
439        return false;
440      }
441    catch (const XMLException& e)
442      {
443        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
444                                  << StrX(e.getMessage())
445                                  << "\n" << XERCES_STD_QUALIFIER endl;
446        errorCount = 1;
447        return false;
448      }
449
450   
451    // Print out the stats that we collected and time taken
452    if (!errorCount) {
453      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
454                                << handler.GetElementCount() << " elems, "
455                                << handler.GetAttrCount() << " attrs, "
456                                << handler.GetSpaceCount() << " spaces, "
457                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
458    }
459  }
460 
461  //
462  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
463  //
464  delete parser;
465 
466  XMLPlatformUtils::Terminate();
467 
468  if (errorCount > 0)
469    return false;
470  else
471    return true;
472}
Note: See TracBrowser for help on using the repository browser.