Subversion Repositories gelsvn

Rev

Rev 25 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>

#if defined(_MSC_VER)
#include <io.h>

#pragma message("Note: including lib: expat.lib\n")
#pragma comment(lib, "expat.lib")

#else
#include <unistd.h>
#endif
#include <expat.h>

#include "CGLA/CGLA.h"
#include "Util/Timer.h"
#include "Util/Parse.h"
#include "x3d_load.h"

using namespace std;
using namespace CGLA;
using namespace Util;
using namespace IMesh;

namespace IMeshUtil
{
  namespace
  {
                TriMeshBuilder* bldr;
  }
        
  void startElement(void *userData, const char *name, const char **atts) 
  {
    if (strcmp(name,"IndexedFaceSet")==0)
      {
                                int j=0;
                                for(j=0; atts[j]!=0; ++j) 
                                        {
                                                if (strcmp(atts[j],"coordIndex")==0) 
                                                        { 
                                                                vector<int> coord_index;
                                                                parse(atts[++j],coord_index);
                                                                
                                                                int tri=0;
                                                                Vec3i face;
                                                                for(int i=0;i<coord_index.size();i++) 
                                                                        {
                                                                                if (coord_index[i]==-1) 
                                                                                        {
                                                                                                tri=0;
                                                                                                continue;
                                                                                        }
                                                                                switch(tri)
                                                                                        {
                                                                                        case 0:
                                                                                                face[tri] = coord_index[i];
                                                                                                tri++;
                                                                                                break;
                                                                                        case 1:
                                                                                                face[tri] = coord_index[i];
                                                                                                tri++;
                                                                                                break;
                                                                                        case 2:
                                                                                                face[tri] = coord_index[i];
                                                                                                tri++;
                                                                                                bldr->add_face(face);
                                                                                                break;
                                                                                        default:
                                                                                                /* This is not a triangle. 
                                                                                                         We perform a super-naive triangulation. */
                                                                                                face[0] = coord_index[i-1];
                                                                                                face[1] = coord_index[i];
                                                                                                face[2] = coord_index[i-tri];
                                                                                                bldr->add_face(face);
                                                                                                tri++;
                                                                                                break;
                                                                                        }
                                                                        } 
                                                        }
                                } 
                        }
                else if (strcmp(name,"Shape")==0) 
      {
                                cout << "Found shape" << endl;
      }
    else if (strcmp(name,"Coordinate")==0) 
      { 
                                int j=0;
                                for (j=0; atts[j]!=0; ++j) 
                                        {
                                                if (strcmp(atts[j],"point")==0) 
                                                        { 
                                                                vector<Vec3f> vertices;
                                                                parse(atts[++j],vertices);
                                                                for(int i=0;i<vertices.size();++i)
                                                                        bldr->add_vpos(vertices[i]);
                                                        }
                                        }
                        }
        }

  void endElement(void *userData, const char *name) 
  {
    if (strcmp(name,"Shape")==0) 
      {
                                cout << "Shape ends" << endl;                           
      } 
  }

  bool x3d_load(const std::string& filename, TriMeshBuilder& builder)
  {
                bldr = &builder;
                builder.clear();

    Util::Timer tim;
    tim.start();

    std::string baseurl;
#define FIND_LAST_OF(F,C) (int)(F.find_last_of(C) == string::npos ? -1 : F.find_last_of(C))     
    int idx = max(FIND_LAST_OF(filename, "\\"), FIND_LAST_OF(filename, "/"));
#undef FIND_LAST_OF

    if(idx != -1)
      baseurl = std::string(filename.substr(0, idx+1));


    XML_Parser parser = XML_ParserCreate(NULL);
    int done=0;
    XML_SetElementHandler(parser, startElement, endElement);

    int in;
    if ((in=open(filename.data(),O_RDONLY)) == -1) {
      cout << "Error. "<<  filename << " not found" << endl;
      assert(0);
      return false;
    }

    struct stat stat_buf;
    fstat(in, &stat_buf);

    const int BUF_SIZE = CGLA::s_min(50000000, static_cast<int>(stat_buf.st_size));
                cout << "buffer size : " << BUF_SIZE << endl;
    char* buf2 = new char[BUF_SIZE];
    size_t len;
    do {
      len = read(in, buf2, BUF_SIZE);
      if (len!=BUF_SIZE)
                                done=1;
      if (!XML_Parse(parser, buf2, len, done)) {
                                cerr << "%s at line %d\n" 
                                                 << XML_ErrorString(XML_GetErrorCode(parser))
                                                 << XML_GetCurrentLineNumber(parser);
                                assert(0);
                                return false;
      }
    } while (!done);
    close(in);
    XML_ParserFree(parser);
    delete buf2;

    cout << " Loading took " << tim.get_secs() << endl;
    return true;
  }
}