writeSTL.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Alec Jacobson <[email protected]>
  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 "writeSTL.h"
  9. #include <iostream>
  10. template <typename DerivedV, typename DerivedF, typename DerivedN>
  11. IGL_INLINE bool igl::writeSTL(
  12. const std::string & filename,
  13. const Eigen::MatrixBase<DerivedV> & V,
  14. const Eigen::MatrixBase<DerivedF> & F,
  15. const Eigen::MatrixBase<DerivedN> & N,
  16. FileEncoding encoding)
  17. {
  18. assert(N.rows() == 0 || F.rows() == N.rows());
  19. if(encoding == FileEncoding::Ascii)
  20. {
  21. FILE * stl_file = fopen(filename.c_str(),"w");
  22. if(stl_file == NULL)
  23. {
  24. std::cerr<<"IOError: "<<filename<<" could not be opened for writing."<<std::endl;
  25. return false;
  26. }
  27. fprintf(stl_file,"solid %s\n",filename.c_str());
  28. for(int f = 0;f<F.rows();f++)
  29. {
  30. fprintf(stl_file,"facet normal ");
  31. if(N.rows()>0)
  32. {
  33. fprintf(stl_file,"%e %e %e\n",
  34. (float)N(f,0),
  35. (float)N(f,1),
  36. (float)N(f,2));
  37. }else
  38. {
  39. fprintf(stl_file,"0 0 0\n");
  40. }
  41. fprintf(stl_file,"outer loop\n");
  42. for(int c = 0;c<F.cols();c++)
  43. {
  44. fprintf(stl_file,"vertex %e %e %e\n",
  45. (float)V(F(f,c),0),
  46. (float)V(F(f,c),1),
  47. (float)V(F(f,c),2));
  48. }
  49. fprintf(stl_file,"endloop\n");
  50. fprintf(stl_file,"endfacet\n");
  51. }
  52. fprintf(stl_file,"endsolid %s\n",filename.c_str());
  53. fclose(stl_file);
  54. return true;
  55. }else
  56. {
  57. FILE * stl_file = fopen(filename.c_str(),"wb");
  58. if(stl_file == NULL)
  59. {
  60. std::cerr<<"IOError: "<<filename<<" could not be opened for writing."<<std::endl;
  61. return false;
  62. }
  63. // Write unused 80-char header
  64. for(char h = 0;h<80;h++)
  65. {
  66. fwrite(&h,sizeof(char),1,stl_file);
  67. }
  68. // Write number of triangles
  69. unsigned int num_tri = F.rows();
  70. fwrite(&num_tri,sizeof(unsigned int),1,stl_file);
  71. assert(F.cols() == 3);
  72. // Write each triangle
  73. for(int f = 0;f<F.rows();f++)
  74. {
  75. std::vector<float> n(3,0);
  76. if(N.rows() > 0)
  77. {
  78. n[0] = N(f,0);
  79. n[1] = N(f,1);
  80. n[2] = N(f,2);
  81. }
  82. fwrite(&n[0],sizeof(float),3,stl_file);
  83. for(int c = 0;c<3;c++)
  84. {
  85. std::vector<float> v(3);
  86. v[0] = V(F(f,c),0);
  87. v[1] = V(F(f,c),1);
  88. v[2] = V(F(f,c),2);
  89. fwrite(&v[0],sizeof(float),3,stl_file);
  90. }
  91. unsigned short att_count = 0;
  92. fwrite(&att_count,sizeof(unsigned short),1,stl_file);
  93. }
  94. fclose(stl_file);
  95. return true;
  96. }
  97. }
  98. template <typename DerivedV, typename DerivedF>
  99. IGL_INLINE bool igl::writeSTL(
  100. const std::string & filename,
  101. const Eigen::MatrixBase<DerivedV> & V,
  102. const Eigen::MatrixBase<DerivedF> & F,
  103. FileEncoding encoding)
  104. {
  105. return writeSTL(filename,V,F, Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic>(), encoding);
  106. }
  107. #ifdef IGL_STATIC_LIBRARY
  108. // Explicit template instantiation
  109. // generated by autoexplicit.sh
  110. template bool igl::writeSTL<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::FileEncoding);
  111. // generated by autoexplicit.sh
  112. template bool igl::writeSTL<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::FileEncoding);
  113. // generated by autoexplicit.sh
  114. template bool igl::writeSTL<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::FileEncoding);
  115. // generated by autoexplicit.sh
  116. template bool igl::writeSTL<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::FileEncoding);
  117. template bool igl::writeSTL<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::FileEncoding);
  118. template bool igl::writeSTL<Eigen::Matrix<double, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, igl::FileEncoding);
  119. #endif