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

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