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

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