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

Revision 1020, 27.3 KB checked in by mattausch, 18 years ago (diff)

worked on view-object space partition
fixed some loading bugs
fixeds some exporting bugs using line segments
enabling other methods for view space sampling in ViewCellsManager? OBJECT_DIRECTION_BASED_DISTRIBUTION)
added class interface for a sampling strategy

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