Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ply2sm.C

Go to the documentation of this file.
00001 /*****************************************************************
00002 
00003   Convert a PLY file to a jot .sm file.
00004 
00005   Modified from ply2iv.c in Greg Turk's PLY 1-1 code:
00006     ftp://graphics.stanford.edu/pub/zippack/ply-1.1.tar.Z
00007 
00008   -------------------------------------------------------
00009 
00010   Copyright (c) 1998 Georgia Institute of Technology.
00011   All rights reserved.
00012 
00013   Permission to use, copy, modify and distribute this software and its   
00014   documentation for any purpose is hereby granted without fee, provided   
00015   that the above copyright notice and this permission notice appear in   
00016   all copies of this software and that you do not sell the software.   
00017 
00018   THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,   
00019   EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY   
00020   WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   
00021 
00022  *****************************************************************/
00023 
00024 #include "mesh/lmesh.H"
00025 #include "std/config.H"
00026 
00027 #include "ply.H"
00028 
00029 static bool debug = Config::get_var_bool("DEBUG_PLY2SM",false,true);
00030 
00031 /* vertex and face definitions for a polygonal object */
00032 
00033 typedef struct Vertex {
00034    float x,y,z;
00035    float r,g,b;
00036    float nx,ny,nz;
00037    void *other_props;       /* other properties */
00038 } Vertex;
00039 
00040 typedef struct Face {
00041    unsigned char nverts;    /* number of vertex indices in list */
00042    int *verts;              /* vertex index list */
00043    void *other_props;       /* other properties */
00044 } Face;
00045 
00046 char *elem_names[] = { /* list of the elements in the object */
00047    "vertex", "face"
00048 };
00049 
00050 PlyProperty vert_props[] = { /* list of property information for a vertex */
00051    {"x", Float32, Float32, offsetof(Vertex,x), 0, 0, 0, 0},
00052    {"y", Float32, Float32, offsetof(Vertex,y), 0, 0, 0, 0},
00053    {"z", Float32, Float32, offsetof(Vertex,z), 0, 0, 0, 0},
00054    {"r", Float32, Float32, offsetof(Vertex,r), 0, 0, 0, 0},
00055    {"g", Float32, Float32, offsetof(Vertex,g), 0, 0, 0, 0},
00056    {"b", Float32, Float32, offsetof(Vertex,b), 0, 0, 0, 0},
00057    {"nx", Float32, Float32, offsetof(Vertex,nx), 0, 0, 0, 0},
00058    {"ny", Float32, Float32, offsetof(Vertex,ny), 0, 0, 0, 0},
00059    {"nz", Float32, Float32, offsetof(Vertex,nz), 0, 0, 0, 0},
00060 };
00061 
00062 PlyProperty face_props[] = { /* list of property information for a face */
00063    {"vertex_indices", Int32, Int32, offsetof(Face,verts),
00064     1, Uint8, Uint8, offsetof(Face,nverts)},
00065 };
00066 
00067 
00068 /*** the PLY object ***/
00069 
00070 static int nverts=0,nfaces=0;
00071 static Vertex **vlist=0;
00072 static Face **flist=0;
00073 
00074 static PlyOtherProp *vert_other=0,*face_other=0;
00075 
00076 static int per_vertex_color = 0;
00077 static int has_normals = 0;
00078 
00079 
00080 /******************************************************************************
00081 Print out usage information.
00082 ******************************************************************************/
00083 void
00084 usage(char *progname)
00085 {
00086    err_msg("usage: %s [flags] < in.ply > out.sm", progname);
00087 }
00088 
00089 
00090 /******************************************************************************
00091 Read in the PLY file from standard in.
00092 ******************************************************************************/
00093 void
00094 read_file()
00095 {
00096    /*** Read in the original PLY object ***/
00097 
00098    PlyFile *in_ply = read_ply (stdin);
00099 
00100    for (int i = 0; i < in_ply->num_elem_types; i++) {
00101 
00102       /* prepare to read the i'th list of elements */
00103       int elem_count=0;
00104       char *elem_name = setup_element_read_ply (in_ply, i, &elem_count);
00105 
00106       err_adv(debug, "%s: %d elements", elem_name, elem_count);
00107 
00108       if (equal_strings ("vertex", elem_name)) {
00109 
00110          /* create a vertex list to hold all the vertices */
00111          vlist = (Vertex **) malloc (sizeof (Vertex *) * elem_count);
00112          nverts = elem_count;
00113 
00114          /* set up for getting vertex elements */
00115 
00116          setup_property_ply (in_ply, &vert_props[0]);
00117          setup_property_ply (in_ply, &vert_props[1]);
00118          setup_property_ply (in_ply, &vert_props[2]);
00119 
00120          int j;
00121          for (j = 0; j < in_ply->elems[i]->nprops; j++) {
00122             PlyProperty *prop;
00123             prop = in_ply->elems[i]->props[j];
00124             if (equal_strings ("r", prop->name)) {
00125                setup_property_ply (in_ply, &vert_props[3]);
00126                per_vertex_color = 1;
00127             }
00128             if (equal_strings ("g", prop->name)) {
00129                setup_property_ply (in_ply, &vert_props[4]);
00130                per_vertex_color = 1;
00131             }
00132             if (equal_strings ("b", prop->name)) {
00133                setup_property_ply (in_ply, &vert_props[5]);
00134                per_vertex_color = 1;
00135             }
00136             if (equal_strings ("nx", prop->name)) {
00137                setup_property_ply (in_ply, &vert_props[6]);
00138                has_normals = 1;
00139             }
00140             if (equal_strings ("ny", prop->name)) {
00141                setup_property_ply (in_ply, &vert_props[7]);
00142                has_normals = 1;
00143             }
00144             if (equal_strings ("nz", prop->name)) {
00145                setup_property_ply (in_ply, &vert_props[8]);
00146                has_normals = 1;
00147             }
00148          }
00149 
00150          vert_other = get_other_properties_ply (in_ply, 
00151                                                 offsetof(Vertex,other_props));
00152 
00153          /* grab all the vertex elements */
00154          for (j = 0; j < elem_count; j++) {
00155             vlist[j] = (Vertex *) malloc (sizeof (Vertex));
00156             vlist[j]->r = 1;
00157             vlist[j]->g = 1;
00158             vlist[j]->b = 1;
00159             get_element_ply (in_ply, (void *) vlist[j]);
00160          }
00161       }
00162       else if (equal_strings ("face", elem_name)) {
00163 
00164          /* create a list to hold all the face elements */
00165          flist = (Face **) malloc (sizeof (Face *) * elem_count);
00166          nfaces = elem_count;
00167 
00168          /* set up for getting face elements */
00169 
00170          setup_property_ply (in_ply, &face_props[0]);
00171          face_other = get_other_properties_ply (in_ply, 
00172                                                 offsetof(Face,other_props));
00173 
00174          /* grab all the face elements */
00175          for (int j = 0; j < elem_count; j++) {
00176             flist[j] = (Face *) malloc (sizeof (Face));
00177             get_element_ply (in_ply, (void *) flist[j]);
00178          }
00179       }
00180       else
00181          get_other_element_ply (in_ply);
00182    }
00183 
00184    close_ply (in_ply);
00185    free_ply (in_ply);
00186 }
00187 
00188 
00189 inline void
00190 add_face(LMESHptr& mesh, Face* f)
00191 {
00192    assert(mesh && f);
00193    switch (f->nverts) {
00194     case 3:     // triangle
00195       mesh->add_face(f->verts[2], f->verts[1], f->verts[0]);
00196       break;
00197     case 4:     // quad
00198       mesh->add_quad(f->verts[3], f->verts[2], f->verts[1], f->verts[0]);
00199       break;
00200     default:    // other
00201       // XXX - should fix this to convert to triangles
00202       err_msg("ply2sm: can't add face: %d-gon", f->nverts);
00203    }
00204 }
00205 
00206 /******************************************************************************
00207 Write out a jot .sm file.
00208 ******************************************************************************/
00209 void
00210 write_sm()
00211 {
00212    LMESHptr mesh = new LMESH;
00213    
00214    int i=0;
00215 
00216    //******** Build the mesh ********
00217 
00218    err_adv(debug, "read ply file: %d vertices, %d faces\n", nverts, nfaces);
00219 
00220    err_adv(debug, "building mesh:");
00221 
00222    // Add vertices to mesh
00223    err_adv(debug, "  adding vertices...");
00224    for (i = 0; i < nverts; i++)
00225       mesh->add_vertex(Wpt(vlist[i]->x, vlist[i]->y, vlist[i]->z));
00226    err_adv(debug, "  done\n");
00227 
00228    // Add per-vertex colors if needed
00229    if (per_vertex_color) {
00230       err_adv(debug, "  adding colors...");
00231       for (i = 0; i < nverts; i++)
00232          mesh->bv(i)->set_color(COLOR(vlist[i]->r, vlist[i]->g, vlist[i]->b));
00233       err_adv(debug, "  done\n");
00234    }
00235 
00236    // Add faces
00237    err_adv(debug, "  adding faces...");
00238    for (i = 0; i < nfaces; i++)
00239       add_face(mesh, flist[i]);
00240    err_adv(debug, "  done\n");
00241 
00242    //******** Filter the mesh ********
00243 
00244    err_adv(debug, "filtering mesh...");
00245 
00246    // Remove any isolated vertices
00247    for (i=mesh->nverts()-1; i>=0; i--) {
00248       if (mesh->bv(i)->degree() == 0) {
00249          mesh->remove_vertex(mesh->bv(i));
00250       }
00251    }
00252    mesh->changed();
00253 
00254    // Remove duplicate vertices while we're at it
00255    mesh->remove_duplicate_vertices(false); // don't keep the bastards
00256 
00257    // Check for consistent orientation of normals
00258    bool is_bad = false;
00259    for (i=0; i<mesh->nedges(); i++)
00260       if (!mesh->be(i)->consistent_orientation())
00261          is_bad = true;
00262    if (is_bad)
00263       err_msg("Warning: inconsistently oriented triangles -- can't fix");
00264 
00265    // Optional: recenter mesh
00266    if (Config::get_var_bool("JOT_RECENTER"))
00267       mesh->recenter();
00268 
00269    // Optional: print stats
00270    if (Config::get_var_bool("JOT_PRINT_MESH"))
00271       mesh->print();
00272 
00273    err_adv(debug, "done\n");
00274 
00275    //******** Write mesh ********
00276 
00277    err_adv(debug, "writing mesh...");
00278    mesh->write_stream(cout);
00279    err_adv(debug, "done\n");
00280 }
00281 
00282 /******************************************************************************
00283 Main program.
00284 ******************************************************************************/
00285 int
00286 main(int argc, char *argv[])
00287 {
00288    char *s;
00289    char *progname;
00290 
00291    progname = argv[0];
00292 
00293    while (--argc > 0 && (*++argv)[0]=='-') {
00294       for (s = argv[0]+1; *s; s++)
00295          switch (*s) {
00296           default:
00297             usage (progname);
00298             exit (-1);
00299             break;
00300          }
00301    }
00302 
00303    err_adv(debug, "reading ply file...");
00304    read_file();
00305    err_adv(debug, "done\n");
00306 
00307    write_sm();
00308 
00309    return 0;
00310 }
00311 
00312 // end of file ply2sm.C

Generated on Mon Sep 18 11:39:32 2006 for jot by  doxygen 1.4.4