// 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 "writePLY.h" #include template < typename DerivedV, typename DerivedF, typename DerivedN, typename DerivedUV> IGL_INLINE bool igl::writePLY( const std::string & filename, const Eigen::PlainObjectBase & V, const Eigen::PlainObjectBase & F, const Eigen::PlainObjectBase & N, const Eigen::PlainObjectBase & 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 vlist(V.rows()); std::vector flist(F.rows()); for(size_t i = 0;i 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); ply_put_element_setup(ply, "vertex"); for(const auto v : vlist) { ply_put_element(ply, (void *) &v); } ply_put_element_setup(ply, "face"); for(const auto f : flist) { ply_put_element(ply, (void *) &f); } ply_close(ply); fclose(fp); for(size_t i = 0;i