Exemplo n.º 1
0
/* 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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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;
}