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

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