Blame | 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;
}
}