ScadPy 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. scadpy-0.1.0/.github/workflows/ci.yml +24 -0
  2. scadpy-0.1.0/.github/workflows/release.yml +54 -0
  3. scadpy-0.1.0/.gitignore +43 -0
  4. scadpy-0.1.0/LICENSE.md +43 -0
  5. scadpy-0.1.0/PKG-INFO +282 -0
  6. scadpy-0.1.0/README.md +213 -0
  7. scadpy-0.1.0/docs/Makefile +48 -0
  8. scadpy-0.1.0/docs/_static/badges/coverage.svg +1 -0
  9. scadpy-0.1.0/docs/_static/badges/interrogate.svg +58 -0
  10. scadpy-0.1.0/docs/_static/css/custom.css +157 -0
  11. scadpy-0.1.0/docs/_static/logo.ico +0 -0
  12. scadpy-0.1.0/docs/_static/logo.png +0 -0
  13. scadpy-0.1.0/docs/conf.py +174 -0
  14. scadpy-0.1.0/docs/index.rst +247 -0
  15. scadpy-0.1.0/docs/scadpy/core/assembly/combinations.rst +8 -0
  16. scadpy-0.1.0/docs/scadpy/core/assembly/topologies.rst +8 -0
  17. scadpy-0.1.0/docs/scadpy/core/assembly/transformations.rst +8 -0
  18. scadpy-0.1.0/docs/scadpy/core/assembly/types.rst +8 -0
  19. scadpy-0.1.0/docs/scadpy/core/assembly/utils.rst +8 -0
  20. scadpy-0.1.0/docs/scadpy/core/assembly.rst +10 -0
  21. scadpy-0.1.0/docs/scadpy/core/component/exporters.rst +8 -0
  22. scadpy-0.1.0/docs/scadpy/core/component/features.rst +8 -0
  23. scadpy-0.1.0/docs/scadpy/core/component/utils.rst +8 -0
  24. scadpy-0.1.0/docs/scadpy/core/component.rst +8 -0
  25. scadpy-0.1.0/docs/scadpy/core/part/combinations.rst +8 -0
  26. scadpy-0.1.0/docs/scadpy/core/part.rst +6 -0
  27. scadpy-0.1.0/docs/scadpy/core.rst +8 -0
  28. scadpy-0.1.0/docs/scadpy/d2/shape/combinations.rst +8 -0
  29. scadpy-0.1.0/docs/scadpy/d2/shape/exporters.rst +8 -0
  30. scadpy-0.1.0/docs/scadpy/d2/shape/features.rst +8 -0
  31. scadpy-0.1.0/docs/scadpy/d2/shape/importers.rst +8 -0
  32. scadpy-0.1.0/docs/scadpy/d2/shape/primitives.rst +8 -0
  33. scadpy-0.1.0/docs/scadpy/d2/shape/topologies.rst +8 -0
  34. scadpy-0.1.0/docs/scadpy/d2/shape/transformations.rst +8 -0
  35. scadpy-0.1.0/docs/scadpy/d2/shape/types.rst +13 -0
  36. scadpy-0.1.0/docs/scadpy/d2/shape.rst +13 -0
  37. scadpy-0.1.0/docs/scadpy/d2.rst +6 -0
  38. scadpy-0.1.0/docs/scadpy/d3/solid/combinations.rst +8 -0
  39. scadpy-0.1.0/docs/scadpy/d3/solid/exporters.rst +8 -0
  40. scadpy-0.1.0/docs/scadpy/d3/solid/features.rst +8 -0
  41. scadpy-0.1.0/docs/scadpy/d3/solid/importers.rst +8 -0
  42. scadpy-0.1.0/docs/scadpy/d3/solid/primitives.rst +8 -0
  43. scadpy-0.1.0/docs/scadpy/d3/solid/topologies.rst +8 -0
  44. scadpy-0.1.0/docs/scadpy/d3/solid/transformations.rst +8 -0
  45. scadpy-0.1.0/docs/scadpy/d3/solid/types.rst +8 -0
  46. scadpy-0.1.0/docs/scadpy/d3/solid.rst +13 -0
  47. scadpy-0.1.0/docs/scadpy/d3.rst +6 -0
  48. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_all__dark.md5 +1 -0
  49. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_all__light.md5 +1 -0
  50. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_clamp_proportional__dark.md5 +1 -0
  51. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_clamp_proportional__light.md5 +1 -0
  52. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_concave_asymmetric__dark.md5 +1 -0
  53. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_concave_asymmetric__light.md5 +1 -0
  54. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_convex_only__dark.md5 +1 -0
  55. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_convex_only__light.md5 +1 -0
  56. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_sharp_convex__dark.md5 +1 -0
  57. scadpy-0.1.0/docs/snapshots/d2__chamfer_shape_sharp_convex__light.md5 +1 -0
  58. scadpy-0.1.0/docs/snapshots/d2__color_shape__dark.md5 +1 -0
  59. scadpy-0.1.0/docs/snapshots/d2__color_shape__light.md5 +1 -0
  60. scadpy-0.1.0/docs/snapshots/d2__color_solid__dark.md5 +1 -0
  61. scadpy-0.1.0/docs/snapshots/d2__color_solid__light.md5 +1 -0
  62. scadpy-0.1.0/docs/snapshots/d2__concat_shape__dark.md5 +1 -0
  63. scadpy-0.1.0/docs/snapshots/d2__concat_shape__light.md5 +1 -0
  64. scadpy-0.1.0/docs/snapshots/d2__concat_solid__dark.md5 +1 -0
  65. scadpy-0.1.0/docs/snapshots/d2__concat_solid__light.md5 +1 -0
  66. scadpy-0.1.0/docs/snapshots/d2__cone__dark.md5 +1 -0
  67. scadpy-0.1.0/docs/snapshots/d2__cone__light.md5 +1 -0
  68. scadpy-0.1.0/docs/snapshots/d2__convexify_shape__dark.md5 +1 -0
  69. scadpy-0.1.0/docs/snapshots/d2__convexify_shape__light.md5 +1 -0
  70. scadpy-0.1.0/docs/snapshots/d2__convexify_shape_partial__dark.md5 +1 -0
  71. scadpy-0.1.0/docs/snapshots/d2__convexify_shape_partial__light.md5 +1 -0
  72. scadpy-0.1.0/docs/snapshots/d2__convexify_solid__dark.md5 +1 -0
  73. scadpy-0.1.0/docs/snapshots/d2__convexify_solid__light.md5 +1 -0
  74. scadpy-0.1.0/docs/snapshots/d2__cube__dark.md5 +1 -0
  75. scadpy-0.1.0/docs/snapshots/d2__cube__light.md5 +1 -0
  76. scadpy-0.1.0/docs/snapshots/d2__cuboid__dark.md5 +1 -0
  77. scadpy-0.1.0/docs/snapshots/d2__cuboid__light.md5 +1 -0
  78. scadpy-0.1.0/docs/snapshots/d2__cylinder__dark.md5 +1 -0
  79. scadpy-0.1.0/docs/snapshots/d2__cylinder__light.md5 +1 -0
  80. scadpy-0.1.0/docs/snapshots/d2__exclude_shape__dark.md5 +1 -0
  81. scadpy-0.1.0/docs/snapshots/d2__exclude_shape__light.md5 +1 -0
  82. scadpy-0.1.0/docs/snapshots/d2__exclude_solid__dark.md5 +1 -0
  83. scadpy-0.1.0/docs/snapshots/d2__exclude_solid__light.md5 +1 -0
  84. scadpy-0.1.0/docs/snapshots/d2__fill_shape__dark.md5 +1 -0
  85. scadpy-0.1.0/docs/snapshots/d2__fill_shape__light.md5 +1 -0
  86. scadpy-0.1.0/docs/snapshots/d2__fill_shape_partial__dark.md5 +1 -0
  87. scadpy-0.1.0/docs/snapshots/d2__fill_shape_partial__light.md5 +1 -0
  88. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_all__dark.md5 +1 -0
  89. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_all__light.md5 +1 -0
  90. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_clamp_proportional__dark.md5 +1 -0
  91. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_clamp_proportional__light.md5 +1 -0
  92. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_concave_asymmetric__dark.md5 +1 -0
  93. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_concave_asymmetric__light.md5 +1 -0
  94. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_convex_only__dark.md5 +1 -0
  95. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_convex_only__light.md5 +1 -0
  96. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_sharp_convex__dark.md5 +1 -0
  97. scadpy-0.1.0/docs/snapshots/d2__fillet_shape_sharp_convex__light.md5 +1 -0
  98. scadpy-0.1.0/docs/snapshots/d2__grow_shape__dark.md5 +1 -0
  99. scadpy-0.1.0/docs/snapshots/d2__grow_shape__light.md5 +1 -0
  100. scadpy-0.1.0/docs/snapshots/d2__grow_shape_partial__dark.md5 +1 -0
  101. scadpy-0.1.0/docs/snapshots/d2__grow_shape_partial__light.md5 +1 -0
  102. scadpy-0.1.0/docs/snapshots/d2__grow_shape_shrink__dark.md5 +1 -0
  103. scadpy-0.1.0/docs/snapshots/d2__grow_shape_shrink__light.md5 +1 -0
  104. scadpy-0.1.0/docs/snapshots/d2__hexagonal_cone__dark.md5 +1 -0
  105. scadpy-0.1.0/docs/snapshots/d2__hexagonal_cone__light.md5 +1 -0
  106. scadpy-0.1.0/docs/snapshots/d2__hexagonal_cylinder__dark.md5 +1 -0
  107. scadpy-0.1.0/docs/snapshots/d2__hexagonal_cylinder__light.md5 +1 -0
  108. scadpy-0.1.0/docs/snapshots/d2__index_2d__dark.md5 +1 -0
  109. scadpy-0.1.0/docs/snapshots/d2__index_2d__light.md5 +1 -0
  110. scadpy-0.1.0/docs/snapshots/d2__index_3d__dark.md5 +1 -0
  111. scadpy-0.1.0/docs/snapshots/d2__index_3d__light.md5 +1 -0
  112. scadpy-0.1.0/docs/snapshots/d2__intersect_shape__dark.md5 +1 -0
  113. scadpy-0.1.0/docs/snapshots/d2__intersect_shape__light.md5 +1 -0
  114. scadpy-0.1.0/docs/snapshots/d2__intersect_shape_parts_example__dark.md5 +1 -0
  115. scadpy-0.1.0/docs/snapshots/d2__intersect_shape_parts_example__light.md5 +1 -0
  116. scadpy-0.1.0/docs/snapshots/d2__intersect_solid__dark.md5 +1 -0
  117. scadpy-0.1.0/docs/snapshots/d2__intersect_solid__light.md5 +1 -0
  118. scadpy-0.1.0/docs/snapshots/d2__intersect_solid_parts_example__dark.md5 +1 -0
  119. scadpy-0.1.0/docs/snapshots/d2__intersect_solid_parts_example__light.md5 +1 -0
  120. scadpy-0.1.0/docs/snapshots/d2__linear_cut_shape__dark.md5 +1 -0
  121. scadpy-0.1.0/docs/snapshots/d2__linear_cut_shape__light.md5 +1 -0
  122. scadpy-0.1.0/docs/snapshots/d2__linear_cut_shape_diagonal__dark.md5 +1 -0
  123. scadpy-0.1.0/docs/snapshots/d2__linear_cut_shape_diagonal__light.md5 +1 -0
  124. scadpy-0.1.0/docs/snapshots/d2__linear_extrude_shape_square__dark.md5 +1 -0
  125. scadpy-0.1.0/docs/snapshots/d2__linear_extrude_shape_square__light.md5 +1 -0
  126. scadpy-0.1.0/docs/snapshots/d2__linear_extrude_shape_tube__dark.md5 +1 -0
  127. scadpy-0.1.0/docs/snapshots/d2__linear_extrude_shape_tube__light.md5 +1 -0
  128. scadpy-0.1.0/docs/snapshots/d2__linear_slice_shape_diagonal__dark.md5 +1 -0
  129. scadpy-0.1.0/docs/snapshots/d2__linear_slice_shape_diagonal__light.md5 +1 -0
  130. scadpy-0.1.0/docs/snapshots/d2__linear_slice_shape_horizontal__dark.md5 +1 -0
  131. scadpy-0.1.0/docs/snapshots/d2__linear_slice_shape_horizontal__light.md5 +1 -0
  132. scadpy-0.1.0/docs/snapshots/d2__linear_slice_shape_partial__dark.md5 +1 -0
  133. scadpy-0.1.0/docs/snapshots/d2__linear_slice_shape_partial__light.md5 +1 -0
  134. scadpy-0.1.0/docs/snapshots/d2__linear_slice_shape_pivot__dark.md5 +1 -0
  135. scadpy-0.1.0/docs/snapshots/d2__linear_slice_shape_pivot__light.md5 +1 -0
  136. scadpy-0.1.0/docs/snapshots/d2__low_resolution_sphere__dark.md5 +1 -0
  137. scadpy-0.1.0/docs/snapshots/d2__low_resolution_sphere__light.md5 +1 -0
  138. scadpy-0.1.0/docs/snapshots/d2__map_dxf_to_shape__dark.md5 +1 -0
  139. scadpy-0.1.0/docs/snapshots/d2__map_dxf_to_shape__light.md5 +1 -0
  140. scadpy-0.1.0/docs/snapshots/d2__map_geometries_to_shape__dark.md5 +1 -0
  141. scadpy-0.1.0/docs/snapshots/d2__map_geometries_to_shape__light.md5 +1 -0
  142. scadpy-0.1.0/docs/snapshots/d2__map_geometries_to_solid__dark.md5 +1 -0
  143. scadpy-0.1.0/docs/snapshots/d2__map_geometries_to_solid__light.md5 +1 -0
  144. scadpy-0.1.0/docs/snapshots/d2__map_geometry_to_shape__dark.md5 +1 -0
  145. scadpy-0.1.0/docs/snapshots/d2__map_geometry_to_shape__light.md5 +1 -0
  146. scadpy-0.1.0/docs/snapshots/d2__map_geometry_to_solid__dark.md5 +1 -0
  147. scadpy-0.1.0/docs/snapshots/d2__map_geometry_to_solid__light.md5 +1 -0
  148. scadpy-0.1.0/docs/snapshots/d2__map_parts_to_shape__dark.md5 +1 -0
  149. scadpy-0.1.0/docs/snapshots/d2__map_parts_to_shape__light.md5 +1 -0
  150. scadpy-0.1.0/docs/snapshots/d2__map_parts_to_solid__dark.md5 +1 -0
  151. scadpy-0.1.0/docs/snapshots/d2__map_parts_to_solid__light.md5 +1 -0
  152. scadpy-0.1.0/docs/snapshots/d2__map_svg_to_shape__dark.md5 +1 -0
  153. scadpy-0.1.0/docs/snapshots/d2__map_svg_to_shape__light.md5 +1 -0
  154. scadpy-0.1.0/docs/snapshots/d2__mirror_shape__dark.md5 +1 -0
  155. scadpy-0.1.0/docs/snapshots/d2__mirror_shape__light.md5 +1 -0
  156. scadpy-0.1.0/docs/snapshots/d2__mirror_solid__dark.md5 +1 -0
  157. scadpy-0.1.0/docs/snapshots/d2__mirror_solid__light.md5 +1 -0
  158. scadpy-0.1.0/docs/snapshots/d2__polyhedron__dark.md5 +1 -0
  159. scadpy-0.1.0/docs/snapshots/d2__polyhedron__light.md5 +1 -0
  160. scadpy-0.1.0/docs/snapshots/d2__pull_shape__dark.md5 +1 -0
  161. scadpy-0.1.0/docs/snapshots/d2__pull_shape__light.md5 +1 -0
  162. scadpy-0.1.0/docs/snapshots/d2__pull_solid__dark.md5 +1 -0
  163. scadpy-0.1.0/docs/snapshots/d2__pull_solid__light.md5 +1 -0
  164. scadpy-0.1.0/docs/snapshots/d2__push_shape__dark.md5 +1 -0
  165. scadpy-0.1.0/docs/snapshots/d2__push_shape__light.md5 +1 -0
  166. scadpy-0.1.0/docs/snapshots/d2__push_solid__dark.md5 +1 -0
  167. scadpy-0.1.0/docs/snapshots/d2__push_solid__light.md5 +1 -0
  168. scadpy-0.1.0/docs/snapshots/d2__radial_extrude_shape__dark.md5 +1 -0
  169. scadpy-0.1.0/docs/snapshots/d2__radial_extrude_shape__light.md5 +1 -0
  170. scadpy-0.1.0/docs/snapshots/d2__radial_extrude_shape_partial__dark.md5 +1 -0
  171. scadpy-0.1.0/docs/snapshots/d2__radial_extrude_shape_partial__light.md5 +1 -0
  172. scadpy-0.1.0/docs/snapshots/d2__radial_slice_shape_partial__dark.md5 +1 -0
  173. scadpy-0.1.0/docs/snapshots/d2__radial_slice_shape_partial__light.md5 +1 -0
  174. scadpy-0.1.0/docs/snapshots/d2__radial_slice_shape_pivot__dark.md5 +1 -0
  175. scadpy-0.1.0/docs/snapshots/d2__radial_slice_shape_pivot__light.md5 +1 -0
  176. scadpy-0.1.0/docs/snapshots/d2__radial_slice_shape_quarter__dark.md5 +1 -0
  177. scadpy-0.1.0/docs/snapshots/d2__radial_slice_shape_quarter__light.md5 +1 -0
  178. scadpy-0.1.0/docs/snapshots/d2__radial_slice_shape_three_quarter__dark.md5 +1 -0
  179. scadpy-0.1.0/docs/snapshots/d2__radial_slice_shape_three_quarter__light.md5 +1 -0
  180. scadpy-0.1.0/docs/snapshots/d2__recoordinate_shape__dark.md5 +1 -0
  181. scadpy-0.1.0/docs/snapshots/d2__recoordinate_shape__light.md5 +1 -0
  182. scadpy-0.1.0/docs/snapshots/d2__recoordinate_solid__dark.md5 +1 -0
  183. scadpy-0.1.0/docs/snapshots/d2__recoordinate_solid__light.md5 +1 -0
  184. scadpy-0.1.0/docs/snapshots/d2__resize_shape_auto__dark.md5 +1 -0
  185. scadpy-0.1.0/docs/snapshots/d2__resize_shape_auto__light.md5 +1 -0
  186. scadpy-0.1.0/docs/snapshots/d2__resize_shape_exact__dark.md5 +1 -0
  187. scadpy-0.1.0/docs/snapshots/d2__resize_shape_exact__light.md5 +1 -0
  188. scadpy-0.1.0/docs/snapshots/d2__resize_shape_freeze__dark.md5 +1 -0
  189. scadpy-0.1.0/docs/snapshots/d2__resize_shape_freeze__light.md5 +1 -0
  190. scadpy-0.1.0/docs/snapshots/d2__resize_solid_auto__dark.md5 +1 -0
  191. scadpy-0.1.0/docs/snapshots/d2__resize_solid_auto__light.md5 +1 -0
  192. scadpy-0.1.0/docs/snapshots/d2__resize_solid_exact__dark.md5 +1 -0
  193. scadpy-0.1.0/docs/snapshots/d2__resize_solid_exact__light.md5 +1 -0
  194. scadpy-0.1.0/docs/snapshots/d2__resize_solid_freeze__dark.md5 +1 -0
  195. scadpy-0.1.0/docs/snapshots/d2__resize_solid_freeze__light.md5 +1 -0
  196. scadpy-0.1.0/docs/snapshots/d2__rotate_shape__dark.md5 +1 -0
  197. scadpy-0.1.0/docs/snapshots/d2__rotate_shape__light.md5 +1 -0
  198. scadpy-0.1.0/docs/snapshots/d2__rotate_solid__dark.md5 +1 -0
  199. scadpy-0.1.0/docs/snapshots/d2__rotate_solid__light.md5 +1 -0
  200. scadpy-0.1.0/docs/snapshots/d2__scale_shape__dark.md5 +1 -0
  201. scadpy-0.1.0/docs/snapshots/d2__scale_shape__light.md5 +1 -0
  202. scadpy-0.1.0/docs/snapshots/d2__scale_solid__dark.md5 +1 -0
  203. scadpy-0.1.0/docs/snapshots/d2__scale_solid__light.md5 +1 -0
  204. scadpy-0.1.0/docs/snapshots/d2__shrink_shape__dark.md5 +1 -0
  205. scadpy-0.1.0/docs/snapshots/d2__shrink_shape__light.md5 +1 -0
  206. scadpy-0.1.0/docs/snapshots/d2__shrink_shape_negative__dark.md5 +1 -0
  207. scadpy-0.1.0/docs/snapshots/d2__shrink_shape_negative__light.md5 +1 -0
  208. scadpy-0.1.0/docs/snapshots/d2__shrink_shape_partial__dark.md5 +1 -0
  209. scadpy-0.1.0/docs/snapshots/d2__shrink_shape_partial__light.md5 +1 -0
  210. scadpy-0.1.0/docs/snapshots/d2__sphere__dark.md5 +1 -0
  211. scadpy-0.1.0/docs/snapshots/d2__sphere__light.md5 +1 -0
  212. scadpy-0.1.0/docs/snapshots/d2__subtract_shape__dark.md5 +1 -0
  213. scadpy-0.1.0/docs/snapshots/d2__subtract_shape__light.md5 +1 -0
  214. scadpy-0.1.0/docs/snapshots/d2__subtract_shape_parts_example__dark.md5 +1 -0
  215. scadpy-0.1.0/docs/snapshots/d2__subtract_shape_parts_example__light.md5 +1 -0
  216. scadpy-0.1.0/docs/snapshots/d2__subtract_solid__dark.md5 +1 -0
  217. scadpy-0.1.0/docs/snapshots/d2__subtract_solid__light.md5 +1 -0
  218. scadpy-0.1.0/docs/snapshots/d2__subtract_solid_parts_example__dark.md5 +1 -0
  219. scadpy-0.1.0/docs/snapshots/d2__subtract_solid_parts_example__light.md5 +1 -0
  220. scadpy-0.1.0/docs/snapshots/d2__translate_shape__dark.md5 +1 -0
  221. scadpy-0.1.0/docs/snapshots/d2__translate_shape__light.md5 +1 -0
  222. scadpy-0.1.0/docs/snapshots/d2__translate_solid__dark.md5 +1 -0
  223. scadpy-0.1.0/docs/snapshots/d2__translate_solid__light.md5 +1 -0
  224. scadpy-0.1.0/docs/snapshots/d2__unify_shape__dark.md5 +1 -0
  225. scadpy-0.1.0/docs/snapshots/d2__unify_shape__light.md5 +1 -0
  226. scadpy-0.1.0/docs/snapshots/d2__unify_shape_parts_example__dark.md5 +1 -0
  227. scadpy-0.1.0/docs/snapshots/d2__unify_shape_parts_example__light.md5 +1 -0
  228. scadpy-0.1.0/docs/snapshots/d2__unify_solid__dark.md5 +1 -0
  229. scadpy-0.1.0/docs/snapshots/d2__unify_solid__light.md5 +1 -0
  230. scadpy-0.1.0/docs/snapshots/d2__unify_solid_parts_example__dark.md5 +1 -0
  231. scadpy-0.1.0/docs/snapshots/d2__unify_solid_parts_example__light.md5 +1 -0
  232. scadpy-0.1.0/project_bundle.json +710 -0
  233. scadpy-0.1.0/pyproject.toml +47 -0
  234. scadpy-0.1.0/scadpy/__init__.py +5 -0
  235. scadpy-0.1.0/scadpy/color/__init__.py +3 -0
  236. scadpy-0.1.0/scadpy/color/constants/BEIGE.py +3 -0
  237. scadpy-0.1.0/scadpy/color/constants/BLACK.py +3 -0
  238. scadpy-0.1.0/scadpy/color/constants/BLUE.py +3 -0
  239. scadpy-0.1.0/scadpy/color/constants/BROWN.py +3 -0
  240. scadpy-0.1.0/scadpy/color/constants/DARK_GRAY.py +3 -0
  241. scadpy-0.1.0/scadpy/color/constants/DEFAULT_COLOR.py +3 -0
  242. scadpy-0.1.0/scadpy/color/constants/DEFAULT_OPACITY.py +1 -0
  243. scadpy-0.1.0/scadpy/color/constants/GRAY.py +3 -0
  244. scadpy-0.1.0/scadpy/color/constants/GREEN.py +3 -0
  245. scadpy-0.1.0/scadpy/color/constants/ORANGE.py +3 -0
  246. scadpy-0.1.0/scadpy/color/constants/RED.py +3 -0
  247. scadpy-0.1.0/scadpy/color/constants/WHITE.py +3 -0
  248. scadpy-0.1.0/scadpy/color/constants/YELLOW.py +3 -0
  249. scadpy-0.1.0/scadpy/color/constants/__init__.py +29 -0
  250. scadpy-0.1.0/scadpy/color/type/__init__.py +3 -0
  251. scadpy-0.1.0/scadpy/color/type/color.py +3 -0
  252. scadpy-0.1.0/scadpy/color/utils/__init__.py +3 -0
  253. scadpy-0.1.0/scadpy/color/utils/get_random_color.py +36 -0
  254. scadpy-0.1.0/scadpy/core/__init__.py +3 -0
  255. scadpy-0.1.0/scadpy/core/assembly/__init__.py +5 -0
  256. scadpy-0.1.0/scadpy/core/assembly/combinations/__init__.py +13 -0
  257. scadpy-0.1.0/scadpy/core/assembly/combinations/concat_assemblies.py +50 -0
  258. scadpy-0.1.0/scadpy/core/assembly/combinations/exclude_assemblies.py +135 -0
  259. scadpy-0.1.0/scadpy/core/assembly/combinations/intersect_assemblies.py +128 -0
  260. scadpy-0.1.0/scadpy/core/assembly/combinations/subtract_assemblies.py +151 -0
  261. scadpy-0.1.0/scadpy/core/assembly/combinations/unify_assemblies.py +59 -0
  262. scadpy-0.1.0/scadpy/core/assembly/topologies/__init__.py +41 -0
  263. scadpy-0.1.0/scadpy/core/assembly/topologies/directed_edge/__init__.py +9 -0
  264. scadpy-0.1.0/scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_directions.py +70 -0
  265. scadpy-0.1.0/scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_to_edge.py +49 -0
  266. scadpy-0.1.0/scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_to_vertex.py +54 -0
  267. scadpy-0.1.0/scadpy/core/assembly/topologies/edge/__init__.py +9 -0
  268. scadpy-0.1.0/scadpy/core/assembly/topologies/edge/get_assembly_edge_lengths.py +46 -0
  269. scadpy-0.1.0/scadpy/core/assembly/topologies/edge/get_assembly_edge_midpoints.py +51 -0
  270. scadpy-0.1.0/scadpy/core/assembly/topologies/edge/get_assembly_edge_normals.py +67 -0
  271. scadpy-0.1.0/scadpy/core/assembly/topologies/face_corner/__init__.py +13 -0
  272. scadpy-0.1.0/scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_angles.py +72 -0
  273. scadpy-0.1.0/scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_normals.py +103 -0
  274. scadpy-0.1.0/scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_to_incoming_directed_edge.py +65 -0
  275. scadpy-0.1.0/scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_to_outgoing_directed_edge.py +65 -0
  276. scadpy-0.1.0/scadpy/core/assembly/topologies/face_corner/get_assembly_face_directed_edge_to_corner.py +79 -0
  277. scadpy-0.1.0/scadpy/core/assembly/topologies/part/__init__.py +5 -0
  278. scadpy-0.1.0/scadpy/core/assembly/topologies/part/get_assembly_part_colors.py +55 -0
  279. scadpy-0.1.0/scadpy/core/assembly/topologies/vertex/__init__.py +7 -0
  280. scadpy-0.1.0/scadpy/core/assembly/topologies/vertex/get_assembly_vertex_coordinates.py +70 -0
  281. scadpy-0.1.0/scadpy/core/assembly/topologies/vertex/get_assembly_vertex_to_part.py +62 -0
  282. scadpy-0.1.0/scadpy/core/assembly/transformations/__init__.py +19 -0
  283. scadpy-0.1.0/scadpy/core/assembly/transformations/color_assembly.py +24 -0
  284. scadpy-0.1.0/scadpy/core/assembly/transformations/mirror_vertex_coordinates.py +68 -0
  285. scadpy-0.1.0/scadpy/core/assembly/transformations/pull_vertex_coordinates.py +64 -0
  286. scadpy-0.1.0/scadpy/core/assembly/transformations/push_vertex_coordinates.py +64 -0
  287. scadpy-0.1.0/scadpy/core/assembly/transformations/resize_vertex_coordinates.py +121 -0
  288. scadpy-0.1.0/scadpy/core/assembly/transformations/rotate_vertex_coordinates.py +73 -0
  289. scadpy-0.1.0/scadpy/core/assembly/transformations/scale_vertex_coordinates.py +76 -0
  290. scadpy-0.1.0/scadpy/core/assembly/transformations/translate_vertex_coordinates.py +70 -0
  291. scadpy-0.1.0/scadpy/core/assembly/types/__init__.py +7 -0
  292. scadpy-0.1.0/scadpy/core/assembly/types/assembly.py +14 -0
  293. scadpy-0.1.0/scadpy/core/assembly/types/topology_filter.py +6 -0
  294. scadpy-0.1.0/scadpy/core/assembly/utils/__init__.py +9 -0
  295. scadpy-0.1.0/scadpy/core/assembly/utils/lookup_pairs.py +56 -0
  296. scadpy-0.1.0/scadpy/core/assembly/utils/resolve_topology_filter.py +84 -0
  297. scadpy-0.1.0/scadpy/core/assembly/utils/transform_filtered_parts.py +55 -0
  298. scadpy-0.1.0/scadpy/core/component/__init__.py +3 -0
  299. scadpy-0.1.0/scadpy/core/component/exporters/__init__.py +7 -0
  300. scadpy-0.1.0/scadpy/core/component/exporters/map_component_to_html_file.py +47 -0
  301. scadpy-0.1.0/scadpy/core/component/exporters/map_component_to_screen.py +63 -0
  302. scadpy-0.1.0/scadpy/core/component/features/__init__.py +5 -0
  303. scadpy-0.1.0/scadpy/core/component/features/get_component_bounds.py +38 -0
  304. scadpy-0.1.0/scadpy/core/component/utils/__init__.py +9 -0
  305. scadpy-0.1.0/scadpy/core/component/utils/blend_component_colors.py +77 -0
  306. scadpy-0.1.0/scadpy/core/component/utils/get_intersecting_component_index_groups.py +108 -0
  307. scadpy-0.1.0/scadpy/core/part/__init__.py +3 -0
  308. scadpy-0.1.0/scadpy/core/part/combinations/__init__.py +11 -0
  309. scadpy-0.1.0/scadpy/core/part/combinations/concat_parts.py +48 -0
  310. scadpy-0.1.0/scadpy/core/part/combinations/intersect_parts.py +147 -0
  311. scadpy-0.1.0/scadpy/core/part/combinations/subtract_parts.py +94 -0
  312. scadpy-0.1.0/scadpy/core/part/combinations/unify_parts.py +143 -0
  313. scadpy-0.1.0/scadpy/core/part/types/__init__.py +5 -0
  314. scadpy-0.1.0/scadpy/core/part/types/part.py +34 -0
  315. scadpy-0.1.0/scadpy/core/part/utils/__init__.py +5 -0
  316. scadpy-0.1.0/scadpy/core/part/utils/blend_part_colors.py +32 -0
  317. scadpy-0.1.0/scadpy/d2/__init__.py +2 -0
  318. scadpy-0.1.0/scadpy/d2/shape/__init__.py +9 -0
  319. scadpy-0.1.0/scadpy/d2/shape/combinations/__init__.py +21 -0
  320. scadpy-0.1.0/scadpy/d2/shape/combinations/are_shape_parts_intersecting.py +49 -0
  321. scadpy-0.1.0/scadpy/d2/shape/combinations/concat_shape.py +48 -0
  322. scadpy-0.1.0/scadpy/d2/shape/combinations/exclude_shape.py +71 -0
  323. scadpy-0.1.0/scadpy/d2/shape/combinations/intersect_shape.py +64 -0
  324. scadpy-0.1.0/scadpy/d2/shape/combinations/intersect_shape_parts.py +71 -0
  325. scadpy-0.1.0/scadpy/d2/shape/combinations/subtract_shape.py +72 -0
  326. scadpy-0.1.0/scadpy/d2/shape/combinations/subtract_shape_parts.py +66 -0
  327. scadpy-0.1.0/scadpy/d2/shape/combinations/unify_shape.py +51 -0
  328. scadpy-0.1.0/scadpy/d2/shape/combinations/unify_shape_parts.py +74 -0
  329. scadpy-0.1.0/scadpy/d2/shape/exporters/__init__.py +17 -0
  330. scadpy-0.1.0/scadpy/d2/shape/exporters/map_shape_to_dxf.py +43 -0
  331. scadpy-0.1.0/scadpy/d2/shape/exporters/map_shape_to_dxf_file.py +38 -0
  332. scadpy-0.1.0/scadpy/d2/shape/exporters/map_shape_to_html.py +117 -0
  333. scadpy-0.1.0/scadpy/d2/shape/exporters/map_shape_to_html_file.py +58 -0
  334. scadpy-0.1.0/scadpy/d2/shape/exporters/map_shape_to_screen.py +51 -0
  335. scadpy-0.1.0/scadpy/d2/shape/exporters/map_shape_to_svg.py +40 -0
  336. scadpy-0.1.0/scadpy/d2/shape/exporters/map_shape_to_svg_file.py +38 -0
  337. scadpy-0.1.0/scadpy/d2/shape/features/__init__.py +9 -0
  338. scadpy-0.1.0/scadpy/d2/shape/features/get_shape_bounds.py +40 -0
  339. scadpy-0.1.0/scadpy/d2/shape/features/get_shape_part_bounds.py +37 -0
  340. scadpy-0.1.0/scadpy/d2/shape/features/is_shape_empty.py +38 -0
  341. scadpy-0.1.0/scadpy/d2/shape/importers/__init__.py +13 -0
  342. scadpy-0.1.0/scadpy/d2/shape/importers/map_dxf_to_shape.py +55 -0
  343. scadpy-0.1.0/scadpy/d2/shape/importers/map_geometries_to_shape.py +45 -0
  344. scadpy-0.1.0/scadpy/d2/shape/importers/map_geometry_to_shape.py +43 -0
  345. scadpy-0.1.0/scadpy/d2/shape/importers/map_parts_to_shape.py +62 -0
  346. scadpy-0.1.0/scadpy/d2/shape/importers/map_svg_to_shape.py +55 -0
  347. scadpy-0.1.0/scadpy/d2/shape/primitives/__init__.py +6 -0
  348. scadpy-0.1.0/scadpy/d2/shape/primitives/circle.py +68 -0
  349. scadpy-0.1.0/scadpy/d2/shape/primitives/polygon.py +86 -0
  350. scadpy-0.1.0/scadpy/d2/shape/primitives/rectangle.py +85 -0
  351. scadpy-0.1.0/scadpy/d2/shape/primitives/square.py +57 -0
  352. scadpy-0.1.0/scadpy/d2/shape/topologies/__init__.py +53 -0
  353. scadpy-0.1.0/scadpy/d2/shape/topologies/corner/__init__.py +15 -0
  354. scadpy-0.1.0/scadpy/d2/shape/topologies/corner/are_shape_corners_convex.py +75 -0
  355. scadpy-0.1.0/scadpy/d2/shape/topologies/corner/get_shape_corner_angles.py +58 -0
  356. scadpy-0.1.0/scadpy/d2/shape/topologies/corner/get_shape_corner_normals.py +82 -0
  357. scadpy-0.1.0/scadpy/d2/shape/topologies/corner/get_shape_corner_to_incoming_directed_edge.py +39 -0
  358. scadpy-0.1.0/scadpy/d2/shape/topologies/corner/get_shape_corner_to_outgoing_directed_edge.py +39 -0
  359. scadpy-0.1.0/scadpy/d2/shape/topologies/corner/get_shape_corner_to_vertex.py +65 -0
  360. scadpy-0.1.0/scadpy/d2/shape/topologies/directed_edge/__init__.py +11 -0
  361. scadpy-0.1.0/scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_directions.py +44 -0
  362. scadpy-0.1.0/scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_corner.py +41 -0
  363. scadpy-0.1.0/scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_edge.py +51 -0
  364. scadpy-0.1.0/scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_vertex.py +63 -0
  365. scadpy-0.1.0/scadpy/d2/shape/topologies/edge/__init__.py +11 -0
  366. scadpy-0.1.0/scadpy/d2/shape/topologies/edge/get_shape_edge_lengths.py +43 -0
  367. scadpy-0.1.0/scadpy/d2/shape/topologies/edge/get_shape_edge_midpoints.py +46 -0
  368. scadpy-0.1.0/scadpy/d2/shape/topologies/edge/get_shape_edge_normals.py +40 -0
  369. scadpy-0.1.0/scadpy/d2/shape/topologies/edge/get_shape_edge_to_vertex.py +71 -0
  370. scadpy-0.1.0/scadpy/d2/shape/topologies/ring/__init__.py +7 -0
  371. scadpy-0.1.0/scadpy/d2/shape/topologies/ring/get_shape_ring_to_part.py +46 -0
  372. scadpy-0.1.0/scadpy/d2/shape/topologies/ring/get_shape_ring_types.py +46 -0
  373. scadpy-0.1.0/scadpy/d2/shape/topologies/vertex/__init__.py +11 -0
  374. scadpy-0.1.0/scadpy/d2/shape/topologies/vertex/get_shape_part_vertex_coordinates.py +62 -0
  375. scadpy-0.1.0/scadpy/d2/shape/topologies/vertex/get_shape_vertex_coordinates.py +44 -0
  376. scadpy-0.1.0/scadpy/d2/shape/topologies/vertex/get_shape_vertex_to_part.py +42 -0
  377. scadpy-0.1.0/scadpy/d2/shape/topologies/vertex/get_shape_vertex_to_ring.py +63 -0
  378. scadpy-0.1.0/scadpy/d2/shape/transformations/__init__.py +43 -0
  379. scadpy-0.1.0/scadpy/d2/shape/transformations/chamfer_shape.py +259 -0
  380. scadpy-0.1.0/scadpy/d2/shape/transformations/color_shape.py +46 -0
  381. scadpy-0.1.0/scadpy/d2/shape/transformations/convexify_shape.py +79 -0
  382. scadpy-0.1.0/scadpy/d2/shape/transformations/fill_shape.py +68 -0
  383. scadpy-0.1.0/scadpy/d2/shape/transformations/fillet_shape.py +289 -0
  384. scadpy-0.1.0/scadpy/d2/shape/transformations/grow_shape.py +82 -0
  385. scadpy-0.1.0/scadpy/d2/shape/transformations/linear_cut_shape.py +116 -0
  386. scadpy-0.1.0/scadpy/d2/shape/transformations/linear_extrude_shape.py +60 -0
  387. scadpy-0.1.0/scadpy/d2/shape/transformations/linear_slice_shape.py +144 -0
  388. scadpy-0.1.0/scadpy/d2/shape/transformations/mirror_shape.py +53 -0
  389. scadpy-0.1.0/scadpy/d2/shape/transformations/pull_shape.py +67 -0
  390. scadpy-0.1.0/scadpy/d2/shape/transformations/push_shape.py +67 -0
  391. scadpy-0.1.0/scadpy/d2/shape/transformations/radial_extrude_shape.py +285 -0
  392. scadpy-0.1.0/scadpy/d2/shape/transformations/radial_slice_shape.py +132 -0
  393. scadpy-0.1.0/scadpy/d2/shape/transformations/recoordinate_shape.py +82 -0
  394. scadpy-0.1.0/scadpy/d2/shape/transformations/resize_shape.py +91 -0
  395. scadpy-0.1.0/scadpy/d2/shape/transformations/rotate_shape.py +63 -0
  396. scadpy-0.1.0/scadpy/d2/shape/transformations/scale_shape.py +58 -0
  397. scadpy-0.1.0/scadpy/d2/shape/transformations/shrink_shape.py +69 -0
  398. scadpy-0.1.0/scadpy/d2/shape/transformations/translate_shape.py +54 -0
  399. scadpy-0.1.0/scadpy/d2/shape/types/__init__.py +3 -0
  400. scadpy-0.1.0/scadpy/d2/shape/types/shape.py +792 -0
  401. scadpy-0.1.0/scadpy/d2/shape/types/utils/__init__.py +5 -0
  402. scadpy-0.1.0/scadpy/d2/shape/types/utils/shapely_base_geometry_to_shapely_polygons.py +25 -0
  403. scadpy-0.1.0/scadpy/d2/shape/utils/__init__.py +5 -0
  404. scadpy-0.1.0/scadpy/d2/shape/utils/shapely_base_geometry_to_shapely_polygons.py +55 -0
  405. scadpy-0.1.0/scadpy/d2/utils/__init__.py +3 -0
  406. scadpy-0.1.0/scadpy/d2/utils/resolve_vector_2d.py +50 -0
  407. scadpy-0.1.0/scadpy/d3/__init__.py +2 -0
  408. scadpy-0.1.0/scadpy/d3/solid/__init__.py +8 -0
  409. scadpy-0.1.0/scadpy/d3/solid/combinations/__init__.py +21 -0
  410. scadpy-0.1.0/scadpy/d3/solid/combinations/are_solid_parts_intersecting.py +51 -0
  411. scadpy-0.1.0/scadpy/d3/solid/combinations/concat_solid.py +48 -0
  412. scadpy-0.1.0/scadpy/d3/solid/combinations/exclude_solid.py +71 -0
  413. scadpy-0.1.0/scadpy/d3/solid/combinations/intersect_solid.py +64 -0
  414. scadpy-0.1.0/scadpy/d3/solid/combinations/intersect_solid_parts.py +73 -0
  415. scadpy-0.1.0/scadpy/d3/solid/combinations/subtract_solid.py +72 -0
  416. scadpy-0.1.0/scadpy/d3/solid/combinations/subtract_solid_parts.py +68 -0
  417. scadpy-0.1.0/scadpy/d3/solid/combinations/unify_solid.py +51 -0
  418. scadpy-0.1.0/scadpy/d3/solid/combinations/unify_solid_parts.py +73 -0
  419. scadpy-0.1.0/scadpy/d3/solid/exporters/__init__.py +11 -0
  420. scadpy-0.1.0/scadpy/d3/solid/exporters/map_solid_to_html.py +318 -0
  421. scadpy-0.1.0/scadpy/d3/solid/exporters/map_solid_to_html_file.py +58 -0
  422. scadpy-0.1.0/scadpy/d3/solid/exporters/map_solid_to_screen.py +51 -0
  423. scadpy-0.1.0/scadpy/d3/solid/exporters/map_solid_to_stl_file.py +48 -0
  424. scadpy-0.1.0/scadpy/d3/solid/features/__init__.py +11 -0
  425. scadpy-0.1.0/scadpy/d3/solid/features/get_solid_bounds.py +37 -0
  426. scadpy-0.1.0/scadpy/d3/solid/features/get_solid_part_bounds.py +37 -0
  427. scadpy-0.1.0/scadpy/d3/solid/features/get_solid_part_colors.py +39 -0
  428. scadpy-0.1.0/scadpy/d3/solid/features/is_solid_empty.py +36 -0
  429. scadpy-0.1.0/scadpy/d3/solid/importers/__init__.py +11 -0
  430. scadpy-0.1.0/scadpy/d3/solid/importers/map_geometries_to_solid.py +42 -0
  431. scadpy-0.1.0/scadpy/d3/solid/importers/map_geometry_to_solid.py +42 -0
  432. scadpy-0.1.0/scadpy/d3/solid/importers/map_parts_to_solid.py +66 -0
  433. scadpy-0.1.0/scadpy/d3/solid/importers/map_stl_to_solid.py +37 -0
  434. scadpy-0.1.0/scadpy/d3/solid/primitives/__init__.py +7 -0
  435. scadpy-0.1.0/scadpy/d3/solid/primitives/cone.py +70 -0
  436. scadpy-0.1.0/scadpy/d3/solid/primitives/cuboid.py +75 -0
  437. scadpy-0.1.0/scadpy/d3/solid/primitives/cylinder.py +73 -0
  438. scadpy-0.1.0/scadpy/d3/solid/primitives/polyhedron.py +60 -0
  439. scadpy-0.1.0/scadpy/d3/solid/primitives/sphere.py +58 -0
  440. scadpy-0.1.0/scadpy/d3/solid/topologies/__init__.py +8 -0
  441. scadpy-0.1.0/scadpy/d3/solid/topologies/triangle/__init__.py +5 -0
  442. scadpy-0.1.0/scadpy/d3/solid/topologies/triangle/get_solid_triangle_to_vertex.py +49 -0
  443. scadpy-0.1.0/scadpy/d3/solid/topologies/vertex/__init__.py +7 -0
  444. scadpy-0.1.0/scadpy/d3/solid/topologies/vertex/get_solid_vertex_coordinates.py +39 -0
  445. scadpy-0.1.0/scadpy/d3/solid/topologies/vertex/get_solid_vertex_to_part.py +37 -0
  446. scadpy-0.1.0/scadpy/d3/solid/transformations/__init__.py +23 -0
  447. scadpy-0.1.0/scadpy/d3/solid/transformations/color_solid.py +46 -0
  448. scadpy-0.1.0/scadpy/d3/solid/transformations/convexify_solid.py +64 -0
  449. scadpy-0.1.0/scadpy/d3/solid/transformations/mirror_solid.py +53 -0
  450. scadpy-0.1.0/scadpy/d3/solid/transformations/pull_solid.py +67 -0
  451. scadpy-0.1.0/scadpy/d3/solid/transformations/push_solid.py +67 -0
  452. scadpy-0.1.0/scadpy/d3/solid/transformations/recoordinate_solid.py +68 -0
  453. scadpy-0.1.0/scadpy/d3/solid/transformations/resize_solid.py +92 -0
  454. scadpy-0.1.0/scadpy/d3/solid/transformations/rotate_solid.py +93 -0
  455. scadpy-0.1.0/scadpy/d3/solid/transformations/scale_solid.py +58 -0
  456. scadpy-0.1.0/scadpy/d3/solid/transformations/translate_solid.py +54 -0
  457. scadpy-0.1.0/scadpy/d3/solid/types/__init__.py +3 -0
  458. scadpy-0.1.0/scadpy/d3/solid/types/solid.py +448 -0
  459. scadpy-0.1.0/scadpy/d3/utils/__init__.py +3 -0
  460. scadpy-0.1.0/scadpy/d3/utils/resolve_vector_3d.py +50 -0
  461. scadpy-0.1.0/scadpy/utils/__init__.py +6 -0
  462. scadpy-0.1.0/scadpy/utils/resolve_vector.py +64 -0
  463. scadpy-0.1.0/scadpy/utils/x.py +38 -0
  464. scadpy-0.1.0/scadpy/utils/y.py +38 -0
  465. scadpy-0.1.0/scadpy/utils/z.py +38 -0
