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

Revision 658, 19.7 KB checked in by mattausch, 19 years ago (diff)

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