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

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