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

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

adding function for testing purpose

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