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

Revision 1420, 27.9 KB checked in by mattausch, 18 years ago (diff)

corrected raycasting bug for triangles because of ill defined triangles

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