123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- // This file is part of libigl, a simple c++ geometry processing library.
- //
- // Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
- //
- // 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 <iostream>
- template <
- typename Vtype,
- typename Ftype,
- typename Ntype,
- typename UVtype>
- IGL_INLINE bool igl::readPLY(
- const std::string & filename,
- std::vector<std::vector<Vtype> > & V,
- std::vector<std::vector<Ftype> > & F,
- std::vector<std::vector<Ntype> > & N,
- std::vector<std::vector<UVtype> > & 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<Vtype>(3));
- if(has_normals)
- {
- N.resize(elem_count,std::vector<Ntype>(3));
- }else
- {
- N.resize(0);
- }
- if(has_texture_coords)
- {
- UV.resize(elem_count,std::vector<UVtype>(2));
- }else
- {
- UV.resize(0);
- }
- for(int j = 0;j<elem_count;j++)
- {
- Vertex v;
- ply_get_element_setup(in_ply,"vertex",3,vert_props);
- ply_get_element(in_ply,(void*)&v);
- V[j][0] = v.x;
- V[j][1] = v.y;
- V[j][2] = v.z;
- if(has_normals)
- {
- N[j][0] = v.nx;
- N[j][1] = v.ny;
- N[j][2] = v.nz;
- }
- if(has_texture_coords)
- {
- UV[j][0] = v.s;
- UV[j][1] = v.t;
- }
- }
- }
- plist = ply_get_element_description (in_ply,"face", &elem_count, &nprops);
- if (plist != NULL)
- {
- F.resize(elem_count);
- ply_get_property(in_ply,"face",&face_props[0]);
- for (int j = 0; j < elem_count; j++)
- {
- Face f;
- ply_get_element(in_ply, (void *) &f);
- for(size_t c = 0;c<f.nverts;c++)
- {
- F[j].push_back(f.verts[c]);
- }
- }
- }
- ply_close(in_ply);
- return true;
- }
- template <
- typename DerivedV,
- typename DerivedF,
- typename DerivedN,
- typename DerivedUV>
- IGL_INLINE bool igl::readPLY(
- const std::string & filename,
- Eigen::PlainObjectBase<DerivedV> & V,
- Eigen::PlainObjectBase<DerivedF> & F,
- Eigen::PlainObjectBase<DerivedN> & N,
- Eigen::PlainObjectBase<DerivedUV> & UV)
- {
- std::vector<std::vector<typename DerivedV::Scalar> > vV;
- std::vector<std::vector<typename DerivedF::Scalar> > vF;
- std::vector<std::vector<typename DerivedN::Scalar> > vN;
- std::vector<std::vector<typename DerivedUV::Scalar> > 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<DerivedV> & V,
- Eigen::PlainObjectBase<DerivedF> & F)
- {
- Eigen::MatrixXd N,UV;
- return readPLY(filename,V,F,N,UV);
- }
- #ifdef IGL_STATIC_LIBRARY
- // Explicit template specialization
- template bool igl::readPLY<double, int, double, double>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&);
- #endif
|