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

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