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

Revision 2176, 26.6 KB checked in by mattausch, 17 years ago (diff)

removed using namespace std from .h

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