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

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

added switch for loading polys as meshes

RevLine 
[170]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>
[162]9
[170]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
[162]24#include "X3dParser.h"
25
[182]26#include "X3dParserXerces.h"
[170]27#include "Mesh.h"
28#include "SceneGraph.h"
[261]29#include "Triangle3.h"
[439]30#include "ViewCellsManager.h"
[162]31
[170]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// ---------------------------------------------------------------------------
[657]63X3dParseHandlers::X3dParseHandlers(SceneGraphNode *root, const bool loadPolygonsAsMeshes):
[176]64  mElementCount(0)
65  , mAttrCount(0)
66  , mCharacterCount(0)
67  , mSpaceCount(0)
[657]68  , mLoadPolygonsAsMeshes(loadPolygonsAsMeshes)
[162]69{
[176]70  mCurrentNode = root;
[162]71}
72
[170]73X3dParseHandlers::~X3dParseHandlers()
74{
75}
[162]76
[170]77
78// ---------------------------------------------------------------------------
79//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
80// ---------------------------------------------------------------------------
81void X3dParseHandlers::endElement(const XMLCh* const name)
[162]82{
[170]83  StrX lname(name);
[176]84  string element(lname.LocalForm());
[170]85  if (element == "Shape")
86    EndShape();
87}
[162]88
[170]89void
90X3dParseHandlers::EndShape()
91{
[658]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        }
[170]139}
140void
141X3dParseHandlers::StartIndexedFaceSet(
[439]142                                                                          AttributeList&  attributes)
[170]143{
144  int len = attributes.getLength();
145  int i;
146  VertexIndexContainer vertices;
[162]147 
[170]148  for (i=0; i < len; i++) {
[176]149    string attrName(StrX(attributes.getName(i)).LocalForm());
[170]150    if (attrName == "coordIndex") {
151      StrX attrValue(attributes.getValue(i));
152      // handle coordIndex
153      vertices.clear();
[176]154      const char *ptr = attrValue.LocalForm();
[170]155      char *endptr;
156      while(1) {
157        int index = strtol(ptr, &endptr, 10);
158        if (ptr == endptr || index == -1) {
159          if (vertices.size() > 2) {
[657]160                  Face *face = new Face(vertices);
161
[658]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          }
[657]172
[170]173          vertices.clear();
174          if (ptr == endptr)
175            break;
176        } else {
177          vertices.push_back(index);
178        }
179        ptr = endptr;
[508]180          }
[170]181    }
[162]182  }
183}
184
[170]185void
186X3dParseHandlers::StartMaterial(
187                                AttributeList&  attributes)
[162]188{
[170]189  int len = attributes.getLength();
190  int i;
[176]191  if (!mCurrentMesh->mMaterial)
192    mCurrentMesh->mMaterial = new Material;
[170]193  for (i=0; i < len; i++) {
[176]194    string attrName(StrX(attributes.getName(i)).LocalForm());
[170]195    StrX attrValue(attributes.getValue(i));
[176]196    const char *ptr = attrValue.LocalForm();
[170]197    if (attrName == "diffuseColor") {
198      float r, g, b;
199      if (sscanf(ptr, "%f %f %f", &r, &g, &b) == 3)
[176]200        mCurrentMesh->mMaterial->mDiffuseColor = RgbColor(r, g, b);
[170]201    }
202  }
[162]203}
204
[170]205void
206X3dParseHandlers::StartCoordinate(
207                                  AttributeList&  attributes)
[162]208{
[657]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                        }
[658]255                        if (mLoadPolygonsAsMeshes)
256                        {
257                                mCurrentVertices = vertices;
258                        }
259                        else
260                        {
261                                mCurrentMesh->mVertices = vertices;
262                        }
[657]263                }
264        }
[162]265}
266
[170]267
268void
269X3dParseHandlers::startElement(const XMLCh* const name,
[439]270                                                           AttributeList&  attributes)
[162]271{
[170]272  StrX lname(name);
[176]273  string element(lname.LocalForm());
[170]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<<"+";
[658]282        mCurrentMesh = new Mesh;
[170]283  }
284 
285  if (element == "Coordinate") {
[176]286    if (mCurrentMesh)
[170]287      StartCoordinate(attributes);
288  }
289 
290  if (element == "Material") {
291    StartMaterial(attributes);
292  }
293
[176]294  mElementCount++;
295  mAttrCount += attributes.getLength();
[162]296}
297
[170]298void
299X3dParseHandlers::characters(const XMLCh* const chars,
300                             const unsigned int length)
[162]301{
[176]302  mCharacterCount += length;
[162]303}
304
[170]305void
306X3dParseHandlers::ignorableWhitespace(const XMLCh* const chars,
307                                      const unsigned int length)
[162]308{
[176]309  mSpaceCount += length;
[162]310}
311
[170]312void
313X3dParseHandlers::resetDocument()
[162]314{
[176]315  mAttrCount = 0;
316  mCharacterCount = 0;
317  mElementCount = 0;
318  mSpaceCount = 0;
[162]319}
320
[170]321
322
323// ---------------------------------------------------------------------------
324//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
325// ---------------------------------------------------------------------------
326void
327X3dParseHandlers::error(const SAXParseException& e)
[162]328{
[170]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}
[162]334
[170]335void
336X3dParseHandlers::fatalError(const SAXParseException& e)
[162]337{
[170]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;
[162]342}
343
[170]344void
345X3dParseHandlers::warning(const SAXParseException& e)
[162]346{
[170]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;
[162]351}
352
[170]353
354bool
355X3dParser::ParseFile(const string filename,
[657]356                                         SceneGraphNode **root,
357                                         const bool loadPolygonsAsMeshes)
[170]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;
[657]390  X3dParseHandlers handler(*root, loadPolygonsAsMeshes);
[170]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      }
[176]426
[170]427   
428    // Print out the stats that we collected and time taken
429    if (!errorCount) {
430      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
[176]431                                << handler.GetElementCount() << " elems, "
432                                << handler.GetAttrCount() << " attrs, "
433                                << handler.GetSpaceCount() << " spaces, "
434                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
[170]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;
[162]449}
450
[170]451
[260]452
[508]453/************************************************************************/
454/*             class X3dViewCellsParseHandlers implementation           */
455/************************************************************************/
[260]456
457
458// ---------------------------------------------------------------------------
459//  StdInParseHandlers: Constructors and Destructor
460// ---------------------------------------------------------------------------
[439]461X3dViewCellsParseHandlers::X3dViewCellsParseHandlers(ViewCellsManager *viewCellsManager,
[657]462                                                                                                         const float viewCellHeight):
[490]463mElementCount(0),
464mAttrCount(0),
465mCharacterCount(0),
466mSpaceCount(0),
467mViewCellsManager(viewCellsManager),
468mViewCellHeight(viewCellHeight)
[260]469{
470}
471
[261]472X3dViewCellsParseHandlers::~X3dViewCellsParseHandlers()
[260]473{
474}
475
476
477// ---------------------------------------------------------------------------
478//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
479// ---------------------------------------------------------------------------
[261]480void X3dViewCellsParseHandlers::endElement(const XMLCh* const name)
[260]481{
482  StrX lname(name);
483  string element(lname.LocalForm());
484  if (element == "Shape")
485    EndShape();
486}
487
488void
[261]489X3dViewCellsParseHandlers::EndShape()
[260]490{
491}
492
493void
[261]494X3dViewCellsParseHandlers::StartIndexedFaceSet(
[260]495                                      AttributeList&  attributes)
496{
497        int len = attributes.getLength();
498        int i;
[262]499        // clear previous vertex indices
500        mCurrentVertexIndices.clear();
[260]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               
[261]513                        while (1)
[260]514                        {
515                                int index = strtol(ptr, &endptr, 10);
516                               
[261]517                                if (ptr == endptr)
518                                        break;
519
520                                if (index != -1)
[260]521                                {
[261]522                                        mCurrentVertexIndices.push_back(index);
[260]523                                }
524                   
525                                ptr = endptr;
526                        }
527                }
528        }
529}
530
531
532void
[439]533X3dViewCellsParseHandlers::StartCoordinate(AttributeList&  attributes)
[260]534{
535        int len = attributes.getLength();
536       
537        VertexContainer vertices;
[364]538        int i;
539        for (i=0; i < len; i++)
[260]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                        {
[469]553                                float x = (float)strtod(ptr, &endptr);
[260]554               
555                                if (ptr == endptr)
556                                        break;
557                                ptr = endptr;
558                               
[469]559                                float y = (float)(float)strtod(ptr, &endptr);
[260]560
561                               
562                                if (ptr == endptr)
563                                        break;
564                                ptr = endptr;
565
[469]566                                float z = (float)(float)strtod(ptr, &endptr);
[260]567
568                                if (ptr == endptr)
569                                        break;
570
571                                ptr = endptr;
572                                if (*ptr == ',')
573                                        ptr++;
574
575                                Vector3 v(x, y, z);
[262]576                                vertices.push_back(v);                         
[260]577                        }
578                }
579        }
[261]580
[333]581        for (i = 0; i < mCurrentVertexIndices.size(); i += 3)
[439]582        {
[312]583                Triangle3 baseTri(vertices[mCurrentVertexIndices[i + 0]],
584                                                  vertices[mCurrentVertexIndices[i + 1]],
585                                                  vertices[mCurrentVertexIndices[i + 2]]);
[261]586
[262]587                // create view cell from base triangle
[490]588                mViewCellsManager->AddViewCell(
589                        mViewCellsManager->ExtrudeViewCell(baseTri,
590                        mViewCellHeight));
[439]591        }
[260]592}
593
594
595void
[261]596X3dViewCellsParseHandlers::startElement(const XMLCh* const name,
[439]597                                                                                AttributeList&  attributes)
[260]598{
599  StrX lname(name);
600  string element(lname.LocalForm());
601 
602  if (element == "IndexedFaceSet") {
[261]603    // create the viewcells from individual triangles
[260]604    StartIndexedFaceSet(attributes);
605  }
[261]606       
[260]607  if (element == "Coordinate") {
[261]608          // add coordinates to the triangles
[260]609      StartCoordinate(attributes);
610  }
[508]611  // do nothing
612  //if (element == "Shape") {}
[261]613  // ignore material
614  //if (element == "Material") {}
[260]615
[508]616  ++ mElementCount;
[260]617  mAttrCount += attributes.getLength();
618}
619
620void
[261]621X3dViewCellsParseHandlers::characters(const XMLCh* const chars,
[260]622                             const unsigned int length)
623{
624  mCharacterCount += length;
625}
626
627void
[261]628X3dViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
[260]629                                      const unsigned int length)
630{
631  mSpaceCount += length;
632}
633
634void
[261]635X3dViewCellsParseHandlers::resetDocument()
[260]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
[261]649X3dViewCellsParseHandlers::error(const SAXParseException& e)
[260]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
[261]658X3dViewCellsParseHandlers::fatalError(const SAXParseException& e)
[260]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
[261]667X3dViewCellsParseHandlers::warning(const SAXParseException& e)
[260]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
[439]677X3dParser::ParseFile(const string filename, ViewCellsManager &viewCells)
[260]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  //
[312]709  X3dViewCellsParseHandlers handler(&viewCells, mViewCellHeight);
[260]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;
[333]768}
Note: See TracBrowser for help on using the repository browser.