TriangleMesh.xsp 8.9 KB

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