Subversion Repositories gelsvn

Rev

Rev 341 | Go to most recent revision | 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 <string.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;

}