Rev 337 | Blame | Last modification | View Log | RSS feed
/*
* ply_load.cpp
* GEL
*
* Created by J. Andreas Bærentzen on 08/08/07.
* Copyright 2007 __MyCompanyName__. All rights reserved.
*
*/
#include <stdio.h>
#include <math.h>
#include <strings.h>
#include "ply_load.h"
#include <CGLA/Vec4f.h>
using namespace std;
using namespace Geometry;
using namespace CGLA;
typedef struct Vertex {
float x,y,z;
float r,g,b;
float nx,ny,nz;
void *other_props; /* other properties */
} Vertex;
typedef struct Face {
unsigned char nverts; /* number of vertex indices in list */
int *verts; /* vertex index list */
void *other_props; /* other properties */
} Face;
char *elem_names[] = { /* list of the elements in the object */
"vertex", "face"
};
PlyProperty vert_props[] = { /* list of property information for a vertex */
{"x", Float32, Float32, offsetof(Vertex,x), 0, 0, 0, 0},
{"y", Float32, Float32, offsetof(Vertex,y), 0, 0, 0, 0},
{"z", Float32, Float32, offsetof(Vertex,z), 0, 0, 0, 0},
{"r", Float32, Float32, offsetof(Vertex,r), 0, 0, 0, 0},
{"g", Float32, Float32, offsetof(Vertex,g), 0, 0, 0, 0},
{"b", Float32, Float32, offsetof(Vertex,b), 0, 0, 0, 0},
{"nx", Float32, Float32, offsetof(Vertex,nx), 0, 0, 0, 0},
{"ny", Float32, Float32, offsetof(Vertex,ny), 0, 0, 0, 0},
{"nz", Float32, Float32, offsetof(Vertex,nz), 0, 0, 0, 0},
};
PlyProperty face_props[] = { /* list of property information for a face */
{"vertex_indices", Int32, Int32, offsetof(Face,verts),
1, Uint8, Uint8, offsetof(Face,nverts)},
};
/*** the PLY object ***/
static int nverts,nfaces;
static Vertex **vlist;
static Face **flist;
static PlyOtherProp *vert_other,*face_other;
static int per_vertex_color = 0;
static int has_normals = 0;
void read_file(FILE* f)
{
int i,j;
int elem_count;
char *elem_name;
PlyFile *in_ply;
/*** Read in the original PLY object ***/
in_ply = read_ply (f);
for (i = 0; i < in_ply->num_elem_types; i++) {
/* prepare to read the i'th list of elements */
elem_name = setup_element_read_ply (in_ply, i, &elem_count);
if (equal_strings ("vertex", elem_name)) {
/* create a vertex list to hold all the vertices */
vlist = (Vertex **) malloc (sizeof (Vertex *) * elem_count);
nverts = elem_count;
/* set up for getting vertex elements */
setup_property_ply (in_ply, &vert_props[0]);
setup_property_ply (in_ply, &vert_props[1]);
setup_property_ply (in_ply, &vert_props[2]);
for (j = 0; j < in_ply->elems[i]->nprops; j++) {
PlyProperty *prop;
prop = in_ply->elems[i]->props[j];
if (equal_strings ("r", prop->name)) {
setup_property_ply (in_ply, &vert_props[3]);
per_vertex_color = 1;
}
if (equal_strings ("g", prop->name)) {
setup_property_ply (in_ply, &vert_props[4]);
per_vertex_color = 1;
}
if (equal_strings ("b", prop->name)) {
setup_property_ply (in_ply, &vert_props[5]);
per_vertex_color = 1;
}
if (equal_strings ("nx", prop->name)) {
setup_property_ply (in_ply, &vert_props[6]);
has_normals = 1;
}
if (equal_strings ("ny", prop->name)) {
setup_property_ply (in_ply, &vert_props[7]);
has_normals = 1;
}
if (equal_strings ("nz", prop->name)) {
setup_property_ply (in_ply, &vert_props[8]);
has_normals = 1;
}
}
vert_other = get_other_properties_ply (in_ply,
offsetof(Vertex,other_props));
/* grab all the vertex elements */
for (j = 0; j < elem_count; j++) {
vlist[j] = (Vertex *) malloc (sizeof (Vertex));
vlist[j]->r = 1;
vlist[j]->g = 1;
vlist[j]->b = 1;
get_element_ply (in_ply, (void *) vlist[j]);
}
}
else if (equal_strings ("face", elem_name)) {
/* create a list to hold all the face elements */
flist = (Face **) malloc (sizeof (Face *) * elem_count);
nfaces = elem_count;
/* set up for getting face elements */
setup_property_ply (in_ply, &face_props[0]);
face_other = get_other_properties_ply (in_ply,
offsetof(Face,other_props));
/* grab all the face elements */
for (j = 0; j < elem_count; j++) {
flist[j] = (Face *) malloc (sizeof (Face));
get_element_ply (in_ply, (void *) flist[j]);
}
}
else
get_other_element_ply (in_ply);
}
close_ply (in_ply);
free_ply (in_ply);
}
void ply_load(const std::string& fn, Geometry::TriMesh& mesh)
{
Vec3f v;
FILE* f = fopen(fn.c_str(),"rb");
read_file(f);
mesh.materials.resize(1);
mesh.materials[0].diffuse[0] = 172.0/256;
mesh.materials[0].diffuse[1] = 48.0/256;
mesh.materials[0].diffuse[2] = 72.0/256;
mesh.materials[0].specular[0] = 0.6;
mesh.materials[0].specular[1] = 0.6;
mesh.materials[0].specular[2] = 0.6;
mesh.materials[0].shininess =128;
int i;
for (i = 0; i < nverts; i++)
mesh.geometry.add_vertex(Vec3f(vlist[i]->x, vlist[i]->y, vlist[i]->z));
for (i = 0; i < nfaces; i++) {
for(int j=2;j<flist[i]->nverts;++j)
{
mesh.mat_idx.push_back(0);
Vec3i f_geo(Vec3i(flist[i]->verts[0], flist[i]->verts[1], flist[i]->verts[j]));
mesh.geometry.add_face(f_geo);
}
}
cout << "LOADED " << nverts << " verts " << nfaces << " faces " << endl;
}