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

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

fixed sah for objeect partition
loader for single triangles also for x3d

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