TriangleMesh.xsp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. %module{Slic3r::XS};
  2. %{
  3. #include <xsinit.h>
  4. #include "libslic3r/TriangleMesh.hpp"
  5. %}
  6. %name{Slic3r::TriangleMesh} class TriangleMesh {
  7. TriangleMesh();
  8. ~TriangleMesh();
  9. Clone<TriangleMesh> clone()
  10. %code{% RETVAL = THIS; %};
  11. void ReadSTLFile(char* input_file);
  12. void write_ascii(char* output_file);
  13. void write_binary(char* output_file);
  14. void repair();
  15. void WriteOBJFile(char* output_file);
  16. void scale(float factor);
  17. void scale_xyz(Vec3d* versor)
  18. %code{% THIS->scale(*versor); %};
  19. void translate(float x, float y, float z);
  20. void rotate_x(float angle);
  21. void rotate_y(float angle);
  22. void rotate_z(float angle);
  23. void mirror_x();
  24. void mirror_y();
  25. void mirror_z();
  26. void align_to_origin();
  27. void rotate(double angle, Point* center);
  28. TriangleMeshPtrs split();
  29. void merge(TriangleMesh* mesh)
  30. %code{% THIS->merge(*mesh); %};
  31. ExPolygons horizontal_projection();
  32. Clone<Polygon> convex_hull();
  33. Clone<BoundingBoxf3> bounding_box();
  34. Clone<Vec3d> center()
  35. %code{% RETVAL = THIS->bounding_box().center(); %};
  36. int facets_count();
  37. void reset_repair_stats();
  38. %{
  39. void
  40. TriangleMesh::ReadFromPerl(vertices, facets)
  41. SV* vertices
  42. SV* facets
  43. CODE:
  44. stl_file &stl = THIS->stl;
  45. stl.stats.type = inmemory;
  46. // count facets and allocate memory
  47. AV* facets_av = (AV*)SvRV(facets);
  48. stl.stats.number_of_facets = av_len(facets_av)+1;
  49. stl.stats.original_num_facets = stl.stats.number_of_facets;
  50. stl_allocate(&stl);
  51. // read geometry
  52. AV* vertices_av = (AV*)SvRV(vertices);
  53. for (int i = 0; i < stl.stats.number_of_facets; i++) {
  54. AV* facet_av = (AV*)SvRV(*av_fetch(facets_av, i, 0));
  55. stl_facet facet;
  56. facet.normal(0) = 0;
  57. facet.normal(1) = 0;
  58. facet.normal(2) = 0;
  59. for (unsigned int v = 0; v <= 2; v++) {
  60. AV* vertex_av = (AV*)SvRV(*av_fetch(vertices_av, SvIV(*av_fetch(facet_av, v, 0)), 0));
  61. facet.vertex[v](0) = SvNV(*av_fetch(vertex_av, 0, 0));
  62. facet.vertex[v](1) = SvNV(*av_fetch(vertex_av, 1, 0));
  63. facet.vertex[v](2) = SvNV(*av_fetch(vertex_av, 2, 0));
  64. }
  65. facet.extra[0] = 0;
  66. facet.extra[1] = 0;
  67. stl.facet_start[i] = facet;
  68. }
  69. stl_get_size(&stl);
  70. SV*
  71. TriangleMesh::stats()
  72. CODE:
  73. HV* hv = newHV();
  74. (void)hv_stores( hv, "number_of_facets", newSViv(THIS->stl.stats.number_of_facets) );
  75. (void)hv_stores( hv, "number_of_parts", newSViv(THIS->stl.stats.number_of_parts) );
  76. (void)hv_stores( hv, "volume", newSVnv(THIS->stl.stats.volume) );
  77. (void)hv_stores( hv, "degenerate_facets", newSViv(THIS->stl.stats.degenerate_facets) );
  78. (void)hv_stores( hv, "edges_fixed", newSViv(THIS->stl.stats.edges_fixed) );
  79. (void)hv_stores( hv, "facets_removed", newSViv(THIS->stl.stats.facets_removed) );
  80. (void)hv_stores( hv, "facets_added", newSViv(THIS->stl.stats.facets_added) );
  81. (void)hv_stores( hv, "facets_reversed", newSViv(THIS->stl.stats.facets_reversed) );
  82. (void)hv_stores( hv, "backwards_edges", newSViv(THIS->stl.stats.backwards_edges) );
  83. (void)hv_stores( hv, "normals_fixed", newSViv(THIS->stl.stats.normals_fixed) );
  84. RETVAL = (SV*)newRV_noinc((SV*)hv);
  85. OUTPUT:
  86. RETVAL
  87. SV*
  88. TriangleMesh::vertices()
  89. CODE:
  90. if (!THIS->repaired) CONFESS("vertices() requires repair()");
  91. THIS->require_shared_vertices();
  92. // vertices
  93. AV* vertices = newAV();
  94. av_extend(vertices, THIS->its.vertices.size());
  95. for (size_t i = 0; i < THIS->its.vertices.size(); i++) {
  96. AV* vertex = newAV();
  97. av_store(vertices, i, newRV_noinc((SV*)vertex));
  98. av_extend(vertex, 2);
  99. av_store(vertex, 0, newSVnv(THIS->its.vertices[i](0)));
  100. av_store(vertex, 1, newSVnv(THIS->its.vertices[i](1)));
  101. av_store(vertex, 2, newSVnv(THIS->its.vertices[i](2)));
  102. }
  103. RETVAL = newRV_noinc((SV*)vertices);
  104. OUTPUT:
  105. RETVAL
  106. SV*
  107. TriangleMesh::facets()
  108. CODE:
  109. if (!THIS->repaired) CONFESS("facets() requires repair()");
  110. THIS->require_shared_vertices();
  111. // facets
  112. AV* facets = newAV();
  113. av_extend(facets, THIS->stl.stats.number_of_facets);
  114. for (int i = 0; i < THIS->stl.stats.number_of_facets; i++) {
  115. AV* facet = newAV();
  116. av_store(facets, i, newRV_noinc((SV*)facet));
  117. av_extend(facet, 2);
  118. av_store(facet, 0, newSVnv(THIS->its.indices[i][0]));
  119. av_store(facet, 1, newSVnv(THIS->its.indices[i][1]));
  120. av_store(facet, 2, newSVnv(THIS->its.indices[i][2]));
  121. }
  122. RETVAL = newRV_noinc((SV*)facets);
  123. OUTPUT:
  124. RETVAL
  125. SV*
  126. TriangleMesh::normals()
  127. CODE:
  128. if (!THIS->repaired) CONFESS("normals() requires repair()");
  129. // normals
  130. AV* normals = newAV();
  131. av_extend(normals, THIS->stl.stats.number_of_facets);
  132. for (int i = 0; i < THIS->stl.stats.number_of_facets; i++) {
  133. AV* facet = newAV();
  134. av_store(normals, i, newRV_noinc((SV*)facet));
  135. av_extend(facet, 2);
  136. av_store(facet, 0, newSVnv(THIS->stl.facet_start[i].normal(0)));
  137. av_store(facet, 1, newSVnv(THIS->stl.facet_start[i].normal(1)));
  138. av_store(facet, 2, newSVnv(THIS->stl.facet_start[i].normal(2)));
  139. }
  140. RETVAL = newRV_noinc((SV*)normals);
  141. OUTPUT:
  142. RETVAL
  143. SV*
  144. TriangleMesh::size()
  145. CODE:
  146. AV* size = newAV();
  147. av_extend(size, 2);
  148. av_store(size, 0, newSVnv(THIS->stl.stats.size(0)));
  149. av_store(size, 1, newSVnv(THIS->stl.stats.size(1)));
  150. av_store(size, 2, newSVnv(THIS->stl.stats.size(2)));
  151. RETVAL = newRV_noinc((SV*)size);
  152. OUTPUT:
  153. RETVAL
  154. SV*
  155. TriangleMesh::slice(z)
  156. std::vector<double> z
  157. CODE:
  158. THIS->require_shared_vertices(); // TriangleMeshSlicer needs this
  159. // convert doubles to floats
  160. std::vector<float> z_f = cast<float>(z);
  161. std::vector<ExPolygons> layers;
  162. TriangleMeshSlicer mslicer(THIS);
  163. mslicer.slice(z_f, SlicingMode::Regular, 0.049f, &layers, [](){});
  164. AV* layers_av = newAV();
  165. size_t len = layers.size();
  166. if (len > 0) av_extend(layers_av, len-1);
  167. for (unsigned int i = 0; i < layers.size(); i++) {
  168. AV* expolygons_av = newAV();
  169. len = layers[i].size();
  170. if (len > 0) av_extend(expolygons_av, len-1);
  171. unsigned int j = 0;
  172. for (ExPolygons::iterator it = layers[i].begin(); it != layers[i].end(); ++it) {
  173. av_store(expolygons_av, j++, perl_to_SV_clone_ref(*it));
  174. }
  175. av_store(layers_av, i, newRV_noinc((SV*)expolygons_av));
  176. }
  177. RETVAL = (SV*)newRV_noinc((SV*)layers_av);
  178. OUTPUT:
  179. RETVAL
  180. void
  181. TriangleMesh::cut(z, upper, lower)
  182. float z;
  183. TriangleMesh* upper;
  184. TriangleMesh* lower;
  185. CODE:
  186. THIS->require_shared_vertices(); // TriangleMeshSlicer needs this
  187. TriangleMeshSlicer mslicer(THIS);
  188. mslicer.cut(z, upper, lower);
  189. std::vector<double>
  190. TriangleMesh::bb3()
  191. CODE:
  192. RETVAL.push_back(THIS->stl.stats.min(0));
  193. RETVAL.push_back(THIS->stl.stats.min(1));
  194. RETVAL.push_back(THIS->stl.stats.max(0));
  195. RETVAL.push_back(THIS->stl.stats.max(1));
  196. RETVAL.push_back(THIS->stl.stats.min(2));
  197. RETVAL.push_back(THIS->stl.stats.max(2));
  198. OUTPUT:
  199. RETVAL
  200. Clone<TriangleMesh>
  201. cube(double x, double y, double z)
  202. CODE:
  203. RETVAL = make_cube(x,y,z);
  204. OUTPUT:
  205. RETVAL
  206. Clone<TriangleMesh>
  207. cylinder(double r, double h)
  208. CODE:
  209. RETVAL = make_cylinder(r, h);
  210. OUTPUT:
  211. RETVAL
  212. Clone<TriangleMesh>
  213. sphere(double rho)
  214. CODE:
  215. RETVAL = make_sphere(rho);
  216. OUTPUT:
  217. RETVAL
  218. %}
  219. };
  220. %package{Slic3r::TriangleMesh};
  221. %{
  222. PROTOTYPES: DISABLE
  223. std::string
  224. hello_world()
  225. CODE:
  226. RETVAL = "Hello world!";
  227. OUTPUT:
  228. RETVAL
  229. %}