source: GTP/trunk/Lib/Vis/Preprocessing/src/X3dParser.cpp @ 657

Revision 657, 19.1 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

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 "X3dParser.h"
25
26#include "X3dParserXerces.h"
27#include "Mesh.h"
28#include "SceneGraph.h"
29#include "Triangle3.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// ---------------------------------------------------------------------------
63X3dParseHandlers::X3dParseHandlers(SceneGraphNode *root, const bool loadPolygonsAsMeshes):
64  mElementCount(0)
65  , mAttrCount(0)
66  , mCharacterCount(0)
67  , mSpaceCount(0)
68  , mLoadPolygonsAsMeshes(loadPolygonsAsMeshes)
69{
70  mCurrentNode = root;
71}
72
73X3dParseHandlers::~X3dParseHandlers()
74{
75}
76
77
78// ---------------------------------------------------------------------------
79//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
80// ---------------------------------------------------------------------------
81void X3dParseHandlers::endElement(const XMLCh* const name)
82{
83  StrX lname(name);
84  string element(lname.LocalForm());
85  if (element == "Shape")
86    EndShape();
87}
88
89void
90X3dParseHandlers::EndShape()
91{
92  if (mCurrentMesh->mFaces.size()) {
93    mCurrentMesh->Preprocess();
94    // make an instance of this mesh
95    MeshInstance *mi = new MeshInstance(mCurrentMesh);
96    mCurrentNode->mGeometry.push_back(mi);
97        // set the object id to a unique value
98        //mi->SetId(mCurrentObjectId ++);
99  } else {
100    cout<<"X";
101    delete mCurrentMesh;
102  }
103  mCurrentMesh = NULL;
104}
105
106void
107X3dParseHandlers::StartIndexedFaceSet(
108                                                                          AttributeList&  attributes)
109{
110  int len = attributes.getLength();
111  int i;
112  VertexIndexContainer vertices;
113 
114  for (i=0; i < len; i++) {
115    string attrName(StrX(attributes.getName(i)).LocalForm());
116    if (attrName == "coordIndex") {
117      StrX attrValue(attributes.getValue(i));
118      // handle coordIndex
119      vertices.clear();
120      const char *ptr = attrValue.LocalForm();
121      char *endptr;
122      while(1) {
123        int index = strtol(ptr, &endptr, 10);
124        if (ptr == endptr || index == -1) {
125          if (vertices.size() > 2) {
126                  Face *face = new Face(vertices);
127
128                   mCurrentMesh->mFaces.push_back(face);
129
130                   // every polygon is a mesh => store in mesh instance and create new mesh
131                  if (mLoadPolygonsAsMeshes)
132                  {
133                          mCurrentMesh->Preprocess();
134
135                          // make an instance of this mesh
136                          MeshInstance *mi = new MeshInstance(mCurrentMesh);
137                          mCurrentNode->mGeometry.push_back(mi);
138
139                          mCurrentMesh = new Mesh();
140                  }
141
142          }
143          vertices.clear();
144          if (ptr == endptr)
145            break;
146        } else {
147          vertices.push_back(index);
148        }
149        ptr = endptr;
150          }
151    }
152  }
153}
154
155void
156X3dParseHandlers::StartMaterial(
157                                AttributeList&  attributes)
158{
159  int len = attributes.getLength();
160  int i;
161  if (!mCurrentMesh->mMaterial)
162    mCurrentMesh->mMaterial = new Material;
163  for (i=0; i < len; i++) {
164    string attrName(StrX(attributes.getName(i)).LocalForm());
165    StrX attrValue(attributes.getValue(i));
166    const char *ptr = attrValue.LocalForm();
167    if (attrName == "diffuseColor") {
168      float r, g, b;
169      if (sscanf(ptr, "%f %f %f", &r, &g, &b) == 3)
170        mCurrentMesh->mMaterial->mDiffuseColor = RgbColor(r, g, b);
171    }
172  }
173}
174
175void
176X3dParseHandlers::StartCoordinate(
177                                  AttributeList&  attributes)
178{
179        int len = attributes.getLength();
180       
181        int i;
182        VertexContainer vertices;
183       
184        for (i=0; i < len; i++)
185        {
186                string attrName(StrX(attributes.getName(i)).LocalForm());
187         
188                if (attrName == "point")
189                {
190                        StrX attrValue(attributes.getValue(i));
191                 
192
193                        const char *ptr = attrValue.LocalForm();
194                        char *endptr;
195
196
197                        while(1)
198                        {
199                                float x = (float)strtod(ptr, &endptr);
200               
201                                if (ptr == endptr)
202                                  break;
203                         
204                                ptr = endptr;
205                               
206                                float y = (float)strtod(ptr, &endptr);
207                         
208                                if (ptr == endptr)
209                                        break;
210
211                                ptr = endptr;
212                         
213                                float z = (float)strtod(ptr, &endptr);
214                                if (ptr == endptr)
215                                        break;
216                         
217                                ptr = endptr;
218                         
219                                if (*ptr == ',')
220                                        ptr ++;
221
222                                Vector3 v(x, y, z);
223                                vertices.push_back(v);
224                        }
225                        mCurrentMesh->mVertices = vertices;
226                }
227        }
228}
229
230
231void
232X3dParseHandlers::startElement(const XMLCh* const name,
233                                                           AttributeList&  attributes)
234{
235  StrX lname(name);
236  string element(lname.LocalForm());
237 
238  if (element == "IndexedFaceSet") {
239    // create a new mesh node in the scene graph
240    StartIndexedFaceSet(attributes);
241  }
242
243  if (element == "Shape") {
244    cout<<"+";
245    mCurrentMesh = new Mesh;
246  }
247 
248  if (element == "Coordinate") {
249    if (mCurrentMesh)
250      StartCoordinate(attributes);
251  }
252 
253  if (element == "Material") {
254    StartMaterial(attributes);
255  }
256
257  mElementCount++;
258  mAttrCount += attributes.getLength();
259}
260
261void
262X3dParseHandlers::characters(const XMLCh* const chars,
263                             const unsigned int length)
264{
265  mCharacterCount += length;
266}
267
268void
269X3dParseHandlers::ignorableWhitespace(const XMLCh* const chars,
270                                      const unsigned int length)
271{
272  mSpaceCount += length;
273}
274
275void
276X3dParseHandlers::resetDocument()
277{
278  mAttrCount = 0;
279  mCharacterCount = 0;
280  mElementCount = 0;
281  mSpaceCount = 0;
282}
283
284
285
286// ---------------------------------------------------------------------------
287//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
288// ---------------------------------------------------------------------------
289void
290X3dParseHandlers::error(const SAXParseException& e)
291{
292  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
293                            << ", line " << e.getLineNumber()
294                            << ", char " << e.getColumnNumber()
295                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
296}
297
298void
299X3dParseHandlers::fatalError(const SAXParseException& e)
300{
301  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
302                            << ", line " << e.getLineNumber()
303                            << ", char " << e.getColumnNumber()
304                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
305}
306
307void
308X3dParseHandlers::warning(const SAXParseException& e)
309{
310  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
311                            << ", line " << e.getLineNumber()
312                            << ", char " << e.getColumnNumber()
313                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
314}
315
316
317bool
318X3dParser::ParseFile(const string filename,
319                                         SceneGraphNode **root,
320                                         const bool loadPolygonsAsMeshes)
321{
322  // Initialize the XML4C system
323  try {
324    XMLPlatformUtils::Initialize();
325  }
326 
327  catch (const XMLException& toCatch)
328    {
329      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
330                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
331      return false;
332    }
333 
334 
335  //
336  //  Create a SAX parser object. Then, according to what we were told on
337  //  the command line, set the options.
338  //
339  SAXParser* parser = new SAXParser;
340  parser->setValidationScheme(valScheme);
341  parser->setDoNamespaces(doNamespaces);
342  parser->setDoSchema(doSchema);
343  parser->setValidationSchemaFullChecking(schemaFullChecking);
344 
345
346  //
347  //  Create our SAX handler object and install it on the parser, as the
348  //  document and error handler. We are responsible for cleaning them
349  //  up, but since its just stack based here, there's nothing special
350  //  to do.
351  //
352  *root = new SceneGraphNode;
353  X3dParseHandlers handler(*root, loadPolygonsAsMeshes);
354  parser->setDocumentHandler(&handler);
355  parser->setErrorHandler(&handler);
356 
357  unsigned long duration;
358  int errorCount = 0;
359  // create a faux scope so that 'src' destructor is called before
360  // XMLPlatformUtils::Terminate
361  {
362    //
363    //  Kick off the parse and catch any exceptions. Create a standard
364    //  input input source and tell the parser to parse from that.
365    //
366    //    StdInInputSource src;
367    try
368      {
369        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
370        parser->parse(filename.c_str());
371        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
372        duration = endMillis - startMillis;
373        errorCount = parser->getErrorCount();
374      }
375    catch (const OutOfMemoryException&)
376      {
377        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
378        errorCount = 2;
379        return false;
380      }
381    catch (const XMLException& e)
382      {
383        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
384                                  << StrX(e.getMessage())
385                                  << "\n" << XERCES_STD_QUALIFIER endl;
386        errorCount = 1;
387        return false;
388      }
389
390   
391    // Print out the stats that we collected and time taken
392    if (!errorCount) {
393      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
394                                << handler.GetElementCount() << " elems, "
395                                << handler.GetAttrCount() << " attrs, "
396                                << handler.GetSpaceCount() << " spaces, "
397                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
398    }
399  }
400 
401  //
402  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
403  //
404  delete parser;
405 
406  XMLPlatformUtils::Terminate();
407 
408  if (errorCount > 0)
409    return false;
410  else
411    return true;
412}
413
414
415
416/************************************************************************/
417/*             class X3dViewCellsParseHandlers implementation           */
418/************************************************************************/
419
420
421// ---------------------------------------------------------------------------
422//  StdInParseHandlers: Constructors and Destructor
423// ---------------------------------------------------------------------------
424X3dViewCellsParseHandlers::X3dViewCellsParseHandlers(ViewCellsManager *viewCellsManager,
425                                                                                                         const float viewCellHeight):
426mElementCount(0),
427mAttrCount(0),
428mCharacterCount(0),
429mSpaceCount(0),
430mViewCellsManager(viewCellsManager),
431mViewCellHeight(viewCellHeight)
432{
433}
434
435X3dViewCellsParseHandlers::~X3dViewCellsParseHandlers()
436{
437}
438
439
440// ---------------------------------------------------------------------------
441//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
442// ---------------------------------------------------------------------------
443void X3dViewCellsParseHandlers::endElement(const XMLCh* const name)
444{
445  StrX lname(name);
446  string element(lname.LocalForm());
447  if (element == "Shape")
448    EndShape();
449}
450
451void
452X3dViewCellsParseHandlers::EndShape()
453{
454}
455
456void
457X3dViewCellsParseHandlers::StartIndexedFaceSet(
458                                      AttributeList&  attributes)
459{
460        int len = attributes.getLength();
461        int i;
462        // clear previous vertex indices
463        mCurrentVertexIndices.clear();
464        for (i=0; i < len; i++)
465        {
466                string attrName(StrX(attributes.getName(i)).LocalForm());
467           
468                if (attrName == "coordIndex")
469                {
470                        StrX attrValue(attributes.getValue(i));
471                       
472                        // handle coordIndex
473                        const char *ptr = attrValue.LocalForm();
474                        char *endptr;
475               
476                        while (1)
477                        {
478                                int index = strtol(ptr, &endptr, 10);
479                               
480                                if (ptr == endptr)
481                                        break;
482
483                                if (index != -1)
484                                {
485                                        mCurrentVertexIndices.push_back(index);
486                                }
487                   
488                                ptr = endptr;
489                        }
490                }
491        }
492}
493
494
495void
496X3dViewCellsParseHandlers::StartCoordinate(AttributeList&  attributes)
497{
498        int len = attributes.getLength();
499       
500        VertexContainer vertices;
501        int i;
502        for (i=0; i < len; i++)
503        {
504                string attrName(StrX(attributes.getName(i)).LocalForm());
505               
506                if (attrName == "point")
507                {
508                        StrX attrValue(attributes.getValue(i));
509                       
510                        const char *ptr = attrValue.LocalForm();
511                       
512                        char *endptr;
513                       
514                        while (1)
515                        {
516                                float x = (float)strtod(ptr, &endptr);
517               
518                                if (ptr == endptr)
519                                        break;
520                                ptr = endptr;
521                               
522                                float y = (float)(float)strtod(ptr, &endptr);
523
524                               
525                                if (ptr == endptr)
526                                        break;
527                                ptr = endptr;
528
529                                float z = (float)(float)strtod(ptr, &endptr);
530
531                                if (ptr == endptr)
532                                        break;
533
534                                ptr = endptr;
535                                if (*ptr == ',')
536                                        ptr++;
537
538                                Vector3 v(x, y, z);
539                                vertices.push_back(v);                         
540                        }
541                }
542        }
543
544        for (i = 0; i < mCurrentVertexIndices.size(); i += 3)
545        {
546                Triangle3 baseTri(vertices[mCurrentVertexIndices[i + 0]],
547                                                  vertices[mCurrentVertexIndices[i + 1]],
548                                                  vertices[mCurrentVertexIndices[i + 2]]);
549
550                // create view cell from base triangle
551                mViewCellsManager->AddViewCell(
552                        mViewCellsManager->ExtrudeViewCell(baseTri,
553                        mViewCellHeight));
554        }
555}
556
557
558void
559X3dViewCellsParseHandlers::startElement(const XMLCh* const name,
560                                                                                AttributeList&  attributes)
561{
562  StrX lname(name);
563  string element(lname.LocalForm());
564 
565  if (element == "IndexedFaceSet") {
566    // create the viewcells from individual triangles
567    StartIndexedFaceSet(attributes);
568  }
569       
570  if (element == "Coordinate") {
571          // add coordinates to the triangles
572      StartCoordinate(attributes);
573  }
574  // do nothing
575  //if (element == "Shape") {}
576  // ignore material
577  //if (element == "Material") {}
578
579  ++ mElementCount;
580  mAttrCount += attributes.getLength();
581}
582
583void
584X3dViewCellsParseHandlers::characters(const XMLCh* const chars,
585                             const unsigned int length)
586{
587  mCharacterCount += length;
588}
589
590void
591X3dViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
592                                      const unsigned int length)
593{
594  mSpaceCount += length;
595}
596
597void
598X3dViewCellsParseHandlers::resetDocument()
599{
600  mAttrCount = 0;
601  mCharacterCount = 0;
602  mElementCount = 0;
603  mSpaceCount = 0;
604}
605
606
607
608// ---------------------------------------------------------------------------
609//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
610// ---------------------------------------------------------------------------
611void
612X3dViewCellsParseHandlers::error(const SAXParseException& e)
613{
614  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
615                            << ", line " << e.getLineNumber()
616                            << ", char " << e.getColumnNumber()
617                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
618}
619
620void
621X3dViewCellsParseHandlers::fatalError(const SAXParseException& e)
622{
623  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
624                            << ", line " << e.getLineNumber()
625                            << ", char " << e.getColumnNumber()
626                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
627}
628
629void
630X3dViewCellsParseHandlers::warning(const SAXParseException& e)
631{
632  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
633                            << ", line " << e.getLineNumber()
634                            << ", char " << e.getColumnNumber()
635                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
636}
637
638
639bool
640X3dParser::ParseFile(const string filename, ViewCellsManager &viewCells)
641{
642  // Initialize the XML4C system
643  try {
644    XMLPlatformUtils::Initialize();
645  }
646 
647  catch (const XMLException& toCatch)
648    {
649      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
650                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
651      return false;
652    }
653 
654 
655  //
656  //  Create a SAX parser object. Then, according to what we were told on
657  //  the command line, set the options.
658  //
659  SAXParser* parser = new SAXParser;
660  parser->setValidationScheme(valScheme);
661  parser->setDoNamespaces(doNamespaces);
662  parser->setDoSchema(doSchema);
663  parser->setValidationSchemaFullChecking(schemaFullChecking);
664 
665
666  //
667  //  Create our SAX handler object and install it on the parser, as the
668  //  document and error handler. We are responsible for cleaning them
669  //  up, but since its just stack based here, there's nothing special
670  //  to do.
671  //
672  X3dViewCellsParseHandlers handler(&viewCells, mViewCellHeight);
673  parser->setDocumentHandler(&handler);
674  parser->setErrorHandler(&handler);
675 
676  unsigned long duration;
677  int errorCount = 0;
678  // create a faux scope so that 'src' destructor is called before
679  // XMLPlatformUtils::Terminate
680  {
681    //
682    //  Kick off the parse and catch any exceptions. Create a standard
683    //  input input source and tell the parser to parse from that.
684    //
685    //    StdInInputSource src;
686    try
687      {
688        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
689        parser->parse(filename.c_str());
690        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
691        duration = endMillis - startMillis;
692        errorCount = parser->getErrorCount();
693      }
694    catch (const OutOfMemoryException&)
695      {
696        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
697        errorCount = 2;
698        return false;
699      }
700    catch (const XMLException& e)
701      {
702        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
703                                  << StrX(e.getMessage())
704                                  << "\n" << XERCES_STD_QUALIFIER endl;
705        errorCount = 1;
706        return false;
707      }
708
709   
710    // Print out the stats that we collected and time taken
711    if (!errorCount) {
712      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
713                                << handler.GetElementCount() << " elems, "
714                                << handler.GetAttrCount() << " attrs, "
715                                << handler.GetSpaceCount() << " spaces, "
716                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
717    }
718  }
719 
720  //
721  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
722  //
723  delete parser;
724 
725  XMLPlatformUtils::Terminate();
726 
727  if (errorCount > 0)
728    return false;
729  else
730    return true;
731}
Note: See TracBrowser for help on using the repository browser.