write_test() { int i,j; PlyFile *ply; int nelems; char **elist; int file_type; float version; int nverts = sizeof (verts) / sizeof (Vertex); int nfaces = sizeof (faces) / sizeof (Face); /* create the vertex index lists for the faces */ for (i = 0; i < nfaces; i++) faces[i].verts = vert_ptrs[i]; /* open either a binary or ascii PLY file for writing */ /* (the file will be called "test.ply" because the routines */ /* enforce the .ply filename extension) */ #if 1 ply = ply_open_for_writing("test", 2, elem_names, PLY_ASCII, &version); #else ply = ply_open_for_writing("test", 2, elem_names, PLY_BINARY_BE, &version); #endif /* describe what properties go into the vertex and face elements */ ply_element_count (ply, "vertex", nverts); ply_describe_property (ply, "vertex", &vert_props[0]); ply_describe_property (ply, "vertex", &vert_props[1]); ply_describe_property (ply, "vertex", &vert_props[2]); ply_element_count (ply, "face", nfaces); ply_describe_property (ply, "face", &face_props[0]); ply_describe_property (ply, "face", &face_props[1]); /* write a comment and an object information field */ ply_put_comment (ply, "author: Greg Turk"); ply_put_obj_info (ply, "random information"); /* we have described exactly what we will put in the file, so */ /* we are now done with the header info */ ply_header_complete (ply); /* set up and write the vertex elements */ ply_put_element_setup (ply, "vertex"); for (i = 0; i < nverts; i++) ply_put_element (ply, (void *) &verts[i]); /* set up and write the face elements */ ply_put_element_setup (ply, "face"); for (i = 0; i < nfaces; i++) ply_put_element (ply, (void *) &faces[i]); /* close the PLY file */ ply_close (ply); }
void write_file() { int i,j,k; PlyFile *ply; int num_elems; char *elem_name; /*** Write out the final PLY object ***/ ply = ply_write (stdout, nelems, elist, file_type); /* describe what properties go into the vertex and face elements */ ply_element_count (ply, "vertex", nverts); ply_describe_property (ply, "vertex", &vert_props[0]); ply_describe_property (ply, "vertex", &vert_props[1]); ply_describe_property (ply, "vertex", &vert_props[2]); ply_describe_property (ply, "vertex", &vert_props[3]); ply_describe_property (ply, "vertex", &vert_props[4]); ply_describe_property (ply, "vertex", &vert_props[5]); ply_describe_other_properties (ply, vert_other, offsetof(Vertex,other_props)); ply_element_count (ply, "face", nfaces); ply_describe_property (ply, "face", &face_props[0]); ply_describe_other_properties (ply, face_other, offsetof(Face,other_props)); ply_describe_other_elements (ply, other_elements); for (i = 0; i < num_comments; i++) ply_put_comment (ply, comments[i]); for (i = 0; i < num_obj_info; i++) ply_put_obj_info (ply, obj_info[i]); ply_header_complete (ply); /* set up and write the vertex elements */ ply_put_element_setup (ply, "vertex"); for (i = 0; i < nverts; i++) ply_put_element (ply, (void *) vlist[i]); /* set up and write the face elements */ ply_put_element_setup (ply, "face"); for (i = 0; i < nfaces; i++) ply_put_element (ply, (void *) flist[i]); ply_put_other_elements (ply); /* close the PLY file */ ply_close (ply); }
IGL_INLINE bool igl::writePLY( const std::string & filename, const Eigen::PlainObjectBase<DerivedV> & V, const Eigen::PlainObjectBase<DerivedF> & F, const Eigen::PlainObjectBase<DerivedN> & N, const Eigen::PlainObjectBase<DerivedUV> & UV, const bool ascii) { // Largely based on obj2ply.c typedef struct Vertex { double x,y,z,w; /* position */ double nx,ny,nz; /* surface normal */ double s,t; /* texture coordinates */ } Vertex; typedef struct Face { unsigned char nverts; /* number of vertex indices in list */ int *verts; /* vertex index list */ } Face; PlyProperty vert_props[] = { /* list of property information for a vertex */ {"x", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,x), 0, 0, 0, 0}, {"y", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,y), 0, 0, 0, 0}, {"z", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,z), 0, 0, 0, 0}, {"nx", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,nx), 0, 0, 0, 0}, {"ny", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,ny), 0, 0, 0, 0}, {"nz", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,nz), 0, 0, 0, 0}, {"s", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,s), 0, 0, 0, 0}, {"t", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,t), 0, 0, 0, 0}, }; PlyProperty face_props[] = { /* list of property information for a face */ {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)}, }; const bool has_normals = N.rows() > 0; const bool has_texture_coords = UV.rows() > 0; std::vector<Vertex> vlist(V.rows()); std::vector<Face> flist(F.rows()); for(size_t i = 0;i<(size_t)V.rows();i++) { vlist[i].x = V(i,0); vlist[i].y = V(i,1); vlist[i].z = V(i,2); if(has_normals) { vlist[i].nx = N(i,0); vlist[i].ny = N(i,1); vlist[i].nz = N(i,2); } if(has_texture_coords) { vlist[i].s = UV(i,0); vlist[i].t = UV(i,1); } } for(size_t i = 0;i<(size_t)F.rows();i++) { flist[i].nverts = F.cols(); flist[i].verts = new int[F.cols()]; for(size_t c = 0;c<(size_t)F.cols();c++) { flist[i].verts[c] = F(i,c); } } const char * elem_names[] = {"vertex","face"}; FILE * fp = fopen(filename.c_str(),"w"); if(fp==NULL) { return false; } PlyFile * ply = ply_write(fp, 2,elem_names, (ascii ? PLY_ASCII : PLY_BINARY_LE)); if(ply==NULL) { return false; } std::vector<PlyProperty> plist; plist.push_back(vert_props[0]); plist.push_back(vert_props[1]); plist.push_back(vert_props[2]); if (has_normals) { plist.push_back(vert_props[3]); plist.push_back(vert_props[4]); plist.push_back(vert_props[5]); } if (has_texture_coords) { plist.push_back(vert_props[6]); plist.push_back(vert_props[7]); } ply_describe_element(ply, "vertex", V.rows(),plist.size(), &plist[0]); ply_describe_element(ply, "face", F.rows(),1,&face_props[0]); ply_header_complete(ply); int native_binary_type = get_native_binary_type2(); ply_put_element_setup(ply, "vertex"); for(const auto v : vlist) { ply_put_element(ply, (void *) &v, &native_binary_type); } ply_put_element_setup(ply, "face"); for(const auto f : flist) { ply_put_element(ply, (void *) &f, &native_binary_type); } ply_close(ply); for(size_t i = 0;i<(size_t)F.rows();i++) { delete[] flist[i].verts; } return true; }