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

Revision 1272, 27.3 KB checked in by bittner, 18 years ago (diff)

mlrta configuration changes

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