/* given a format mode, an input file name and an output file name, * convert input file to output in given format mode */ int main(int argc, char **argv) { const char *value = NULL; e_ply_storage_mode storage_mode = PLY_LITTLE_ENDIAN; const char *iname = NULL, *oname = NULL; p_ply iply = NULL, oply = NULL; /* parse command line arguments */ parse_arguments(argc, argv, &storage_mode, &iname, &oname); /* open input file and make sure we parsed its header */ iply = ply_open(iname, NULL, 0, NULL); if (!iply) error("Unable to open file '%s'", iname); if (!ply_read_header(iply)) error("Failed reading '%s' header", iname); /* create output file */ oply = ply_create(oname, storage_mode, NULL, 0, NULL); if (!oply) error("Unable to create file '%s'", oname); /* create elements and properties in output file and * setup callbacks for them in input file */ setup_callbacks(iply, oply); /* pass comments and obj_infos from input to output */ value = NULL; while ((value = ply_get_next_comment(iply, value))) if (!ply_add_comment(oply, value)) error("Failed adding comments"); value = NULL; while ((value = ply_get_next_obj_info(iply, value))) if (!ply_add_obj_info(oply, value)) error("Failed adding comments"); /* write output header */ if (!ply_write_header(oply)) error("Failed writing '%s' header", oname); /* read input file generating callbacks that pass data to output file */ if (!ply_read(iply)) error("Conversion failed"); /* close up, we are done */ if (!ply_close(iply)) error("Error closing file '%s'", iname); if (!ply_close(oply)) error("Error closing file '%s'", oname); return 0; }
int main(int argc, char **argv) { const char *value; p_ply iply, oply; iply = ply_open("input.ply", NULL); if (!iply) return 1; if (!ply_read_header(iply)) return 1; oply = ply_create("output.ply", PLY_LITTLE_ENDIAN, NULL); if (!oply) return 1; if (!setup_callbacks(iply, oply)) return 1; /* pass comments and obj_infos from input to output */ value = NULL; while ((value = ply_get_next_comment(iply, value))) if (!ply_add_comment(oply, value)) return 1; value = NULL; while ((value = ply_get_next_obj_info(iply, value))) if (!ply_add_obj_info(oply, value)) return 1;; /* write output header */ if (!ply_write_header(oply)) return 1; /* read input file generating callbacks that pass data to output file */ if (!ply_read(iply)) return 1; /* close up, we are done */ if (!ply_close(iply)) return 1; if (!ply_close(oply)) return 1; return 0; }
bool loadPlyFile(const QString& fileName, PlyLoadInfo& info) { // Read a triangulation from a .ply file std::unique_ptr<t_ply_, int(*)(p_ply)> ply( ply_open(fileName.toUtf8().constData(), logRplyError, 0, NULL), ply_close); if (!ply || !ply_read_header(ply.get())) { g_logger.error("Could not open ply or read header"); return false; } long nvertices = ply_set_read_cb(ply.get(), "vertex", "x", vertex_cb, &info, 0); if (ply_set_read_cb(ply.get(), "vertex", "y", vertex_cb, &info, 1) != nvertices || ply_set_read_cb(ply.get(), "vertex", "z", vertex_cb, &info, 2) != nvertices) { g_logger.error("Expected vertex properties (x,y,z) in ply file"); return false; } info.nvertices = nvertices; info.currPoly.setVertexCount(nvertices); info.verts.reserve(3*nvertices); long ncolors = ply_set_read_cb(ply.get(), "color", "r", color_cb, &info, 0); if (ncolors != 0) { ply_set_read_cb(ply.get(), "color", "g", color_cb, &info, 1); ply_set_read_cb(ply.get(), "color", "b", color_cb, &info, 2); info.colors.reserve(3*nvertices); } if (ncolors == 0) { ncolors = ply_set_read_cb(ply.get(), "vertex", "r", color_cb, &info, 0); if (ncolors != 0) { ply_set_read_cb(ply.get(), "vertex", "g", color_cb, &info, 1); ply_set_read_cb(ply.get(), "vertex", "b", color_cb, &info, 2); info.colors.reserve(3*nvertices); } } long ntexcoords = ply_set_read_cb(ply.get(), "vertex", "u", texcoord_cb, &info, 0); if (ntexcoords != 0) { if (ply_set_read_cb(ply.get(), "vertex", "v", texcoord_cb, &info, 1) == ntexcoords) info.texcoords.reserve(2*nvertices); else ntexcoords = 0; } const char* cmt = NULL; while (true) { cmt = ply_get_next_comment(ply.get(), cmt); if (!cmt) break; QList<QString> tokens = QString(cmt).split(" "); if (tokens[0] == "TextureFile" && tokens.size() > 1) { QDir d = QFileInfo(fileName).dir(); info.textureFileName = d.absoluteFilePath(tokens[1]); } } long nfaces = 0; long nedges = 0; // Attach callbacks for faces. Try both face.vertex_index and // face.vertex_indices since there doesn't seem to be a real standard. nfaces += ply_set_read_cb(ply.get(), "face", "vertex_index", face_cb, &info, PolygonBuilder::OuterRingInds); nfaces += ply_set_read_cb(ply.get(), "face", "vertex_indices", face_cb, &info, PolygonBuilder::OuterRingInds); // Attach callbacks for polygons with holes. // This isn't a standard at all, it's something I just made up :-/ long npolygons = 0; npolygons += ply_set_read_cb(ply.get(), "polygon", "vertex_index", face_cb, &info, PolygonBuilder::OuterRingInds); npolygons += ply_set_read_cb(ply.get(), "polygon", "outer_vertex_index", face_cb, &info, PolygonBuilder::OuterRingInds); // DEPRECATED nfaces += npolygons; if (npolygons > 0) { // Holes if (ply_set_read_cb(ply.get(), "polygon", "inner_vertex_counts", face_cb, &info, PolygonBuilder::InnerRingSizes)) { if (!ply_set_read_cb(ply.get(), "polygon", "inner_vertex_index", face_cb, &info, PolygonBuilder::InnerRingInds)) { g_logger.error("Found ply property polygon.inner_vertex_counts " "without polygon.inner_vertex_index"); return false; } info.currPoly.setPropertiesAvailable(PolygonBuilder::OuterRingInds | PolygonBuilder::InnerRingSizes | PolygonBuilder::InnerRingInds); } } // Attach callbacks for edges. AFAIK this isn't really a standard, I'm // just copying the semi-standard people use for faces. nedges += ply_set_read_cb(ply.get(), "edge", "vertex_index", edge_cb, &info, 0); nedges += ply_set_read_cb(ply.get(), "edge", "vertex_indices", edge_cb, &info, 0); if (nedges <= 0 && nfaces <= 0) { g_logger.error("Expected more than zero edges or faces in ply file"); return false; } if (!ply_read(ply.get())) { g_logger.error("Error reading ply file data section"); return false; } info.postprocess(); if (info.colors.size() != info.verts.size()) info.colors.clear(); return true; }