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

Revision 1404, 27.8 KB checked in by mattausch, 18 years ago (diff)

debugging after merge

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