@@ -0,0 +1,24 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.12"
16
+
17
+ - name: Install system dependencies
18
+ run: sudo apt-get install -y libegl1
19
+
20
+ - name: Install dependencies
21
+ run: pip install -e .[dev]
22
+
23
+ - name: Run doctests
24
+ run: cd docs && make doctest
@@ -0,0 +1,54 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ environment:
12
+ name: github-pages
13
+ url: ${{ steps.pages.outputs.page_url }}
14
+ permissions:
15
+ contents: write
16
+ pages: write
17
+ id-token: write
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+
26
+ - name: Install system dependencies
27
+ run: sudo apt-get install -y libegl1
28
+
29
+ - name: Install dependencies
30
+ run: pip install -e .[dev] build
31
+
32
+ - name: Run doctests
33
+ run: cd docs && make doctest
34
+
35
+ - name: Build documentation
36
+ run: cd docs && make html
37
+
38
+ - name: Disable Jekyll
39
+ run: touch docs/build/html/.nojekyll
40
+
41
+ - name: Upload Pages artifact
42
+ uses: actions/upload-pages-artifact@v3
43
+ with:
44
+ path: docs/build/html
45
+
46
+ - name: Deploy to GitHub Pages
47
+ id: pages
48
+ uses: actions/deploy-pages@v4
49
+
50
+ - name: Build wheel
51
+ run: python -m build
52
+
53
+ - name: Publish to PyPI
54
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,43 @@
1
+ # --- Virtual environments ---
2
+ .venv/
3
+ venv/
4
+
5
+ # --- Python cache ---
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+ .ropeproject/
10
+
11
+ # --- Build and distribution folders ---
12
+ build/
13
+ dist/
14
+ *.egg-info/
15
+ .eggs/
16
+
17
+ # --- Documentation build ---
18
+ docs/build/
19
+
20
+ # --- Logs and temporary files ---
21
+ *.log
22
+ *.tmp
23
+
24
+ # --- Environment and local config files ---
25
+ .env
26
+ .DS_Store
27
+ .idea/
28
+ .vscode/
29
+ .zed/*
30
+ !.zed/settings.json # keep only shared settings
31
+
32
+ # --- Test and coverage files ---
33
+ .coverage
34
+ htmlcov/
35
+ .tox/
36
+ .nox/
37
+ pytest_cache/
38
+ tests/
39
+
40
+ # --- Type checker cache ---
41
+ .mypy_cache/
42
+ .pytype/
43
+ .pyre/
@@ -0,0 +1,43 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2026 m-fabregue
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ ## Third-party dependencies
26
+
27
+ ScadPy depends on the following third-party libraries, each distributed under
28
+ their own terms:
29
+
30
+ | Package | License |
31
+ |---------|---------|
32
+ | [trimesh](https://github.com/mikedh/trimesh) | MIT |
33
+ | [Shapely](https://github.com/shapely/shapely) | BSD 3-Clause |
34
+ | [typeguard](https://github.com/agronholm/typeguard) | MIT |
35
+ | [IPython](https://github.com/ipython/ipython) | BSD 3-Clause |
36
+ | [PySide6](https://doc.qt.io/qtforpython) | LGPL v3 |
37
+ | [triangle](https://github.com/drufat/triangle) | See note below |
38
+
39
+ **Note on `triangle`:** The `triangle` package wraps Jonathan Shewchuk's
40
+ Triangle library, which restricts commercial use without written permission
41
+ from the author. Users intending commercial applications should review
42
+ [Triangle's license](https://www.cs.cmu.edu/~quake/triangle.html) and
43
+ consider replacing the `triangle` dependency accordingly.
scadpy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,282 @@
1
+ Metadata-Version: 2.4
2
+ Name: ScadPy
3
+ Version: 0.1.0
4
+ Summary: Simplified 2D/3D modeling for Python with fluent API and boolean operations
5
+ Author: m-fabregue
6
+ License: # MIT License
7
+
8
+ Copyright (c) 2026 m-fabregue
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ ---
29
+
30
+ ## Third-party dependencies
31
+
32
+ ScadPy depends on the following third-party libraries, each distributed under
33
+ their own terms:
34
+
35
+ | Package | License |
36
+ |---------|---------|
37
+ | [trimesh](https://github.com/mikedh/trimesh) | MIT |
38
+ | [Shapely](https://github.com/shapely/shapely) | BSD 3-Clause |
39
+ | [typeguard](https://github.com/agronholm/typeguard) | MIT |
40
+ | [IPython](https://github.com/ipython/ipython) | BSD 3-Clause |
41
+ | [PySide6](https://doc.qt.io/qtforpython) | LGPL v3 |
42
+ | [triangle](https://github.com/drufat/triangle) | See note below |
43
+
44
+ **Note on `triangle`:** The `triangle` package wraps Jonathan Shewchuk's
45
+ Triangle library, which restricts commercial use without written permission
46
+ from the author. Users intending commercial applications should review
47
+ [Triangle's license](https://www.cs.cmu.edu/~quake/triangle.html) and
48
+ consider replacing the `triangle` dependency accordingly.
49
+ License-File: LICENSE.md
50
+ Keywords: 2d,3d,modeling,python,scad,shape,solid
51
+ Classifier: Development Status :: 3 - Alpha
52
+ Requires-Python: >=3.12
53
+ Requires-Dist: ipython~=8.30
54
+ Requires-Dist: matplotlib~=3.10
55
+ Requires-Dist: pyside6~=6.10
56
+ Requires-Dist: triangle==20250106
57
+ Requires-Dist: trimesh[easy]~=4.10
58
+ Requires-Dist: typeguard~=4.4
59
+ Provides-Extra: dev
60
+ Requires-Dist: coverage; extra == 'dev'
61
+ Requires-Dist: furo; extra == 'dev'
62
+ Requires-Dist: genbadge[coverage]; extra == 'dev'
63
+ Requires-Dist: interrogate; extra == 'dev'
64
+ Requires-Dist: numpydoc; extra == 'dev'
65
+ Requires-Dist: sphinx; extra == 'dev'
66
+ Requires-Dist: sphinx-autodoc-typehints; extra == 'dev'
67
+ Requires-Dist: sphinx-pyproject; extra == 'dev'
68
+ Description-Content-Type: text/markdown
69
+
70
+ # ScadPy
71
+
72
+ ![test coverage](docs/_static/badges/coverage.svg)
73
+ ![doc coverage](docs/_static/badges/interrogate.svg)
74
+
75
+ **Programmatic CAD in Pure Python.**
76
+
77
+ ScadPy provides a fluent, type-safe API for 2D and 3D parametric modeling,
78
+ built on [Shapely](https://shapely.readthedocs.io) and
79
+ [trimesh](https://trimesh.org).
80
+ Write designs with the conciseness of OpenSCAD and the full power of Python.
81
+
82
+ ## Installation
83
+
84
+ ```bash
85
+ pip install scadpy
86
+ ```
87
+
88
+ Requirements: Python ≥ 3.12.
89
+
90
+ ## Quick examples
91
+
92
+ ```python
93
+ # 2D — chamfered mounting plate
94
+ from scadpy import *
95
+ import numpy as np
96
+
97
+ PLATE_WIDTH = 80
98
+ PLATE_HEIGHT = 50
99
+ HOLE_RADIUS = 4
100
+ HOLE_MARGIN = 10
101
+ CHAMFER_SIZE = 8
102
+
103
+ base = rectangle([PLATE_WIDTH, PLATE_HEIGHT])
104
+ plate = base.chamfer(CHAMFER_SIZE)
105
+ corner_coordinates = base.vertex_coordinates[base.corner_to_vertex[:, 1]]
106
+
107
+ for position, normal in zip(corner_coordinates, base.corner_normals):
108
+ hole_center = position - HOLE_MARGIN * np.sqrt(2) * normal
109
+ plate -= circle(HOLE_RADIUS).translate(hole_center)
110
+ ```
111
+
112
+ ```python
113
+ # 3D — parametric ball bearing
114
+ import numpy as np
115
+ from scadpy import *
116
+
117
+ BALL_RADIUS = 3
118
+ RACE_RADIUS = 15
119
+ NB_BALLS = 11
120
+ CLEARANCE = 0.1
121
+ RING_HEIGHT = 7
122
+ RACE_THICKNESS = 10
123
+
124
+ groove = circle(BALL_RADIUS + CLEARANCE) | rectangle([BALL_RADIUS, RING_HEIGHT])
125
+ race = rectangle([RACE_THICKNESS, RING_HEIGHT]) - groove
126
+ race = race.radial_extrude(axis=y(1), pivot=x(RACE_RADIUS))
127
+
128
+ balls = Solid()
129
+ for angle in np.linspace(0, 360, NB_BALLS, endpoint=False):
130
+ balls += sphere(BALL_RADIUS).rotate(angle, axis=y(1), pivot=x(RACE_RADIUS))
131
+
132
+ bearing = race + balls
133
+ ```
134
+
135
+ ## Cheat sheet
136
+
137
+ *Parameters shown in `# comments` are optional, with their default values.*
138
+
139
+ **2D — Shape**
140
+
141
+ ```python
142
+ from scadpy import *
143
+
144
+ # primitives
145
+ circle(radius=3) # segment_count=64
146
+ polygon(points=[(-2, -2), (2, -2), (0, 2)])
147
+ rectangle(size=[6, 3])
148
+ Shape.from_dxf("file.dxf")
149
+ Shape.from_svg("file.svg")
150
+ square(size=4)
151
+
152
+ # boolean operations
153
+ s = square(size=4); c = circle(radius=3)
154
+ s | c # union
155
+ s - c # difference
156
+ s & c # intersection
157
+ s ^ c # symmetric difference
158
+ s + c # concat (no merge)
159
+
160
+ # transforms
161
+ s.chamfer(size=0.8) # corner_filter=None, epsilon=1e-8
162
+ s.color(color=RED)
163
+ s.convexify() # part_filter=None
164
+ s.fill() # part_filter=None
165
+ s.fillet(size=0.8) # corner_filter=None, segment_count=32, epsilon=1e-8
166
+ s.grow(distance=0.5) # part_filter=None
167
+ s.linear_cut(axis=x(1)) # pivot=0
168
+ s.linear_slice(thickness=2, direction=x(1)) # pivot=0, part_filter=None
169
+ s.mirror(normal=[1, 0]) # pivot=0
170
+ s.pull(distance=1.0) # pivot=0, vertex_filter=None
171
+ s.push(distance=1.0) # pivot=0, vertex_filter=None
172
+ s.radial_slice(start=0, end=180) # pivot=0, part_filter=None
173
+ s.resize(size=[6, None]) # auto=False, pivot=None, vertex_filter=None
174
+ s.rotate(angle=30) # pivot=0, vertex_filter=None
175
+ s.scale(scale=[2, 0.5]) # pivot=0, vertex_filter=None
176
+ s.shrink(distance=0.5) # part_filter=None
177
+ s.translate(translation=[2, 1]) # vertex_filter=None
178
+
179
+ # topology — coordinates & attributes
180
+ s.are_corners_convex # (n_corners,) — convexity mask
181
+ s.corner_angles # (n_corners,) — interior angles (°)
182
+ s.corner_normals # (n_corners, 2) — outward unit normals
183
+ s.directed_edge_directions # (2*n_edges, 2)
184
+ s.edge_lengths # (n_edges,)
185
+ s.edge_midpoints # (n_edges, 2)
186
+ s.edge_normals # (n_edges, 2)
187
+ s.ring_types # (n_rings,) — "exterior"|"interior"
188
+ s.vertex_coordinates # (n_vertices, 2)
189
+
190
+ # topology — bridges (*_to_*)
191
+ s.corner_to_incoming_directed_edge # corner → directed_edge
192
+ s.corner_to_outgoing_directed_edge # corner → directed_edge
193
+ s.corner_to_vertex # corner → [prev, curr, next]
194
+ s.directed_edge_to_corner # directed_edge → [source, target]
195
+ s.directed_edge_to_edge # directed_edge → edge
196
+ s.directed_edge_to_vertex # directed_edge → [start, end]
197
+ s.edge_to_vertex # edge → [start, end]
198
+ s.ring_to_part # ring → part
199
+ s.vertex_to_part # vertex → part
200
+ s.vertex_to_ring # vertex → ring
201
+
202
+ # extrusions → Solid
203
+ s.linear_extrude(height=3)
204
+ s.radial_extrude(axis=y(1), pivot=x(5)) # start=0, end=360, segment_count=64
205
+
206
+ # export
207
+ s.to_dxf_file("output.dxf")
208
+ s.to_html_file("output.html")
209
+ s.to_screen()
210
+ s.to_svg_file("output.svg")
211
+ ```
212
+
213
+ **3D — Solid**
214
+
215
+ ```python
216
+ from scadpy import *
217
+
218
+ # primitives
219
+ cone(radius=2, height=4) # section_count=32
220
+ cuboid(size=[4, 3, 2])
221
+ cylinder(radius=2, height=4) # section_count=32
222
+ polyhedron(vertices=vertices, faces=faces)
223
+ sphere(radius=3) # subdivision_count=4
224
+ Solid.from_stl("model.stl")
225
+
226
+ # boolean operations
227
+ a = cuboid(size=[4, 3, 2]); b = sphere(radius=2)
228
+ a | b # union
229
+ a - b # difference
230
+ a & b # intersection
231
+ a ^ b # symmetric difference
232
+ a + b # concat (no merge)
233
+
234
+ # transforms
235
+ a.color(color=RED)
236
+ a.convexify() # part_filter=None
237
+ a.mirror(normal=[1, 0, 0]) # pivot=0
238
+ a.pull(distance=1.0) # pivot=0, vertex_filter=None
239
+ a.push(distance=1.0) # pivot=0, vertex_filter=None
240
+ a.resize(size=[6, None, None]) # auto=False, pivot=None, vertex_filter=None
241
+ a.rotate(angle=30, axis=z(1)) # pivot=0, vertex_filter=None
242
+ a.scale(scale=[2, 1, 0.5]) # pivot=0, vertex_filter=None
243
+ a.translate(translation=[1, 0, 0]) # vertex_filter=None
244
+
245
+ # topology — coordinates & bridges (*_to_*)
246
+ a.triangle_to_vertex # triangle → [v0, v1, v2]
247
+ a.vertex_coordinates # (n_vertices, 3)
248
+ a.vertex_to_part # vertex → part
249
+
250
+ # export
251
+ a.to_html_file("output.html")
252
+ a.to_screen()
253
+ a.to_stl_file("output.stl")
254
+ ```
255
+
256
+ ## Roadmap
257
+
258
+ - Improve documentation
259
+ - Richer topology for Shape and Solid
260
+ - Richer transformations for Shape and Solid
261
+ - Chamfer and fillet on Solid
262
+ - New assembly types: `PointCloud2d`, `Wire2d`, `PointCloud3d`, `Wire3d`
263
+ - Better error messages
264
+ - More import/export formats
265
+
266
+ ## Development
267
+
268
+ ```bash
269
+ # Create and activate venv
270
+ python3 -m venv .venv
271
+ source .venv/bin/activate
272
+
273
+ # Install with dev dependencies
274
+ pip install -e .[dev]
275
+
276
+ # Run doctests & generate documentation
277
+ cd docs && make doctest && make html
278
+ ```
279
+
280
+ ## License
281
+
282
+ See [LICENSE.md](LICENSE.md).
scadpy-0.1.0/README.md ADDED
@@ -0,0 +1,213 @@
1
+ # ScadPy
2
+
3
+ ![test coverage](docs/_static/badges/coverage.svg)
4
+ ![doc coverage](docs/_static/badges/interrogate.svg)
5
+
6
+ **Programmatic CAD in Pure Python.**
7
+
8
+ ScadPy provides a fluent, type-safe API for 2D and 3D parametric modeling,
9
+ built on [Shapely](https://shapely.readthedocs.io) and
10
+ [trimesh](https://trimesh.org).
11
+ Write designs with the conciseness of OpenSCAD and the full power of Python.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install scadpy
17
+ ```
18
+
19
+ Requirements: Python ≥ 3.12.
20
+
21
+ ## Quick examples
22
+
23
+ ```python
24
+ # 2D — chamfered mounting plate
25
+ from scadpy import *
26
+ import numpy as np
27
+
28
+ PLATE_WIDTH = 80
29
+ PLATE_HEIGHT = 50
30
+ HOLE_RADIUS = 4
31
+ HOLE_MARGIN = 10
32
+ CHAMFER_SIZE = 8
33
+
34
+ base = rectangle([PLATE_WIDTH, PLATE_HEIGHT])
35
+ plate = base.chamfer(CHAMFER_SIZE)
36
+ corner_coordinates = base.vertex_coordinates[base.corner_to_vertex[:, 1]]
37
+
38
+ for position, normal in zip(corner_coordinates, base.corner_normals):
39
+ hole_center = position - HOLE_MARGIN * np.sqrt(2) * normal
40
+ plate -= circle(HOLE_RADIUS).translate(hole_center)
41
+ ```
42
+
43
+ ```python
44
+ # 3D — parametric ball bearing
45
+ import numpy as np
46
+ from scadpy import *
47
+
48
+ BALL_RADIUS = 3
49
+ RACE_RADIUS = 15
50
+ NB_BALLS = 11
51
+ CLEARANCE = 0.1
52
+ RING_HEIGHT = 7
53
+ RACE_THICKNESS = 10
54
+
55
+ groove = circle(BALL_RADIUS + CLEARANCE) | rectangle([BALL_RADIUS, RING_HEIGHT])
56
+ race = rectangle([RACE_THICKNESS, RING_HEIGHT]) - groove
57
+ race = race.radial_extrude(axis=y(1), pivot=x(RACE_RADIUS))
58
+
59
+ balls = Solid()
60
+ for angle in np.linspace(0, 360, NB_BALLS, endpoint=False):
61
+ balls += sphere(BALL_RADIUS).rotate(angle, axis=y(1), pivot=x(RACE_RADIUS))
62
+
63
+ bearing = race + balls
64
+ ```
65
+
66
+ ## Cheat sheet
67
+
68
+ *Parameters shown in `# comments` are optional, with their default values.*
69
+
70
+ **2D — Shape**
71
+
72
+ ```python
73
+ from scadpy import *
74
+
75
+ # primitives
76
+ circle(radius=3) # segment_count=64
77
+ polygon(points=[(-2, -2), (2, -2), (0, 2)])
78
+ rectangle(size=[6, 3])
79
+ Shape.from_dxf("file.dxf")
80
+ Shape.from_svg("file.svg")
81
+ square(size=4)
82
+
83
+ # boolean operations
84
+ s = square(size=4); c = circle(radius=3)
85
+ s | c # union
86
+ s - c # difference
87
+ s & c # intersection
88
+ s ^ c # symmetric difference
89
+ s + c # concat (no merge)
90
+
91
+ # transforms
92
+ s.chamfer(size=0.8) # corner_filter=None, epsilon=1e-8
93
+ s.color(color=RED)
94
+ s.convexify() # part_filter=None
95
+ s.fill() # part_filter=None
96
+ s.fillet(size=0.8) # corner_filter=None, segment_count=32, epsilon=1e-8
97
+ s.grow(distance=0.5) # part_filter=None
98
+ s.linear_cut(axis=x(1)) # pivot=0
99
+ s.linear_slice(thickness=2, direction=x(1)) # pivot=0, part_filter=None
100
+ s.mirror(normal=[1, 0]) # pivot=0
101
+ s.pull(distance=1.0) # pivot=0, vertex_filter=None
102
+ s.push(distance=1.0) # pivot=0, vertex_filter=None
103
+ s.radial_slice(start=0, end=180) # pivot=0, part_filter=None
104
+ s.resize(size=[6, None]) # auto=False, pivot=None, vertex_filter=None
105
+ s.rotate(angle=30) # pivot=0, vertex_filter=None
106
+ s.scale(scale=[2, 0.5]) # pivot=0, vertex_filter=None
107
+ s.shrink(distance=0.5) # part_filter=None
108
+ s.translate(translation=[2, 1]) # vertex_filter=None
109
+
110
+ # topology — coordinates & attributes
111
+ s.are_corners_convex # (n_corners,) — convexity mask
112
+ s.corner_angles # (n_corners,) — interior angles (°)
113
+ s.corner_normals # (n_corners, 2) — outward unit normals
114
+ s.directed_edge_directions # (2*n_edges, 2)
115
+ s.edge_lengths # (n_edges,)
116
+ s.edge_midpoints # (n_edges, 2)
117
+ s.edge_normals # (n_edges, 2)
118
+ s.ring_types # (n_rings,) — "exterior"|"interior"
119
+ s.vertex_coordinates # (n_vertices, 2)
120
+
121
+ # topology — bridges (*_to_*)
122
+ s.corner_to_incoming_directed_edge # corner → directed_edge
123
+ s.corner_to_outgoing_directed_edge # corner → directed_edge
124
+ s.corner_to_vertex # corner → [prev, curr, next]
125
+ s.directed_edge_to_corner # directed_edge → [source, target]
126
+ s.directed_edge_to_edge # directed_edge → edge
127
+ s.directed_edge_to_vertex # directed_edge → [start, end]
128
+ s.edge_to_vertex # edge → [start, end]
129
+ s.ring_to_part # ring → part
130
+ s.vertex_to_part # vertex → part
131
+ s.vertex_to_ring # vertex → ring
132
+
133
+ # extrusions → Solid
134
+ s.linear_extrude(height=3)
135
+ s.radial_extrude(axis=y(1), pivot=x(5)) # start=0, end=360, segment_count=64
136
+
137
+ # export
138
+ s.to_dxf_file("output.dxf")
139
+ s.to_html_file("output.html")
140
+ s.to_screen()
141
+ s.to_svg_file("output.svg")
142
+ ```
143
+
144
+ **3D — Solid**
145
+
146
+ ```python
147
+ from scadpy import *
148
+
149
+ # primitives
150
+ cone(radius=2, height=4) # section_count=32
151
+ cuboid(size=[4, 3, 2])
152
+ cylinder(radius=2, height=4) # section_count=32
153
+ polyhedron(vertices=vertices, faces=faces)
154
+ sphere(radius=3) # subdivision_count=4
155
+ Solid.from_stl("model.stl")
156
+
157
+ # boolean operations
158
+ a = cuboid(size=[4, 3, 2]); b = sphere(radius=2)
159
+ a | b # union
160
+ a - b # difference
161
+ a & b # intersection
162
+ a ^ b # symmetric difference
163
+ a + b # concat (no merge)
164
+
165
+ # transforms
166
+ a.color(color=RED)
167
+ a.convexify() # part_filter=None
168
+ a.mirror(normal=[1, 0, 0]) # pivot=0
169
+ a.pull(distance=1.0) # pivot=0, vertex_filter=None
170
+ a.push(distance=1.0) # pivot=0, vertex_filter=None
171
+ a.resize(size=[6, None, None]) # auto=False, pivot=None, vertex_filter=None
172
+ a.rotate(angle=30, axis=z(1)) # pivot=0, vertex_filter=None
173
+ a.scale(scale=[2, 1, 0.5]) # pivot=0, vertex_filter=None
174
+ a.translate(translation=[1, 0, 0]) # vertex_filter=None
175
+
176
+ # topology — coordinates & bridges (*_to_*)
177
+ a.triangle_to_vertex # triangle → [v0, v1, v2]
178
+ a.vertex_coordinates # (n_vertices, 3)
179
+ a.vertex_to_part # vertex → part
180
+
181
+ # export
182
+ a.to_html_file("output.html")
183
+ a.to_screen()
184
+ a.to_stl_file("output.stl")
185
+ ```
186
+
187
+ ## Roadmap
188
+
189
+ - Improve documentation
190
+ - Richer topology for Shape and Solid
191
+ - Richer transformations for Shape and Solid
192
+ - Chamfer and fillet on Solid
193
+ - New assembly types: `PointCloud2d`, `Wire2d`, `PointCloud3d`, `Wire3d`
194
+ - Better error messages
195
+ - More import/export formats
196
+
197
+ ## Development
198
+
199
+ ```bash
200
+ # Create and activate venv
201
+ python3 -m venv .venv
202
+ source .venv/bin/activate
203
+
204
+ # Install with dev dependencies
205
+ pip install -e .[dev]
206
+
207
+ # Run doctests & generate documentation
208
+ cd docs && make doctest && make html
209
+ ```
210
+
211
+ ## License
212
+
213
+ See [LICENSE.md](LICENSE.md).