// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2014 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "readPLY.h" #include "list_to_matrix.h" #include "ply.h" #include template < typename Vtype, typename Ftype, typename Ntype, typename UVtype> IGL_INLINE bool igl::readPLY( const std::string & filename, std::vector > & V, std::vector > & F, std::vector > & N, std::vector > & UV) { using namespace std; // Largely follows ply2iv.c typedef struct Vertex { double x,y,z; /* position */ double nx,ny,nz; /* surface normal */ double s,t; /* texture coordinates */ void *other_props; /* other properties */ } Vertex; typedef struct Face { unsigned char nverts; /* number of vertex indices in list */ int *verts; /* vertex index list */ void *other_props; /* other properties */ } 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)}, }; FILE * fp = fopen(filename.c_str(),"r"); if(fp == NULL) { return false; } int nelems; char ** elem_names; PlyFile * in_ply = ply_read(fp,&nelems,&elem_names); if(in_ply==NULL) { return false; } bool has_normals = false; bool has_texture_coords = false; PlyProperty **plist; int nprops; int elem_count; plist = ply_get_element_description (in_ply,"vertex", &elem_count, &nprops); if (plist != NULL) { /* set up for getting vertex elements */ ply_get_property (in_ply,"vertex",&vert_props[0]); ply_get_property (in_ply,"vertex",&vert_props[1]); ply_get_property (in_ply,"vertex",&vert_props[2]); for (int j = 0; j < nprops; j++) { PlyProperty * prop = plist[j]; if (equal_strings ("nx", prop->name) || equal_strings ("ny", prop->name) || equal_strings ("nz", prop->name)) { ply_get_property (in_ply,"vertex",&vert_props[3]); ply_get_property (in_ply,"vertex",&vert_props[4]); ply_get_property (in_ply,"vertex",&vert_props[5]); has_normals = true; } if (equal_strings ("s", prop->name) || equal_strings ("t", prop->name)) { ply_get_property(in_ply,"vertex",&vert_props[6]); ply_get_property(in_ply,"vertex",&vert_props[7]); has_texture_coords = true; } } // Is this call necessary? ply_get_other_properties(in_ply,"vertex", offsetof(Vertex,other_props)); V.resize(elem_count,std::vector(3)); if(has_normals) { N.resize(elem_count,std::vector(3)); }else { N.resize(0); } if(has_texture_coords) { UV.resize(elem_count,std::vector(2)); }else { UV.resize(0); } for(int j = 0;j IGL_INLINE bool igl::readPLY( const std::string & filename, Eigen::PlainObjectBase & V, Eigen::PlainObjectBase & F, Eigen::PlainObjectBase & N, Eigen::PlainObjectBase & UV) { std::vector > vV; std::vector > vF; std::vector > vN; std::vector > vUV; if(!readPLY(filename,vV,vF,vN,vUV)) { return false; } return list_to_matrix(vV,V) && list_to_matrix(vF,F) && list_to_matrix(vN,N) && list_to_matrix(vUV,UV); } template < typename DerivedV, typename DerivedF> IGL_INLINE bool igl::readPLY( const std::string & filename, Eigen::PlainObjectBase & V, Eigen::PlainObjectBase & F) { Eigen::MatrixXd N,UV; return readPLY(filename,V,F,N,UV); } #ifdef IGL_STATIC_LIBRARY // Explicit template specialization template bool igl::readPLY(std::basic_string, std::allocator > const&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&); #endif