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

Revision 1005, 26.7 KB checked in by mattausch, 18 years ago (diff)
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", &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", &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", &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 (mCurrentMesh->mFaces.empty())
278                        cout << "warning: empy mesh" << endl;
279
280                if (!mUsingMeshDefinition)
281                {
282                        // make an instance of this mesh
283            mi = new MeshInstance(mCurrentMesh);
284
285                        // this mesh is used only once => write transformations directly into it
286                        ApplyTransformations(mTransformations, mCurrentMesh);
287                }
288                else
289                {
290                         // make an instance of this mesh
291                         TransformedMeshInstance *tmi = new TransformedMeshInstance(mCurrentMesh);
292
293                         // apply transformation on the instance of the mesh
294                         ApplyTransformations(mTransformations, tmi);
295
296                         mi = tmi;
297                }
298               
299                if (mCurrentMaterial)
300                {
301                        // HACK: add the material to the mesh directly if no material yet
302                        if (mCurrentMesh->mMaterial)
303                        {
304                                mCurrentMesh->mMaterial = mCurrentMaterial;
305                        }
306                        else // add material to the instance
307                        {
308                                mi->SetMaterial(mCurrentMaterial);
309                        }
310                }
311
312                // create local mesh kd tree
313                mCurrentMesh->Preprocess();
314                // add to scene graph
315                mCurrentNode->mGeometry.push_back(mi);
316       
317                // reset current mesh
318                mCurrentMesh = NULL;
319        }
320}
321
322
323void X3dParseHandlers::StartIndexedFaceSet(AttributeList&  attributes)
324{
325        //-- indexedfaceset corresponds  to Mesh in our implementation
326        const int len = attributes.getLength();
327
328        VertexIndexContainer vertices;
329 
330        mIsMeshDefinition = false;
331        mUsingMeshDefinition = false;
332
333        for (int i = 0; i < len; ++ i)
334        {
335                const string attrName(StrX(attributes.getName(i)).LocalForm());
336       
337                //-- we use an already defined mesh
338                if (attrName == "USE")
339                {
340                        StrX attrValue(attributes.getValue(i));
341                        const char *meshName = attrValue.LocalForm();
342
343                        mUsingMeshDefinition = true;
344
345            // retrieve mesh from mesh container
346                        const int meshIdx = mMeshDefinitions[meshName];
347
348                        mCurrentMesh =
349                                MeshManager::GetSingleton()->FindEntry(meshIdx);
350
351                        //Debug << "retrieving mesh definition: " << mCurrentMeshName << endl;
352                        cout << "u";
353                }
354                else if (attrName == "DEF") //-- a definition of a mesh
355                {
356                        const StrX attrValue(attributes.getValue(i));
357                        const char *meshName = attrValue.LocalForm();
358
359                        // this is only a definition, don't create actual  instance
360                        mIsMeshDefinition = true;
361                       
362                        //-- create new mesh definition
363                        mCurrentMesh = MeshManager::GetSingleton()->CreateResource();
364                       
365                        // store the mesh defination in a lookup table
366                        mMeshDefinitions[meshName] = mCurrentMesh->GetId();
367                        cout << "d";
368                }
369               
370                //-- read coordinate indices for current mesh
371                else if (attrName == "coordIndex")
372                {
373                        StrX attrValue(attributes.getValue(i));
374                        const char *ptr = attrValue.LocalForm();
375
376                        //-- immediate use: create a new mesh using a generic name
377                        if (!mCurrentMesh)
378                        {
379                                mCurrentMesh = MeshManager::GetSingleton()->CreateResource();
380                        }
381
382                        // handle coordIndex
383                        vertices.clear();
384                       
385                 
386                        char *endptr;
387         
388                        while (1)
389                        {
390                                int index = strtol(ptr, &endptr, 10);
391                                 
392                                if (ptr == endptr || index == -1)
393                                {
394                                        if (vertices.size() > 2)
395                                        {
396                                                Face *face = new Face(vertices);                 
397                                                mCurrentMesh->mFaces.push_back(face);
398                                        }
399                         
400                                        vertices.clear();
401                 
402                                        if (ptr == endptr)
403                                                break;
404                         
405                                  }
406                                  else
407                                  {
408                                          vertices.push_back(index);
409                                  }
410                                  ptr = endptr;
411                        }
412                }
413        }
414}
415
416
417void
418X3dParseHandlers::StartMaterial(AttributeList&  attributes)
419{
420        const int len = attributes.getLength();
421               
422        mCurrentMaterial = MaterialManager::GetSingleton()->CreateResource();
423 
424        for (int i = 0; i < len; ++ i)
425        {
426                const string attrName(StrX(attributes.getName(i)).LocalForm());
427               
428                const StrX attrValue(attributes.getValue(i));
429                const char *ptr = attrValue.LocalForm();
430
431
432                //-- we use an already defined material
433                if (attrName == "USE")
434                {
435                        //mUsingMaterialDefinition = true;
436                        string matName(ptr);
437
438            // retrieve mesh from mesh container
439                        const int matIdx = mMaterialDefinitions[matName];
440
441                        mCurrentMaterial =
442                                MaterialManager::GetSingleton()->FindEntry(matIdx);
443
444                        //Debug << "retrieving mesh definition: " << mCurrentMeshName << endl;
445                        cout << "u";
446                }
447                else if (attrName == "DEF") //-- a definition of a material
448                {
449                        //mIsMaterialDefinition = true;
450                        string matName(ptr);
451               
452                        //-- create new material definition
453                        mCurrentMaterial = MaterialManager::GetSingleton()->CreateResource();
454                        // store the mesh defination in a lookup table
455                        mMaterialDefinitions[matName] = mCurrentMaterial->GetId();
456                        cout << "d";
457                }
458                // TODO: support not only diffuse material
459                else if (attrName == "diffuseColor")
460                {
461                        float r, g, b;
462     
463                        if (sscanf(ptr, "%f %f %f", &r, &g, &b) == 3)
464                                mCurrentMaterial->mDiffuseColor = RgbColor(r, g, b);
465                }
466        }
467}
468
469
470void
471X3dParseHandlers::StartCoordinate(AttributeList&  attributes)
472{
473        const int len = attributes.getLength();
474       
475        int i;
476        VertexContainer vertices;
477       
478        for (i=0; i < len; i++)
479        {
480                const string attrName(StrX(attributes.getName(i)).LocalForm());
481         
482                if (attrName == "point")
483                {
484                        StrX attrValue(attributes.getValue(i));
485                 
486
487                        const char *ptr = attrValue.LocalForm();
488                        char *endptr;
489
490
491                        while (1)
492                        {
493                                float x = (float)strtod(ptr, &endptr);
494               
495                                if (ptr == endptr)
496                                  break;
497                         
498                                ptr = endptr;
499                               
500                                float y = (float)strtod(ptr, &endptr);
501                         
502                                if (ptr == endptr)
503                                        break;
504
505                                ptr = endptr;
506                         
507                                float z = (float)strtod(ptr, &endptr);
508                                if (ptr == endptr)
509                                        break;
510                         
511                                ptr = endptr;
512                         
513                                if (*ptr == ',')
514                                        ptr ++;
515
516                                Vector3 v(x, y, z);
517                                vertices.push_back(v);
518                        }
519       
520                        // substitute vertices into current mesh
521                        mCurrentMesh->mVertices = vertices;
522                }
523        }
524}
525
526
527void
528X3dParseHandlers::startElement(const XMLCh* const name,
529                                                           AttributeList&  attributes)
530{
531  StrX lname(name);
532  string element(lname.LocalForm());
533 
534  if (element == "IndexedFaceSet") {
535          // create a new mesh node in the scene graph
536          StartIndexedFaceSet(attributes);
537  }
538 
539  if (element == "Shape") {
540          cout << "+";
541
542          // reset current shape values
543          mCurrentMesh = NULL;
544          mCurrentMaterial = NULL;
545          mCurrentVertexIndices.clear();
546          //mCurrentVertices.clear();
547  }
548 
549  if (element == "Coordinate") {
550          StartCoordinate(attributes);
551  }
552
553  // todo
554  if (element == "Material") {
555          StartMaterial(attributes);
556  }
557 
558  if (element == "Transform") {
559          StartTransform(attributes);
560  }
561
562  ++ mElementCount;
563  mAttrCount += attributes.getLength();
564}
565
566void
567X3dParseHandlers::characters(const XMLCh* const chars,
568                                                         const unsigned int length)
569{
570  mCharacterCount += length;
571}
572
573void
574X3dParseHandlers::ignorableWhitespace(const XMLCh* const chars,
575                                                                          const unsigned int length)
576{
577  mSpaceCount += length;
578}
579
580void
581X3dParseHandlers::resetDocument()
582{
583  mAttrCount = 0;
584  mCharacterCount = 0;
585  mElementCount = 0;
586  mSpaceCount = 0;
587}
588
589
590// ---------------------------------------------------------------------------
591//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
592// ---------------------------------------------------------------------------
593
594
595void
596X3dParseHandlers::error(const SAXParseException& e)
597{
598  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
599                            << ", line " << e.getLineNumber()
600                            << ", char " << e.getColumnNumber()
601                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
602}
603
604void
605X3dParseHandlers::fatalError(const SAXParseException& e)
606{
607  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
608                            << ", line " << e.getLineNumber()
609                            << ", char " << e.getColumnNumber()
610                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
611}
612
613void
614X3dParseHandlers::warning(const SAXParseException& e)
615{
616  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
617                            << ", line " << e.getLineNumber()
618                            << ", char " << e.getColumnNumber()
619                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
620}
621
622/*************************************************************************/
623/*                     X3dParser implementation                          */
624/*******************+*****************************************************/
625
626X3dParser::X3dParser():
627mViewCellHeight(DEFAULT_VIEWCELL_HEIGHT)
628{}
629
630bool
631X3dParser::ParseFile(const string filename,
632                                         SceneGraphNode **root,
633                                         const bool loadPolygonsAsMeshes)
634{
635  // Initialize the XML4C system
636  try {
637    XMLPlatformUtils::Initialize();
638  }
639 
640  catch (const XMLException& toCatch)
641    {
642      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
643                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
644      return false;
645    }
646 
647 
648  //
649  //  Create a SAX parser object. Then, according to what we were told on
650  //  the command line, set the options.
651  //
652  SAXParser* parser = new SAXParser;
653  parser->setValidationScheme(valScheme);
654  parser->setDoNamespaces(doNamespaces);
655  parser->setDoSchema(doSchema);
656  parser->setValidationSchemaFullChecking(schemaFullChecking);
657 
658
659  //
660  //  Create our SAX handler object and install it on the parser, as the
661  //  document and error handler. We are responsible for cleaning them
662  //  up, but since its just stack based here, there's nothing special
663  //  to do.
664  //
665  *root = new SceneGraphNode;
666  X3dParseHandlers handler(*root, loadPolygonsAsMeshes);
667  parser->setDocumentHandler(&handler);
668  parser->setErrorHandler(&handler);
669 
670  unsigned long duration;
671  int errorCount = 0;
672  // create a faux scope so that 'src' destructor is called before
673  // XMLPlatformUtils::Terminate
674  {
675    //
676    //  Kick off the parse and catch any exceptions. Create a standard
677    //  input input source and tell the parser to parse from that.
678    //
679    //    StdInInputSource src;
680    try
681      {
682        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
683        parser->parse(filename.c_str());
684       
685        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
686        duration = endMillis - startMillis;
687        errorCount = parser->getErrorCount();
688      }
689    catch (const OutOfMemoryException&)
690      {
691        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
692        errorCount = 2;
693        return false;
694      }
695    catch (const XMLException& e)
696      {
697        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
698                                  << StrX(e.getMessage())
699                                  << "\n" << XERCES_STD_QUALIFIER endl;
700        errorCount = 1;
701        return false;
702      }
703
704   
705    // Print out the stats that we collected and time taken
706    if (!errorCount) {
707      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
708                                << handler.GetElementCount() << " elems, "
709                                << handler.GetAttrCount() << " attrs, "
710                                << handler.GetSpaceCount() << " spaces, "
711                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
712    }
713  }
714 
715  //
716  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
717  //
718  delete parser;
719 
720  XMLPlatformUtils::Terminate();
721 
722  if (errorCount > 0)
723    return false;
724  else
725    return true;
726}
727
728
729
730/************************************************************************/
731/*             class X3dViewCellsParseHandlers implementation           */
732/************************************************************************/
733
734
735// ---------------------------------------------------------------------------
736//  StdInParseHandlers: Constructors and Destructor
737// ---------------------------------------------------------------------------
738X3dViewCellsParseHandlers::X3dViewCellsParseHandlers(ViewCellsManager *viewCellsManager,
739                                                                                                         const float viewCellHeight):
740mElementCount(0),
741mAttrCount(0),
742mCharacterCount(0),
743mSpaceCount(0),
744mViewCellsManager(viewCellsManager),
745mViewCellHeight(viewCellHeight)
746{
747}
748
749X3dViewCellsParseHandlers::~X3dViewCellsParseHandlers()
750{
751}
752
753
754// ---------------------------------------------------------------------------
755//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
756// ---------------------------------------------------------------------------
757void X3dViewCellsParseHandlers::endElement(const XMLCh* const name)
758{
759        StrX lname(name);
760
761        string element(lname.LocalForm());
762
763        if (element == "Shape")
764                EndShape();
765}
766
767void
768X3dViewCellsParseHandlers::EndShape()
769{
770        // currently processing no shape
771}
772
773void
774X3dViewCellsParseHandlers::StartIndexedFaceSet(
775                                      AttributeList&  attributes)
776{
777        int len = attributes.getLength();
778        int i;
779       
780        for (i=0; i < len; i++)
781        {
782                string attrName(StrX(attributes.getName(i)).LocalForm());
783           
784
785                if (attrName == "coordIndex")
786                {
787                        StrX attrValue(attributes.getValue(i));
788                       
789                        // handle coordIndex
790                        const char *ptr = attrValue.LocalForm();
791                        char *endptr;
792               
793                        while (1)
794                        {
795                                int index = strtol(ptr, &endptr, 10);
796                               
797                                if (ptr == endptr)
798                                        break;
799
800                                if (index != -1)
801                                {
802                                        mCurrentVertexIndices.push_back(index);
803                                }
804                   
805                                ptr = endptr;
806                        }
807                }
808        }
809}
810
811
812void
813X3dViewCellsParseHandlers::StartCoordinate(AttributeList&  attributes)
814{
815        int len = attributes.getLength();
816       
817        VertexContainer vertices;
818        int i;
819        for (i=0; i < len; i++)
820        {
821                string attrName(StrX(attributes.getName(i)).LocalForm());
822               
823                if (attrName == "point")
824                {
825                        StrX attrValue(attributes.getValue(i));
826                       
827                        const char *ptr = attrValue.LocalForm();
828                       
829                        char *endptr;
830                       
831                        while (1)
832                        {
833                                float x = (float)strtod(ptr, &endptr);
834               
835                                if (ptr == endptr)
836                                        break;
837                                ptr = endptr;
838                               
839                                float y = (float)(float)strtod(ptr, &endptr);
840
841                               
842                                if (ptr == endptr)
843                                        break;
844                                ptr = endptr;
845
846                                float z = (float)(float)strtod(ptr, &endptr);
847
848                                if (ptr == endptr)
849                                        break;
850
851                                ptr = endptr;
852                                if (*ptr == ',')
853                                        ptr++;
854
855                                Vector3 v(x, y, z);
856                                vertices.push_back(v);                         
857                        }
858                }
859        }
860
861        for (i = 0; i < mCurrentVertexIndices.size(); i += 3)
862        {
863                Triangle3 baseTri(vertices[mCurrentVertexIndices[i + 0]],
864                                                  vertices[mCurrentVertexIndices[i + 1]],
865                                                  vertices[mCurrentVertexIndices[i + 2]]);
866
867                // create view cell from base triangle
868                mViewCellsManager->AddViewCell(
869                        mViewCellsManager->ExtrudeViewCell(baseTri,
870                        mViewCellHeight));
871        }
872}
873
874
875void
876X3dViewCellsParseHandlers::startElement(const XMLCh* const name,
877                                                                                AttributeList&  attributes)
878{
879  StrX lname(name);
880  string element(lname.LocalForm());
881 
882  if (element == "IndexedFaceSet") {
883    // create the viewcells from individual triangles
884    StartIndexedFaceSet(attributes);
885  }
886       
887  if (element == "Coordinate") {
888          // add coordinates to the triangles
889      StartCoordinate(attributes);
890  }
891  // do nothing
892  //if (element == "Shape") {}
893  // ignore material
894  //if (element == "Material") {}
895
896  ++ mElementCount;
897  mAttrCount += attributes.getLength();
898}
899
900void
901X3dViewCellsParseHandlers::characters(const XMLCh* const chars,
902                             const unsigned int length)
903{
904  mCharacterCount += length;
905}
906
907void
908X3dViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
909                                      const unsigned int length)
910{
911  mSpaceCount += length;
912}
913
914void
915X3dViewCellsParseHandlers::resetDocument()
916{
917  mAttrCount = 0;
918  mCharacterCount = 0;
919  mElementCount = 0;
920  mSpaceCount = 0;
921}
922
923
924
925// ---------------------------------------------------------------------------
926//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
927// ---------------------------------------------------------------------------
928void
929X3dViewCellsParseHandlers::error(const SAXParseException& e)
930{
931  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
932                            << ", line " << e.getLineNumber()
933                            << ", char " << e.getColumnNumber()
934                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
935}
936
937void
938X3dViewCellsParseHandlers::fatalError(const SAXParseException& e)
939{
940  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
941                            << ", line " << e.getLineNumber()
942                            << ", char " << e.getColumnNumber()
943                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
944}
945
946void
947X3dViewCellsParseHandlers::warning(const SAXParseException& e)
948{
949  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
950                            << ", line " << e.getLineNumber()
951                            << ", char " << e.getColumnNumber()
952                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
953}
954
955
956bool
957X3dParser::ParseFile(const string filename, ViewCellsManager &viewCells)
958{
959  // Initialize the XML4C system
960  try {
961    XMLPlatformUtils::Initialize();
962  }
963 
964  catch (const XMLException& toCatch)
965    {
966      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
967                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
968      return false;
969    }
970 
971 
972  //
973  //  Create a SAX parser object. Then, according to what we were told on
974  //  the command line, set the options.
975  //
976  SAXParser* parser = new SAXParser;
977  parser->setValidationScheme(valScheme);
978  parser->setDoNamespaces(doNamespaces);
979  parser->setDoSchema(doSchema);
980  parser->setValidationSchemaFullChecking(schemaFullChecking);
981 
982
983  //
984  //  Create our SAX handler object and install it on the parser, as the
985  //  document and error handler. We are responsible for cleaning them
986  //  up, but since its just stack based here, there's nothing special
987  //  to do.
988  //
989  X3dViewCellsParseHandlers handler(&viewCells, mViewCellHeight);
990  parser->setDocumentHandler(&handler);
991  parser->setErrorHandler(&handler);
992 
993  unsigned long duration;
994  int errorCount = 0;
995  // create a faux scope so that 'src' destructor is called before
996  // XMLPlatformUtils::Terminate
997  {
998    //
999    //  Kick off the parse and catch any exceptions. Create a standard
1000    //  input input source and tell the parser to parse from that.
1001    //
1002    //    StdInInputSource src;
1003    try
1004      {
1005        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
1006        //GzBinFileInputStream str(filename.c_str());
1007       
1008        parser->parse(filename.c_str());
1009        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1010        duration = endMillis - startMillis;
1011        errorCount = parser->getErrorCount();
1012      }
1013    catch (const OutOfMemoryException&)
1014      {
1015        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1016        errorCount = 2;
1017        return false;
1018      }
1019    catch (const XMLException& e)
1020      {
1021        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
1022                                  << StrX(e.getMessage())
1023                                  << "\n" << XERCES_STD_QUALIFIER endl;
1024        errorCount = 1;
1025        return false;
1026      }
1027
1028   
1029    // Print out the stats that we collected and time taken
1030    if (!errorCount) {
1031      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
1032                                << handler.GetElementCount() << " elems, "
1033                                << handler.GetAttrCount() << " attrs, "
1034                                << handler.GetSpaceCount() << " spaces, "
1035                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1036    }
1037  }
1038 
1039  //
1040  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1041  //
1042  delete parser;
1043 
1044  XMLPlatformUtils::Terminate();
1045 
1046  if (errorCount > 0)
1047    return false;
1048  else
1049    return true;
1050}
1051
1052
1053
1054
1055}
Note: See TracBrowser for help on using the repository browser.