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

Revision 1002, 26.7 KB checked in by mattausch, 18 years ago (diff)

debug run: fixing memory holes

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#include <xercesc/util/BinFileInputStream.hpp>
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#include "ResourceManager.h"
32
33namespace GtpVisibilityPreprocessor {
34
35float X3dParser::DEFAULT_VIEWCELL_HEIGHT = 5.0f;
36
37// ---------------------------------------------------------------------------
38//  Local data
39//
40//  doNamespaces
41//      Indicates whether namespace processing should be enabled or not.
42//      The default is no, but -n overrides that.
43//
44//  doSchema
45//      Indicates whether schema processing should be enabled or not.
46//      The default is no, but -s overrides that.
47//
48//  schemaFullChecking
49//      Indicates whether full schema constraint checking should be enabled or not.
50//      The default is no, but -s overrides that.
51//
52//  valScheme
53//      Indicates what validation scheme to use. It defaults to 'auto', but
54//      can be set via the -v= command.
55// ---------------------------------------------------------------------------
56static bool     doNamespaces       = false;
57static bool     doSchema           = false;
58static bool     schemaFullChecking = false;
59static SAXParser::ValSchemes    valScheme       = SAXParser::Val_Auto;
60
61#define ROTATE_SCENE 0
62
63static int sUniqueMeshIdx = 0;
64
65// hack: rotate mesh by n degrees
66static void RotateMesh(Mesh *mesh, const float angle)
67{
68        VertexContainer::iterator it, it_end = mesh->mVertices.end();
69
70        const float angleRad = angle * PI / 180.0f;
71        const Matrix4x4 rot = RotationYMatrix(angleRad);
72
73        for (it = mesh->mVertices.begin(); it != it_end; ++ it)
74        {
75                (*it) = rot * (*it);       
76        }
77}
78
79// ---------------------------------------------------------------------------
80//  StdInParseHandlers: Constructors and Destructor
81// ---------------------------------------------------------------------------
82X3dParseHandlers::X3dParseHandlers(SceneGraphNode *root, const bool loadPolygonsAsMeshes):
83  mElementCount(0)
84  , mAttrCount(0)
85  , mCharacterCount(0)
86  , mSpaceCount(0)
87  , mLoadPolygonsAsMeshes(loadPolygonsAsMeshes)
88  , mCurrentMesh(NULL)
89{
90        mCurrentNode = root;
91
92        // this matrix should never be removed from stack
93        //mTransformations.push(IdentityMatrix());
94}
95
96X3dParseHandlers::~X3dParseHandlers()
97{
98        if (!mTransformations.empty())
99                cout << "error: transformation stack size: " << (int)mTransformations.size() << endl;
100}
101
102
103// ---------------------------------------------------------------------------
104//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
105// ---------------------------------------------------------------------------
106
107void X3dParseHandlers::endElement(const XMLCh* const name)
108{
109        StrX lname(name);
110        string element(lname.LocalForm());
111
112        // only create new mesh instance if define mechanism was not used
113        if (element == "Shape")
114                EndShape();
115
116        if (element == "Transform")
117                EndTransform();
118}
119
120
121void X3dParseHandlers::ApplyTransformations(TrafoStack trafos, Mesh *mesh) const
122{
123        while (!trafos.empty())
124        {
125                const Matrix4x4 m = trafos.top();
126                trafos.pop();
127
128                mesh->ApplyTransformation(m);
129        }
130}
131
132
133void X3dParseHandlers::ApplyTransformations(TrafoStack trafos,
134                                                                                        TransformedMeshInstance *mi) const
135{
136        while (!trafos.empty())
137        {
138                const Matrix4x4 m = trafos.top();
139                trafos.pop();
140
141                mi->ApplyWorldTransform(m);
142        }
143}
144
145
146void X3dParseHandlers::StartTransform(AttributeList&  attributes)
147{
148        Matrix4x4 currentTransform = IdentityMatrix();
149
150        const int len = attributes.getLength();
151
152    Matrix4x4 *rotm = NULL;
153        Matrix4x4 *scalem = NULL;
154        Matrix4x4 *translm = NULL;
155   
156        for (int i = 0; i < len; ++ i)
157        {
158                string attrName(StrX(attributes.getName(i)).LocalForm());
159                       
160                StrX attrValue(attributes.getValue(i));
161                const char *ptr = attrValue.LocalForm();
162                       
163                if (attrName == "rotation")
164                {
165                        Vector3 axis;
166                        float angle;
167                               
168                        if (sscanf(ptr, "%f %f %f %f", &axis.x, &axis.y, &axis.z, &angle) == 4)
169                        {
170                                rotm = new Matrix4x4(RotationAxisMatrix(axis, angle));
171                        }
172                }
173                else if (attrName == "translation")
174                {
175                        Vector3 transl;
176                                                       
177                        if (sscanf(ptr, "%f %f %f %f", &transl.x, &transl.y, &transl.z) == 3)
178                        {
179                                translm = new Matrix4x4(TranslationMatrix(transl));
180                        }
181                }
182                else if (attrName == "scale")
183                {
184                        Vector3 scale;
185
186                        if (sscanf(ptr, "%f %f %f %f", &scale.x, &scale.y, &scale.z) == 3)
187                        {
188                                scalem = new Matrix4x4(ScaleMatrix(scale.x, scale.y, scale.z));
189                        }
190                }
191                // todo: scale orientation
192        }
193       
194        if (scalem)
195                currentTransform *= (*scalem);
196        if (rotm)
197                currentTransform *= (*rotm);
198        if (translm)
199                currentTransform *= (*translm);
200
201        DEL_PTR(scalem);
202        DEL_PTR(rotm);
203        DEL_PTR(translm);
204
205        mTransformations.push(currentTransform);
206}
207
208
209void X3dParseHandlers::EndTransform()
210{
211        mTransformations.pop();
212}
213
214
215void X3dParseHandlers::EndShape()
216{
217         //-- if shape is merely a definition => don't create particular mesh instance
218         if (!mCurrentMesh || mIsMeshDefinition)
219         {
220                 return;
221         }
222
223         //-- each polygon is one single mesh
224         if (mLoadPolygonsAsMeshes)
225         {
226                 FaceContainer::const_iterator fit, fit_end = mCurrentMesh->mFaces.end();
227
228                 cout << "m";
229               
230                 for (fit = mCurrentMesh->mFaces.begin(); fit != fit_end; ++ fit)
231                 {
232                         cout << "f";
233
234                         Face *face = *fit;
235               
236                         // we create a new mesh for each face from the current mesh
237                         Mesh *mesh = MeshManager::GetSingleton()->CreateResource();
238                       
239                         VertexIndexContainer::const_iterator vit, vit_end = face->mVertexIndices.end();
240               
241                         int i = 0;
242                         VertexIndexContainer vcIndices;
243
244                         for (vit = face->mVertexIndices.begin(); vit != vit_end; ++ vit, ++ i)
245                         {
246                                 cout << "i";
247                                 const int index = (*vit);
248
249                                 // add vertices
250                                 mesh->mVertices.push_back(mCurrentMesh->mVertices[index]);
251
252                                 // indices don't make much sense if mesh = face, but
253                                 // we need them anyway ...
254                                 vcIndices.push_back(i);
255                         }
256
257                         mesh->mFaces.push_back(new Face(vcIndices));
258
259                         // NOTE: should rather be written into trafo of mesh instance
260                         ApplyTransformations(mTransformations, mesh);
261
262                         mesh->Preprocess();
263                               
264                         // make an instance of this mesh
265                         MeshInstance *mi = new MeshInstance(mesh);
266                         mCurrentNode->mGeometry.push_back(mi);
267                 }
268
269                 // this mesh is not needed, unless it is used as a definition
270                 if (!mUsingMeshDefinition)
271                         MeshManager::GetSingleton()->DestroyEntry(mCurrentMesh->GetId());
272        }
273        else // default usage: create a mesh instance from the current mesh
274        {
275                MeshInstance *mi;
276
277                if (!mUsingMeshDefinition)
278                {
279                        // make an instance of this mesh
280            mi = new MeshInstance(mCurrentMesh);
281
282                        // this mesh is used only once => write transformations directly into it
283                        ApplyTransformations(mTransformations, mCurrentMesh);
284                }
285                else
286                {
287                         // make an instance of this mesh
288                         TransformedMeshInstance *tmi = new TransformedMeshInstance(mCurrentMesh);
289
290                         // apply transformation on the instance of the mesh
291                         ApplyTransformations(mTransformations, tmi);
292
293                         mi = tmi;
294                }
295               
296                if (mCurrentMaterial)
297                {
298                        // HACK: add the material to the mesh directly if no material yet
299                        if (mCurrentMesh->mMaterial)
300                        {
301                                mCurrentMesh->mMaterial = mCurrentMaterial;
302                        }
303                        else // add material to the instance
304                        {
305                                mi->SetMaterial(mCurrentMaterial);
306                        }
307                }
308
309                // create local mesh kd tree
310                mCurrentMesh->Preprocess();
311                // add to scene graph
312                mCurrentNode->mGeometry.push_back(mi);
313       
314                // reset current mesh
315                mCurrentMesh = NULL;
316        }
317}
318
319
320void X3dParseHandlers::StartIndexedFaceSet(AttributeList&  attributes)
321{
322        //-- indexedfaceset corresponds  to Mesh in our implementation
323        const int len = attributes.getLength();
324
325        VertexIndexContainer vertices;
326 
327        mIsMeshDefinition = false;
328        mUsingMeshDefinition = false;
329
330        for (int i = 0; i < len; ++ i)
331        {
332                const string attrName(StrX(attributes.getName(i)).LocalForm());
333       
334                //-- we use an already defined mesh
335                if (attrName == "USE")
336                {
337                        StrX attrValue(attributes.getValue(i));
338                        const char *meshName = attrValue.LocalForm();
339
340                        mUsingMeshDefinition = true;
341
342            // retrieve mesh from mesh container
343                        const int meshIdx = mMeshDefinitions[meshName];
344
345                        mCurrentMesh =
346                                MeshManager::GetSingleton()->FindEntry(meshIdx);
347
348                        //Debug << "retrieving mesh definition: " << mCurrentMeshName << endl;
349                        cout << "u";
350                }
351                else if (attrName == "DEF") //-- a definition of a mesh
352                {
353                        const StrX attrValue(attributes.getValue(i));
354                        const char *meshName = attrValue.LocalForm();
355
356                        // this is only a definition, don't create actual  instance
357                        mIsMeshDefinition = true;
358                       
359                        //-- create new mesh definition
360                        mCurrentMesh = MeshManager::GetSingleton()->CreateResource();
361                       
362                        // store the mesh defination in a lookup table
363                        mMeshDefinitions[meshName] = mCurrentMesh->GetId();
364                        cout << "d";
365                }
366               
367                //-- read coordinate indices for current mesh
368                else if (attrName == "coordIndex")
369                {
370                        StrX attrValue(attributes.getValue(i));
371                        const char *ptr = attrValue.LocalForm();
372
373                        //-- immediate use: create a new mesh using a generic name
374                        if (!mCurrentMesh)
375                        {
376                                mCurrentMesh = MeshManager::GetSingleton()->CreateResource();
377                        }
378
379                        // handle coordIndex
380                        vertices.clear();
381                       
382                 
383                        char *endptr;
384         
385                        while (1)
386                        {
387                                int index = strtol(ptr, &endptr, 10);
388                                 
389                                if (ptr == endptr || index == -1)
390                                {
391                                        if (vertices.size() > 2)
392                                        {
393                                                Face *face = new Face(vertices);                 
394                                                mCurrentMesh->mFaces.push_back(face);
395                                        }
396                         
397                                        vertices.clear();
398                 
399                                        if (ptr == endptr)
400                                                break;
401                         
402                                  }
403                                  else
404                                  {
405                                          vertices.push_back(index);
406                                  }
407                                  ptr = endptr;
408                        }
409                }
410        }
411}
412
413
414void
415X3dParseHandlers::StartMaterial(AttributeList&  attributes)
416{
417        const int len = attributes.getLength();
418               
419        mCurrentMaterial = MaterialManager::GetSingleton()->CreateResource();
420 
421        for (int i = 0; i < len; ++ i)
422        {
423                const string attrName(StrX(attributes.getName(i)).LocalForm());
424               
425                const StrX attrValue(attributes.getValue(i));
426                const char *ptr = attrValue.LocalForm();
427
428
429                //-- we use an already defined material
430                if (attrName == "USE")
431                {
432                        //mUsingMaterialDefinition = true;
433                        string matName(ptr);
434
435            // retrieve mesh from mesh container
436                        const int matIdx = mMaterialDefinitions[matName];
437
438                        mCurrentMaterial =
439                                MaterialManager::GetSingleton()->FindEntry(matIdx);
440
441                        //Debug << "retrieving mesh definition: " << mCurrentMeshName << endl;
442                        cout << "u";
443                }
444                else if (attrName == "DEF") //-- a definition of a material
445                {
446                        //mIsMaterialDefinition = true;
447                        string matName(ptr);
448               
449                        //-- create new material definition
450                        mCurrentMaterial = MaterialManager::GetSingleton()->CreateResource();
451                        // store the mesh defination in a lookup table
452                        mMaterialDefinitions[matName] = mCurrentMaterial->GetId();
453                        cout << "d";
454                }
455                // TODO: support not only diffuse material
456                else if (attrName == "diffuseColor")
457                {
458                        float r, g, b;
459     
460                        if (sscanf(ptr, "%f %f %f", &r, &g, &b) == 3)
461                                mCurrentMaterial->mDiffuseColor = RgbColor(r, g, b);
462                }
463        }
464}
465
466
467void
468X3dParseHandlers::StartCoordinate(AttributeList&  attributes)
469{
470        const int len = attributes.getLength();
471       
472        int i;
473        VertexContainer vertices;
474       
475        for (i=0; i < len; i++)
476        {
477                const string attrName(StrX(attributes.getName(i)).LocalForm());
478         
479                if (attrName == "point")
480                {
481                        StrX attrValue(attributes.getValue(i));
482                 
483
484                        const char *ptr = attrValue.LocalForm();
485                        char *endptr;
486
487
488                        while (1)
489                        {
490                                float x = (float)strtod(ptr, &endptr);
491               
492                                if (ptr == endptr)
493                                  break;
494                         
495                                ptr = endptr;
496                               
497                                float y = (float)strtod(ptr, &endptr);
498                         
499                                if (ptr == endptr)
500                                        break;
501
502                                ptr = endptr;
503                         
504                                float z = (float)strtod(ptr, &endptr);
505                                if (ptr == endptr)
506                                        break;
507                         
508                                ptr = endptr;
509                         
510                                if (*ptr == ',')
511                                        ptr ++;
512
513                                Vector3 v(x, y, z);
514                                vertices.push_back(v);
515                        }
516       
517                        // substitute vertices into current mesh
518                        mCurrentMesh->mVertices = vertices;
519                }
520        }
521}
522
523
524void
525X3dParseHandlers::startElement(const XMLCh* const name,
526                                                           AttributeList&  attributes)
527{
528  StrX lname(name);
529  string element(lname.LocalForm());
530 
531  if (element == "IndexedFaceSet") {
532          // create a new mesh node in the scene graph
533          StartIndexedFaceSet(attributes);
534  }
535 
536  if (element == "Shape") {
537          cout << "+";
538
539          // reset current shape values
540          mCurrentMesh = NULL;
541          mCurrentMaterial = NULL;
542          mCurrentVertexIndices.clear();
543          //mCurrentVertices.clear();
544  }
545 
546  if (element == "Coordinate") {
547          StartCoordinate(attributes);
548  }
549
550  // todo
551  if (0 && element == "Material") {
552          StartMaterial(attributes);
553  }
554 
555  if (element == "Transform") {
556          StartTransform(attributes);
557  }
558
559  ++ mElementCount;
560  mAttrCount += attributes.getLength();
561}
562
563void
564X3dParseHandlers::characters(const XMLCh* const chars,
565                                                         const unsigned int length)
566{
567  mCharacterCount += length;
568}
569
570void
571X3dParseHandlers::ignorableWhitespace(const XMLCh* const chars,
572                                                                          const unsigned int length)
573{
574  mSpaceCount += length;
575}
576
577void
578X3dParseHandlers::resetDocument()
579{
580  mAttrCount = 0;
581  mCharacterCount = 0;
582  mElementCount = 0;
583  mSpaceCount = 0;
584}
585
586
587// ---------------------------------------------------------------------------
588//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
589// ---------------------------------------------------------------------------
590
591
592void
593X3dParseHandlers::error(const SAXParseException& e)
594{
595  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
596                            << ", line " << e.getLineNumber()
597                            << ", char " << e.getColumnNumber()
598                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
599}
600
601void
602X3dParseHandlers::fatalError(const SAXParseException& e)
603{
604  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
605                            << ", line " << e.getLineNumber()
606                            << ", char " << e.getColumnNumber()
607                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
608}
609
610void
611X3dParseHandlers::warning(const SAXParseException& e)
612{
613  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
614                            << ", line " << e.getLineNumber()
615                            << ", char " << e.getColumnNumber()
616                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
617}
618
619/*************************************************************************/
620/*                     X3dParser implementation                          */
621/*******************+*****************************************************/
622
623X3dParser::X3dParser():
624mViewCellHeight(DEFAULT_VIEWCELL_HEIGHT)
625{}
626
627bool
628X3dParser::ParseFile(const string filename,
629                                         SceneGraphNode **root,
630                                         const bool loadPolygonsAsMeshes)
631{
632  // Initialize the XML4C system
633  try {
634    XMLPlatformUtils::Initialize();
635  }
636 
637  catch (const XMLException& toCatch)
638    {
639      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
640                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
641      return false;
642    }
643 
644 
645  //
646  //  Create a SAX parser object. Then, according to what we were told on
647  //  the command line, set the options.
648  //
649  SAXParser* parser = new SAXParser;
650  parser->setValidationScheme(valScheme);
651  parser->setDoNamespaces(doNamespaces);
652  parser->setDoSchema(doSchema);
653  parser->setValidationSchemaFullChecking(schemaFullChecking);
654 
655
656  //
657  //  Create our SAX handler object and install it on the parser, as the
658  //  document and error handler. We are responsible for cleaning them
659  //  up, but since its just stack based here, there's nothing special
660  //  to do.
661  //
662  *root = new SceneGraphNode;
663  X3dParseHandlers handler(*root, loadPolygonsAsMeshes);
664  parser->setDocumentHandler(&handler);
665  parser->setErrorHandler(&handler);
666 
667  unsigned long duration;
668  int errorCount = 0;
669  // create a faux scope so that 'src' destructor is called before
670  // XMLPlatformUtils::Terminate
671  {
672    //
673    //  Kick off the parse and catch any exceptions. Create a standard
674    //  input input source and tell the parser to parse from that.
675    //
676    //    StdInInputSource src;
677    try
678      {
679        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
680        parser->parse(filename.c_str());
681       
682        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
683        duration = endMillis - startMillis;
684        errorCount = parser->getErrorCount();
685      }
686    catch (const OutOfMemoryException&)
687      {
688        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
689        errorCount = 2;
690        return false;
691      }
692    catch (const XMLException& e)
693      {
694        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
695                                  << StrX(e.getMessage())
696                                  << "\n" << XERCES_STD_QUALIFIER endl;
697        errorCount = 1;
698        return false;
699      }
700
701   
702    // Print out the stats that we collected and time taken
703    if (!errorCount) {
704      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
705                                << handler.GetElementCount() << " elems, "
706                                << handler.GetAttrCount() << " attrs, "
707                                << handler.GetSpaceCount() << " spaces, "
708                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
709    }
710  }
711 
712  //
713  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
714  //
715  delete parser;
716 
717  XMLPlatformUtils::Terminate();
718 
719  if (errorCount > 0)
720    return false;
721  else
722    return true;
723}
724
725
726
727/************************************************************************/
728/*             class X3dViewCellsParseHandlers implementation           */
729/************************************************************************/
730
731
732// ---------------------------------------------------------------------------
733//  StdInParseHandlers: Constructors and Destructor
734// ---------------------------------------------------------------------------
735X3dViewCellsParseHandlers::X3dViewCellsParseHandlers(ViewCellsManager *viewCellsManager,
736                                                                                                         const float viewCellHeight):
737mElementCount(0),
738mAttrCount(0),
739mCharacterCount(0),
740mSpaceCount(0),
741mViewCellsManager(viewCellsManager),
742mViewCellHeight(viewCellHeight)
743{
744}
745
746X3dViewCellsParseHandlers::~X3dViewCellsParseHandlers()
747{
748}
749
750
751// ---------------------------------------------------------------------------
752//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
753// ---------------------------------------------------------------------------
754void X3dViewCellsParseHandlers::endElement(const XMLCh* const name)
755{
756        StrX lname(name);
757
758        string element(lname.LocalForm());
759
760        if (element == "Shape")
761                EndShape();
762}
763
764void
765X3dViewCellsParseHandlers::EndShape()
766{
767        // currently processing no shape
768}
769
770void
771X3dViewCellsParseHandlers::StartIndexedFaceSet(
772                                      AttributeList&  attributes)
773{
774        int len = attributes.getLength();
775        int i;
776       
777        for (i=0; i < len; i++)
778        {
779                string attrName(StrX(attributes.getName(i)).LocalForm());
780           
781
782                if (attrName == "coordIndex")
783                {
784                        StrX attrValue(attributes.getValue(i));
785                       
786                        // handle coordIndex
787                        const char *ptr = attrValue.LocalForm();
788                        char *endptr;
789               
790                        while (1)
791                        {
792                                int index = strtol(ptr, &endptr, 10);
793                               
794                                if (ptr == endptr)
795                                        break;
796
797                                if (index != -1)
798                                {
799                                        mCurrentVertexIndices.push_back(index);
800                                }
801                   
802                                ptr = endptr;
803                        }
804                }
805        }
806}
807
808
809void
810X3dViewCellsParseHandlers::StartCoordinate(AttributeList&  attributes)
811{
812        int len = attributes.getLength();
813       
814        VertexContainer vertices;
815        int i;
816        for (i=0; i < len; i++)
817        {
818                string attrName(StrX(attributes.getName(i)).LocalForm());
819               
820                if (attrName == "point")
821                {
822                        StrX attrValue(attributes.getValue(i));
823                       
824                        const char *ptr = attrValue.LocalForm();
825                       
826                        char *endptr;
827                       
828                        while (1)
829                        {
830                                float x = (float)strtod(ptr, &endptr);
831               
832                                if (ptr == endptr)
833                                        break;
834                                ptr = endptr;
835                               
836                                float y = (float)(float)strtod(ptr, &endptr);
837
838                               
839                                if (ptr == endptr)
840                                        break;
841                                ptr = endptr;
842
843                                float z = (float)(float)strtod(ptr, &endptr);
844
845                                if (ptr == endptr)
846                                        break;
847
848                                ptr = endptr;
849                                if (*ptr == ',')
850                                        ptr++;
851
852                                Vector3 v(x, y, z);
853                                vertices.push_back(v);                         
854                        }
855                }
856        }
857
858        for (i = 0; i < mCurrentVertexIndices.size(); i += 3)
859        {
860                Triangle3 baseTri(vertices[mCurrentVertexIndices[i + 0]],
861                                                  vertices[mCurrentVertexIndices[i + 1]],
862                                                  vertices[mCurrentVertexIndices[i + 2]]);
863
864                // create view cell from base triangle
865                mViewCellsManager->AddViewCell(
866                        mViewCellsManager->ExtrudeViewCell(baseTri,
867                        mViewCellHeight));
868        }
869}
870
871
872void
873X3dViewCellsParseHandlers::startElement(const XMLCh* const name,
874                                                                                AttributeList&  attributes)
875{
876  StrX lname(name);
877  string element(lname.LocalForm());
878 
879  if (element == "IndexedFaceSet") {
880    // create the viewcells from individual triangles
881    StartIndexedFaceSet(attributes);
882  }
883       
884  if (element == "Coordinate") {
885          // add coordinates to the triangles
886      StartCoordinate(attributes);
887  }
888  // do nothing
889  //if (element == "Shape") {}
890  // ignore material
891  //if (element == "Material") {}
892
893  ++ mElementCount;
894  mAttrCount += attributes.getLength();
895}
896
897void
898X3dViewCellsParseHandlers::characters(const XMLCh* const chars,
899                             const unsigned int length)
900{
901  mCharacterCount += length;
902}
903
904void
905X3dViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
906                                      const unsigned int length)
907{
908  mSpaceCount += length;
909}
910
911void
912X3dViewCellsParseHandlers::resetDocument()
913{
914  mAttrCount = 0;
915  mCharacterCount = 0;
916  mElementCount = 0;
917  mSpaceCount = 0;
918}
919
920
921
922// ---------------------------------------------------------------------------
923//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
924// ---------------------------------------------------------------------------
925void
926X3dViewCellsParseHandlers::error(const SAXParseException& e)
927{
928  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
929                            << ", line " << e.getLineNumber()
930                            << ", char " << e.getColumnNumber()
931                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
932}
933
934void
935X3dViewCellsParseHandlers::fatalError(const SAXParseException& e)
936{
937  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
938                            << ", line " << e.getLineNumber()
939                            << ", char " << e.getColumnNumber()
940                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
941}
942
943void
944X3dViewCellsParseHandlers::warning(const SAXParseException& e)
945{
946  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
947                            << ", line " << e.getLineNumber()
948                            << ", char " << e.getColumnNumber()
949                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
950}
951
952
953bool
954X3dParser::ParseFile(const string filename, ViewCellsManager &viewCells)
955{
956  // Initialize the XML4C system
957  try {
958    XMLPlatformUtils::Initialize();
959  }
960 
961  catch (const XMLException& toCatch)
962    {
963      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
964                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
965      return false;
966    }
967 
968 
969  //
970  //  Create a SAX parser object. Then, according to what we were told on
971  //  the command line, set the options.
972  //
973  SAXParser* parser = new SAXParser;
974  parser->setValidationScheme(valScheme);
975  parser->setDoNamespaces(doNamespaces);
976  parser->setDoSchema(doSchema);
977  parser->setValidationSchemaFullChecking(schemaFullChecking);
978 
979
980  //
981  //  Create our SAX handler object and install it on the parser, as the
982  //  document and error handler. We are responsible for cleaning them
983  //  up, but since its just stack based here, there's nothing special
984  //  to do.
985  //
986  X3dViewCellsParseHandlers handler(&viewCells, mViewCellHeight);
987  parser->setDocumentHandler(&handler);
988  parser->setErrorHandler(&handler);
989 
990  unsigned long duration;
991  int errorCount = 0;
992  // create a faux scope so that 'src' destructor is called before
993  // XMLPlatformUtils::Terminate
994  {
995    //
996    //  Kick off the parse and catch any exceptions. Create a standard
997    //  input input source and tell the parser to parse from that.
998    //
999    //    StdInInputSource src;
1000    try
1001      {
1002        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
1003        //GzBinFileInputStream str(filename.c_str());
1004       
1005        parser->parse(filename.c_str());
1006        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1007        duration = endMillis - startMillis;
1008        errorCount = parser->getErrorCount();
1009      }
1010    catch (const OutOfMemoryException&)
1011      {
1012        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1013        errorCount = 2;
1014        return false;
1015      }
1016    catch (const XMLException& e)
1017      {
1018        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
1019                                  << StrX(e.getMessage())
1020                                  << "\n" << XERCES_STD_QUALIFIER endl;
1021        errorCount = 1;
1022        return false;
1023      }
1024
1025   
1026    // Print out the stats that we collected and time taken
1027    if (!errorCount) {
1028      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
1029                                << handler.GetElementCount() << " elems, "
1030                                << handler.GetAttrCount() << " attrs, "
1031                                << handler.GetSpaceCount() << " spaces, "
1032                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1033    }
1034  }
1035 
1036  //
1037  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1038  //
1039  delete parser;
1040 
1041  XMLPlatformUtils::Terminate();
1042 
1043  if (errorCount > 0)
1044    return false;
1045  else
1046    return true;
1047}
1048
1049
1050
1051
1052}
Note: See TracBrowser for help on using the repository browser.