00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00032
00033 typedef struct Vertex {
00034 float x,y,z;
00035 float r,g,b;
00036 float nx,ny,nz;
00037 void *other_props;
00038 } Vertex;
00039
00040 typedef struct Face {
00041 unsigned char nverts;
00042 int *verts;
00043 void *other_props;
00044 } Face;
00045
00046 char *elem_names[] = {
00047 "vertex", "face"
00048 };
00049
00050 PlyProperty vert_props[] = {
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[] = {
00063 {"vertex_indices", Int32, Int32, offsetof(Face,verts),
00064 1, Uint8, Uint8, offsetof(Face,nverts)},
00065 };
00066
00067
00068
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
00082
00083 void
00084 usage(char *progname)
00085 {
00086 err_msg("usage: %s [flags] < in.ply > out.sm", progname);
00087 }
00088
00089
00090
00091
00092
00093 void
00094 read_file()
00095 {
00096
00097
00098 PlyFile *in_ply = read_ply (stdin);
00099
00100 for (int i = 0; i < in_ply->num_elem_types; i++) {
00101
00102
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
00111 vlist = (Vertex **) malloc (sizeof (Vertex *) * elem_count);
00112 nverts = elem_count;
00113
00114
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
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
00165 flist = (Face **) malloc (sizeof (Face *) * elem_count);
00166 nfaces = elem_count;
00167
00168
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
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:
00195 mesh->add_face(f->verts[2], f->verts[1], f->verts[0]);
00196 break;
00197 case 4:
00198 mesh->add_quad(f->verts[3], f->verts[2], f->verts[1], f->verts[0]);
00199 break;
00200 default:
00201
00202 err_msg("ply2sm: can't add face: %d-gon", f->nverts);
00203 }
00204 }
00205
00206
00207
00208
00209 void
00210 write_sm()
00211 {
00212 LMESHptr mesh = new LMESH;
00213
00214 int i=0;
00215
00216
00217
00218 err_adv(debug, "read ply file: %d vertices, %d faces\n", nverts, nfaces);
00219
00220 err_adv(debug, "building mesh:");
00221
00222
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
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
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
00243
00244 err_adv(debug, "filtering mesh...");
00245
00246
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
00255 mesh->remove_duplicate_vertices(false);
00256
00257
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
00266 if (Config::get_var_bool("JOT_RECENTER"))
00267 mesh->recenter();
00268
00269
00270 if (Config::get_var_bool("JOT_PRINT_MESH"))
00271 mesh->print();
00272
00273 err_adv(debug, "done\n");
00274
00275
00276
00277 err_adv(debug, "writing mesh...");
00278 mesh->write_stream(cout);
00279 err_adv(debug, "done\n");
00280 }
00281
00282
00283
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