DeformModel::DeformModel(const std::string &fname, unsigned int num_frame, float ply_scale) { Init(); // char ply_fname[256]; _num_frame = num_frame; for (unsigned int cur_f = 0; cur_f < _num_frame; cur_f++) { std::stringstream ply_fname; ply_fname << fname << cur_f << ".ply"; // sprintf(ply_fname, "%s%d.ply", fname, cur_f); std::cout << "Opening " << ply_fname.str() << std::endl; FILE *fp = fopen(ply_fname.str().c_str(), "rb"); assert(fp); // PLY object: PlyFile *ply; // PLY properties: char **elist; int nelems; // hand over the stream to the ply functions: ply = ply_read(fp, &nelems, &elist); assert(ply); int file_type; float version; ply_get_info(ply, &version, &file_type); for (int i=0; i<nelems; i++) { char *elem_name = elist[i]; int num_elems, nprops; PlyProperty **plist = ply_get_element_description(ply, elem_name, &num_elems, &nprops); bool has_vertex_x = false, has_vertex_y = false, has_vertex_z = false, has_colors = false; unsigned char color_components = 0; // this is a vertex: if (equal_strings ("vertex", elem_name)) { for (int j=0; j<nprops; j++) { if (equal_strings("x", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[0]); /* x */ has_vertex_x = true; } else if (equal_strings("y", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[1]); /* y */ has_vertex_y = true; } else if (equal_strings("z", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[2]); /* z */ has_vertex_z = true; } else if (equal_strings("red", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[3]); /* z */ color_components++; } else if (equal_strings("green", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[4]); /* z */ color_components++; } else if (equal_strings("blue", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[5]); /* z */ color_components++; } } has_colors = color_components == 3; // test for necessary properties if ((!has_vertex_x) || (!has_vertex_y) || (!has_vertex_z)) { logger->update("Warning: Vertex with less than 3 coordinated detected. Output will most likely be corrupt!"); continue; } // must be first frame, initialize structures: if (_num_vtx == 0) { _num_vtx = num_elems; _vtxs = new vec3f[_num_vtx*_num_frame]; _cur_vtxs = new vec3f[_num_vtx]; _prev_vtxs = new vec3f[_num_vtx]; _vtx_boxes = new BOX[_num_vtx]; _nrms = new vec3f[_num_vtx]; _vtx_fids = new id_list[_num_vtx]; cout << "Vtx # = " << _num_vtx << endl; if (has_colors) _colors = new color3[_num_vtx]; } // grab all the vertex elements PLYVertex plyNewVertex; for (int j=0; j<num_elems; j++) { ply_get_element(ply, (void *)&plyNewVertex); if (has_colors && cur_f == 0) { _colors[j].set(plyNewVertex.color); } _vtxs[cur_f*_num_vtx+j] = vec3f(plyNewVertex.coords) * ply_scale; if (cur_f == 0) { _prev_vtxs[j] = _cur_vtxs[j] = _vtxs[j]; } if (j != 0 && j%1000000 == 0) { cout << " - " << j << " of " << num_elems << " loaded." << endl; } } } // this is a face (and, hopefully, a triangle): else if (equal_strings ("face", elem_name) && _tris == NULL) { // I need this for..., otherwise error ... for (int j=0; j<nprops; j++) { if (equal_strings("vertex_indices", plist[j]->name)) { ply_get_property (ply, elem_name, &face_props[0]); /* vertex_indices */ } } /* grab all the face elements */ PLYFace plyFace; plyFace.other_props = NULL; list<edge2f> edgelist_temp; vector<tri3f> trilist_temp; for (int j = 0; j < num_elems; j++) { ply_get_element(ply, (void *)&plyFace); for (int fi = 0; fi < plyFace.nverts-2; fi++) { // // make a triangle in our format from PLY face + vertices // // copy vertex indices unsigned int id0, id1, id2; id0 = plyFace.verts[0]; id1 = plyFace.verts[fi+1]; id2 = plyFace.verts[fi+2]; tri3f tri(id0, id1, id2); // insert triangle into list trilist_temp.push_back(tri); unsigned int fid = (unsigned int)trilist_temp.size()-1; edgelist_temp.push_back(edge2f(id0, id1, fid)); edgelist_temp.push_back(edge2f(id1, id2, fid)); edgelist_temp.push_back(edge2f(id2, id0, fid)); } free(plyFace.verts); if (j != 0 && j%500000 == 0) { cout << " - " << j << " of " << num_elems << " loaded." << endl; } } edgelist_temp.sort(); list<edge2f> edge_unqie; for (list<edge2f>::iterator it=edgelist_temp.begin(); it!=edgelist_temp.end(); it++) { if (!edge_unqie.empty() && *it == edge_unqie.back()) { // find duplicated with other fid unsigned int fid = (*it).fid(0); assert(fid != -1); edge_unqie.back().set_fid2(fid); } else edge_unqie.push_back(*it); } edgelist_temp.clear(); vector<edge2f> edge_array; _num_edge = (unsigned int)edge_unqie.size(); _edges = new edge2f[_num_edge]; _edg_boxes = new BOX[_num_edge]; unsigned int t=0; for (list<edge2f>::iterator it=edge_unqie.begin(); it != edge_unqie.end(); it++) { _edges[t++] = *it; edge_array.push_back(*it); } // copy over temp list to static array _num_tri = (unsigned int)trilist_temp.size(); cout << "Allocating " << _num_tri*sizeof(tri3f) << " bytes of storage for triangles." << endl; _tris = new tri3f[_num_tri]; _tri_nrms = new vec3f[_num_tri]; _old_tri_nrms = NULL; _tri_edges = new tri3e[_num_tri]; _fac_boxes = new BOX[_num_tri]; _tri_flags = new char[_num_tri]; vector <edge2f>::iterator first = edge_array.begin(); vector <edge2f>::iterator last = edge_array.end(); for (t = 0; t < _num_tri; t++) { _tris[t] = trilist_temp[t]; vector <edge2f>::iterator it1 = lower_bound(first, last, edge2f(_tris[t].id0(), _tris[t].id1(), 0)); vector <edge2f>::iterator it2 = lower_bound(first, last, edge2f(_tris[t].id1(), _tris[t].id2(), 0)); vector <edge2f>::iterator it3 = lower_bound(first, last, edge2f(_tris[t].id2(), _tris[t].id0(), 0)); _tri_edges[t].set(it1-first, it2-first, it3-first); } cout << "Edge # = " << _num_edge << endl; cout << "Tri # = " << _num_tri << endl; } else // otherwise: skip all further NULL; } // PLY parsing ended, clean up vertex buffer and close the file // fclose(fp); ply_close(ply); } UpdateTriNorm(); for (unsigned t = 0; t < _num_tri; t++) for (int i=0; i<3; i++) { unsigned int vid = _tris[t].id(i); _vtx_fids[vid].push_back(t); } BufferAdjacent(); }
void read_file(FILE *inFile) { int i,j,k; PlyFile *ply; int nprops; int num_elems; PlyProperty **plist; char *elem_name; float version; int get_nx,get_ny,get_nz; /*** Read in the original PLY object ***/ ply = ply_read (inFile, &nelems, &elist); ply_get_info (ply, &version, &file_type); for (i = 0; i < nelems; i++) { /* get the description of the first element */ elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); if (equal_strings ("vertex", elem_name)) { /* see if vertex holds any normal information */ get_nx = get_ny = get_nz = 0; for (j = 0; j < nprops; j++) { if (equal_strings ("nx", plist[j]->name)) get_nx = 1; if (equal_strings ("ny", plist[j]->name)) get_ny = 1; if (equal_strings ("nz", plist[j]->name)) get_nz = 1; } /* create a vertex list to hold all the vertices */ vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems); nverts = num_elems; /* set up for getting vertex elements */ ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); if (get_nx) ply_get_property (ply, elem_name, &vert_props[3]); if (get_ny) ply_get_property (ply, elem_name, &vert_props[4]); if (get_nz) ply_get_property (ply, elem_name, &vert_props[5]); vert_other = ply_get_other_properties (ply, elem_name, offsetof(Vertex,other_props)); /* grab all the vertex elements */ for (j = 0; j < num_elems; j++) { vlist[j] = (Vertex *) malloc (sizeof (Vertex)); ply_get_element (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 *) * num_elems); nfaces = num_elems; /* set up for getting face elements */ ply_get_property (ply, elem_name, &face_props[0]); face_other = ply_get_other_properties (ply, elem_name, offsetof(Face,other_props)); /* grab all the face elements */ for (j = 0; j < num_elems; j++) { flist[j] = (Face *) malloc (sizeof (Face)); ply_get_element (ply, (void *) flist[j]); } } else other_elements = ply_get_other_element (ply, elem_name, num_elems); } comments = ply_get_comments (ply, &num_comments); obj_info = ply_get_obj_info (ply, &num_obj_info); ply_close (ply); }
void ReadFile( MFIList *mfi, Model *model ) { int i,j; PlyFile *ply; int nprops; int num_elems; PlyProperty **plist; char *elem_name; float version; FILE *fp; if ((fp = fopen(mfi->file_info.path, "rb")) == NULL) { crError( "Can't open %s for reading!", mfi->file_info.path ); } ply = ply_read (fp, &nelems, &elist); ply_get_info (ply, &version, &file_type); for (i = 0; i < nelems; i++) { /* get the description of the first element */ elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); if (equal_strings ("vertex", elem_name)) { /* see if vertex holds any normal information */ globals.has_nx = globals.has_ny = globals.has_nz = 0; globals.has_r = globals.has_g = globals.has_b = 0; for (j = 0; j < nprops; j++) { if (equal_strings ("nx", plist[j]->name)) globals.has_nx = 1; if (equal_strings ("ny", plist[j]->name)) globals.has_ny = 1; if (equal_strings ("nz", plist[j]->name)) globals.has_nz = 1; if (equal_strings ("red", plist[j]->name)) globals.has_r = 1; if (equal_strings ("green", plist[j]->name)) globals.has_g = 1; if (equal_strings ("blue", plist[j]->name)) globals.has_b = 1; } /* create a vertex list to hold all the vertices */ model->vlist = (Vertex *) crAlloc (sizeof (*(model->vlist)) * num_elems); model->nverts = num_elems; /* set up for getting vertex elements */ ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); if (globals.has_r) ply_get_property (ply, elem_name, &vert_props[3]); if (globals.has_g) ply_get_property (ply, elem_name, &vert_props[4]); if (globals.has_b) ply_get_property (ply, elem_name, &vert_props[5]); if (globals.has_nx) ply_get_property (ply, elem_name, &vert_props[6]); if (globals.has_ny) ply_get_property (ply, elem_name, &vert_props[7]); if (globals.has_nz) ply_get_property (ply, elem_name, &vert_props[8]); /* grab all the vertex elements */ for (j = 0; j < num_elems; j++) { model->vlist[j].r = 1.0f; model->vlist[j].g = 1.0f; model->vlist[j].b = 1.0f; model->vlist[j].nx = 1.0f; model->vlist[j].ny = 1.0f; model->vlist[j].nz = 1.0f; ply_get_element (ply, model->vlist+j); model->vlist[j].r /= 255.0f; model->vlist[j].g /= 255.0f; model->vlist[j].b /= 255.0f; } } else if (equal_strings ("face", elem_name)) { /* create a list to hold all the face elements */ model->flist = (Face *) crAlloc (sizeof (*(model->flist)) * num_elems); model->nfaces = num_elems; /* set up for getting face elements */ ply_get_property (ply, elem_name, &face_props[0]); /* grab all the face elements */ crDebug( "Reading %s (%d faces)", mfi->file_info.path, model->nfaces ); model->faces = (unsigned int *) crAlloc( model->nfaces * 3 * sizeof( *(model->faces) ) ); for (j = 0; j < num_elems; j++) { ply_get_element (ply, model->flist + j); model->faces[j*3+0] = model->flist[j].verts[0]; model->faces[j*3+1] = model->flist[j].verts[1]; model->faces[j*3+2] = model->flist[j].verts[2]; } } } ply_close (ply); }