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

Revision 694, 20.2 KB checked in by mattausch, 19 years ago (diff)

added means for rotating scene

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