readPLY.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "readPLY.h"
  9. #include "list_to_matrix.h"
  10. #include "ply.h"
  11. #include <iostream>
  12. template <
  13. typename Vtype,
  14. typename Ftype,
  15. typename Ntype,
  16. typename UVtype>
  17. IGL_INLINE bool igl::readPLY(
  18. const std::string & filename,
  19. std::vector<std::vector<Vtype> > & V,
  20. std::vector<std::vector<Ftype> > & F,
  21. std::vector<std::vector<Ntype> > & N,
  22. std::vector<std::vector<UVtype> > & UV)
  23. {
  24. using namespace std;
  25. // Largely follows ply2iv.c
  26. PlyOtherProp *vert_other,*face_other;
  27. typedef struct Vertex {
  28. double x,y,z; /* position */
  29. double nx,ny,nz; /* surface normal */
  30. double s,t; /* texture coordinates */
  31. void *other_props; /* other properties */
  32. } Vertex;
  33. typedef struct Face {
  34. unsigned char nverts; /* number of vertex indices in list */
  35. int *verts; /* vertex index list */
  36. void *other_props; /* other properties */
  37. } Face;
  38. PlyProperty vert_props[] = { /* list of property information for a vertex */
  39. {"x", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,x), 0, 0, 0, 0},
  40. {"y", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,y), 0, 0, 0, 0},
  41. {"z", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,z), 0, 0, 0, 0},
  42. {"nx", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,nx), 0, 0, 0, 0},
  43. {"ny", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,ny), 0, 0, 0, 0},
  44. {"nz", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,nz), 0, 0, 0, 0},
  45. {"s", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,s), 0, 0, 0, 0},
  46. {"t", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,t), 0, 0, 0, 0},
  47. };
  48. PlyProperty face_props[] = { /* list of property information for a face */
  49. {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts),
  50. 1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)},
  51. };
  52. char * elem_name;
  53. FILE * fp = fopen(filename.c_str(),"r");
  54. if(fp == NULL)
  55. {
  56. return false;
  57. }
  58. int nelems;
  59. char ** elem_names;
  60. PlyFile * in_ply = ply_read(fp,&nelems,&elem_names);
  61. if(in_ply==NULL)
  62. {
  63. return false;
  64. }
  65. bool has_normals = false;
  66. bool has_texture_coords = false;
  67. PlyProperty **plist;
  68. int nprops;
  69. int elem_count;
  70. plist = ply_get_element_description (in_ply,"vertex", &elem_count, &nprops);
  71. if (plist != NULL)
  72. {
  73. /* set up for getting vertex elements */
  74. ply_get_property (in_ply,"vertex",&vert_props[0]);
  75. ply_get_property (in_ply,"vertex",&vert_props[1]);
  76. ply_get_property (in_ply,"vertex",&vert_props[2]);
  77. for (size_t j = 0; j < nprops; j++)
  78. {
  79. PlyProperty * prop = plist[j];
  80. if (equal_strings ("nx", prop->name)
  81. || equal_strings ("ny", prop->name)
  82. || equal_strings ("nz", prop->name))
  83. {
  84. ply_get_property (in_ply,"vertex",&vert_props[3]);
  85. ply_get_property (in_ply,"vertex",&vert_props[4]);
  86. ply_get_property (in_ply,"vertex",&vert_props[5]);
  87. has_normals = true;
  88. }
  89. if (equal_strings ("s", prop->name) ||
  90. equal_strings ("t", prop->name))
  91. {
  92. ply_get_property(in_ply,"vertex",&vert_props[6]);
  93. ply_get_property(in_ply,"vertex",&vert_props[7]);
  94. has_texture_coords = true;
  95. }
  96. }
  97. vert_other = ply_get_other_properties(in_ply,"vertex",
  98. offsetof(Vertex,other_props));
  99. V.resize(elem_count,std::vector<Vtype>(3));
  100. if(has_normals)
  101. {
  102. N.resize(elem_count,std::vector<Ntype>(3));
  103. }else
  104. {
  105. N.resize(0);
  106. }
  107. if(has_texture_coords)
  108. {
  109. UV.resize(elem_count,std::vector<UVtype>(2));
  110. }else
  111. {
  112. UV.resize(0);
  113. }
  114. for(size_t j = 0;j<elem_count;j++)
  115. {
  116. Vertex v;
  117. ply_get_element_setup(in_ply,"vertex",3,vert_props);
  118. ply_get_element(in_ply,(void*)&v);
  119. V[j][0] = v.x;
  120. V[j][1] = v.y;
  121. V[j][2] = v.z;
  122. if(has_normals)
  123. {
  124. N[j][0] = v.nx;
  125. N[j][1] = v.ny;
  126. N[j][2] = v.nz;
  127. }
  128. if(has_texture_coords)
  129. {
  130. UV[j][0] = v.s;
  131. UV[j][1] = v.t;
  132. }
  133. }
  134. }
  135. plist = ply_get_element_description (in_ply,"face", &elem_count, &nprops);
  136. if (plist != NULL)
  137. {
  138. F.resize(elem_count);
  139. ply_get_property(in_ply,"face",&face_props[0]);
  140. for (size_t j = 0; j < elem_count; j++)
  141. {
  142. Face f;
  143. ply_get_element(in_ply, (void *) &f);
  144. for(size_t c = 0;c<f.nverts;c++)
  145. {
  146. F[j].push_back(f.verts[c]);
  147. }
  148. }
  149. }
  150. ply_close(in_ply);
  151. fclose(fp);
  152. return true;
  153. }
  154. template <
  155. typename DerivedV,
  156. typename DerivedF,
  157. typename DerivedN,
  158. typename DerivedUV>
  159. IGL_INLINE bool igl::readPLY(
  160. const std::string & filename,
  161. Eigen::PlainObjectBase<DerivedV> & V,
  162. Eigen::PlainObjectBase<DerivedF> & F,
  163. Eigen::PlainObjectBase<DerivedN> & N,
  164. Eigen::PlainObjectBase<DerivedUV> & UV)
  165. {
  166. std::vector<std::vector<typename DerivedV::Scalar> > vV;
  167. std::vector<std::vector<typename DerivedF::Scalar> > vF;
  168. std::vector<std::vector<typename DerivedN::Scalar> > vN;
  169. std::vector<std::vector<typename DerivedUV::Scalar> > vUV;
  170. if(!readPLY(filename,vV,vF,vN,vUV))
  171. {
  172. return false;
  173. }
  174. return
  175. list_to_matrix(vV,V) &&
  176. list_to_matrix(vF,F) &&
  177. list_to_matrix(vN,N) &&
  178. list_to_matrix(vUV,UV);
  179. }
  180. #ifdef IGL_STATIC_LIBRARY
  181. // Explicit template specialization
  182. #endif