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

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