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

Revision 2610, 26.6 KB checked in by bittner, 17 years ago (diff)

pixel error computation revival

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