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

Revision 2610, 26.6 KB checked in by bittner, 17 years ago (diff)

pixel error computation revival

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