ScadPy 0.1.0__py3-none-any.whl

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 (236) hide show
  1. scadpy/__init__.py +5 -0
  2. scadpy/color/__init__.py +3 -0
  3. scadpy/color/constants/BEIGE.py +3 -0
  4. scadpy/color/constants/BLACK.py +3 -0
  5. scadpy/color/constants/BLUE.py +3 -0
  6. scadpy/color/constants/BROWN.py +3 -0
  7. scadpy/color/constants/DARK_GRAY.py +3 -0
  8. scadpy/color/constants/DEFAULT_COLOR.py +3 -0
  9. scadpy/color/constants/DEFAULT_OPACITY.py +1 -0
  10. scadpy/color/constants/GRAY.py +3 -0
  11. scadpy/color/constants/GREEN.py +3 -0
  12. scadpy/color/constants/ORANGE.py +3 -0
  13. scadpy/color/constants/RED.py +3 -0
  14. scadpy/color/constants/WHITE.py +3 -0
  15. scadpy/color/constants/YELLOW.py +3 -0
  16. scadpy/color/constants/__init__.py +29 -0
  17. scadpy/color/type/__init__.py +3 -0
  18. scadpy/color/type/color.py +3 -0
  19. scadpy/color/utils/__init__.py +3 -0
  20. scadpy/color/utils/get_random_color.py +36 -0
  21. scadpy/core/__init__.py +3 -0
  22. scadpy/core/assembly/__init__.py +5 -0
  23. scadpy/core/assembly/combinations/__init__.py +13 -0
  24. scadpy/core/assembly/combinations/concat_assemblies.py +50 -0
  25. scadpy/core/assembly/combinations/exclude_assemblies.py +135 -0
  26. scadpy/core/assembly/combinations/intersect_assemblies.py +128 -0
  27. scadpy/core/assembly/combinations/subtract_assemblies.py +151 -0
  28. scadpy/core/assembly/combinations/unify_assemblies.py +59 -0
  29. scadpy/core/assembly/topologies/__init__.py +41 -0
  30. scadpy/core/assembly/topologies/directed_edge/__init__.py +9 -0
  31. scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_directions.py +70 -0
  32. scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_to_edge.py +49 -0
  33. scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_to_vertex.py +54 -0
  34. scadpy/core/assembly/topologies/edge/__init__.py +9 -0
  35. scadpy/core/assembly/topologies/edge/get_assembly_edge_lengths.py +46 -0
  36. scadpy/core/assembly/topologies/edge/get_assembly_edge_midpoints.py +51 -0
  37. scadpy/core/assembly/topologies/edge/get_assembly_edge_normals.py +67 -0
  38. scadpy/core/assembly/topologies/face_corner/__init__.py +13 -0
  39. scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_angles.py +72 -0
  40. scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_normals.py +103 -0
  41. scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_to_incoming_directed_edge.py +65 -0
  42. scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_to_outgoing_directed_edge.py +65 -0
  43. scadpy/core/assembly/topologies/face_corner/get_assembly_face_directed_edge_to_corner.py +79 -0
  44. scadpy/core/assembly/topologies/part/__init__.py +5 -0
  45. scadpy/core/assembly/topologies/part/get_assembly_part_colors.py +55 -0
  46. scadpy/core/assembly/topologies/vertex/__init__.py +7 -0
  47. scadpy/core/assembly/topologies/vertex/get_assembly_vertex_coordinates.py +70 -0
  48. scadpy/core/assembly/topologies/vertex/get_assembly_vertex_to_part.py +62 -0
  49. scadpy/core/assembly/transformations/__init__.py +19 -0
  50. scadpy/core/assembly/transformations/color_assembly.py +24 -0
  51. scadpy/core/assembly/transformations/mirror_vertex_coordinates.py +68 -0
  52. scadpy/core/assembly/transformations/pull_vertex_coordinates.py +64 -0
  53. scadpy/core/assembly/transformations/push_vertex_coordinates.py +64 -0
  54. scadpy/core/assembly/transformations/resize_vertex_coordinates.py +121 -0
  55. scadpy/core/assembly/transformations/rotate_vertex_coordinates.py +73 -0
  56. scadpy/core/assembly/transformations/scale_vertex_coordinates.py +76 -0
  57. scadpy/core/assembly/transformations/translate_vertex_coordinates.py +70 -0
  58. scadpy/core/assembly/types/__init__.py +7 -0
  59. scadpy/core/assembly/types/assembly.py +14 -0
  60. scadpy/core/assembly/types/topology_filter.py +6 -0
  61. scadpy/core/assembly/utils/__init__.py +9 -0
  62. scadpy/core/assembly/utils/lookup_pairs.py +56 -0
  63. scadpy/core/assembly/utils/resolve_topology_filter.py +84 -0
  64. scadpy/core/assembly/utils/transform_filtered_parts.py +55 -0
  65. scadpy/core/component/__init__.py +3 -0
  66. scadpy/core/component/exporters/__init__.py +7 -0
  67. scadpy/core/component/exporters/map_component_to_html_file.py +47 -0
  68. scadpy/core/component/exporters/map_component_to_screen.py +63 -0
  69. scadpy/core/component/features/__init__.py +5 -0
  70. scadpy/core/component/features/get_component_bounds.py +38 -0
  71. scadpy/core/component/utils/__init__.py +9 -0
  72. scadpy/core/component/utils/blend_component_colors.py +77 -0
  73. scadpy/core/component/utils/get_intersecting_component_index_groups.py +108 -0
  74. scadpy/core/part/__init__.py +3 -0
  75. scadpy/core/part/combinations/__init__.py +11 -0
  76. scadpy/core/part/combinations/concat_parts.py +48 -0
  77. scadpy/core/part/combinations/intersect_parts.py +147 -0
  78. scadpy/core/part/combinations/subtract_parts.py +94 -0
  79. scadpy/core/part/combinations/unify_parts.py +143 -0
  80. scadpy/core/part/types/__init__.py +5 -0
  81. scadpy/core/part/types/part.py +34 -0
  82. scadpy/core/part/utils/__init__.py +5 -0
  83. scadpy/core/part/utils/blend_part_colors.py +32 -0
  84. scadpy/d2/__init__.py +2 -0
  85. scadpy/d2/shape/__init__.py +9 -0
  86. scadpy/d2/shape/combinations/__init__.py +21 -0
  87. scadpy/d2/shape/combinations/are_shape_parts_intersecting.py +49 -0
  88. scadpy/d2/shape/combinations/concat_shape.py +48 -0
  89. scadpy/d2/shape/combinations/exclude_shape.py +71 -0
  90. scadpy/d2/shape/combinations/intersect_shape.py +64 -0
  91. scadpy/d2/shape/combinations/intersect_shape_parts.py +71 -0
  92. scadpy/d2/shape/combinations/subtract_shape.py +72 -0
  93. scadpy/d2/shape/combinations/subtract_shape_parts.py +66 -0
  94. scadpy/d2/shape/combinations/unify_shape.py +51 -0
  95. scadpy/d2/shape/combinations/unify_shape_parts.py +74 -0
  96. scadpy/d2/shape/exporters/__init__.py +17 -0
  97. scadpy/d2/shape/exporters/map_shape_to_dxf.py +43 -0
  98. scadpy/d2/shape/exporters/map_shape_to_dxf_file.py +38 -0
  99. scadpy/d2/shape/exporters/map_shape_to_html.py +117 -0
  100. scadpy/d2/shape/exporters/map_shape_to_html_file.py +58 -0
  101. scadpy/d2/shape/exporters/map_shape_to_screen.py +51 -0
  102. scadpy/d2/shape/exporters/map_shape_to_svg.py +40 -0
  103. scadpy/d2/shape/exporters/map_shape_to_svg_file.py +38 -0
  104. scadpy/d2/shape/features/__init__.py +9 -0
  105. scadpy/d2/shape/features/get_shape_bounds.py +40 -0
  106. scadpy/d2/shape/features/get_shape_part_bounds.py +37 -0
  107. scadpy/d2/shape/features/is_shape_empty.py +38 -0
  108. scadpy/d2/shape/importers/__init__.py +13 -0
  109. scadpy/d2/shape/importers/map_dxf_to_shape.py +55 -0
  110. scadpy/d2/shape/importers/map_geometries_to_shape.py +45 -0
  111. scadpy/d2/shape/importers/map_geometry_to_shape.py +43 -0
  112. scadpy/d2/shape/importers/map_parts_to_shape.py +62 -0
  113. scadpy/d2/shape/importers/map_svg_to_shape.py +55 -0
  114. scadpy/d2/shape/primitives/__init__.py +6 -0
  115. scadpy/d2/shape/primitives/circle.py +68 -0
  116. scadpy/d2/shape/primitives/polygon.py +86 -0
  117. scadpy/d2/shape/primitives/rectangle.py +85 -0
  118. scadpy/d2/shape/primitives/square.py +57 -0
  119. scadpy/d2/shape/topologies/__init__.py +53 -0
  120. scadpy/d2/shape/topologies/corner/__init__.py +15 -0
  121. scadpy/d2/shape/topologies/corner/are_shape_corners_convex.py +75 -0
  122. scadpy/d2/shape/topologies/corner/get_shape_corner_angles.py +58 -0
  123. scadpy/d2/shape/topologies/corner/get_shape_corner_normals.py +82 -0
  124. scadpy/d2/shape/topologies/corner/get_shape_corner_to_incoming_directed_edge.py +39 -0
  125. scadpy/d2/shape/topologies/corner/get_shape_corner_to_outgoing_directed_edge.py +39 -0
  126. scadpy/d2/shape/topologies/corner/get_shape_corner_to_vertex.py +65 -0
  127. scadpy/d2/shape/topologies/directed_edge/__init__.py +11 -0
  128. scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_directions.py +44 -0
  129. scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_corner.py +41 -0
  130. scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_edge.py +51 -0
  131. scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_vertex.py +63 -0
  132. scadpy/d2/shape/topologies/edge/__init__.py +11 -0
  133. scadpy/d2/shape/topologies/edge/get_shape_edge_lengths.py +43 -0
  134. scadpy/d2/shape/topologies/edge/get_shape_edge_midpoints.py +46 -0
  135. scadpy/d2/shape/topologies/edge/get_shape_edge_normals.py +40 -0
  136. scadpy/d2/shape/topologies/edge/get_shape_edge_to_vertex.py +71 -0
  137. scadpy/d2/shape/topologies/ring/__init__.py +7 -0
  138. scadpy/d2/shape/topologies/ring/get_shape_ring_to_part.py +46 -0
  139. scadpy/d2/shape/topologies/ring/get_shape_ring_types.py +46 -0
  140. scadpy/d2/shape/topologies/vertex/__init__.py +11 -0
  141. scadpy/d2/shape/topologies/vertex/get_shape_part_vertex_coordinates.py +62 -0
  142. scadpy/d2/shape/topologies/vertex/get_shape_vertex_coordinates.py +44 -0
  143. scadpy/d2/shape/topologies/vertex/get_shape_vertex_to_part.py +42 -0
  144. scadpy/d2/shape/topologies/vertex/get_shape_vertex_to_ring.py +63 -0
  145. scadpy/d2/shape/transformations/__init__.py +43 -0
  146. scadpy/d2/shape/transformations/chamfer_shape.py +259 -0
  147. scadpy/d2/shape/transformations/color_shape.py +46 -0
  148. scadpy/d2/shape/transformations/convexify_shape.py +79 -0
  149. scadpy/d2/shape/transformations/fill_shape.py +68 -0
  150. scadpy/d2/shape/transformations/fillet_shape.py +289 -0
  151. scadpy/d2/shape/transformations/grow_shape.py +82 -0
  152. scadpy/d2/shape/transformations/linear_cut_shape.py +116 -0
  153. scadpy/d2/shape/transformations/linear_extrude_shape.py +60 -0
  154. scadpy/d2/shape/transformations/linear_slice_shape.py +144 -0
  155. scadpy/d2/shape/transformations/mirror_shape.py +53 -0
  156. scadpy/d2/shape/transformations/pull_shape.py +67 -0
  157. scadpy/d2/shape/transformations/push_shape.py +67 -0
  158. scadpy/d2/shape/transformations/radial_extrude_shape.py +285 -0
  159. scadpy/d2/shape/transformations/radial_slice_shape.py +132 -0
  160. scadpy/d2/shape/transformations/recoordinate_shape.py +82 -0
  161. scadpy/d2/shape/transformations/resize_shape.py +91 -0
  162. scadpy/d2/shape/transformations/rotate_shape.py +63 -0
  163. scadpy/d2/shape/transformations/scale_shape.py +58 -0
  164. scadpy/d2/shape/transformations/shrink_shape.py +69 -0
  165. scadpy/d2/shape/transformations/translate_shape.py +54 -0
  166. scadpy/d2/shape/types/__init__.py +3 -0
  167. scadpy/d2/shape/types/shape.py +792 -0
  168. scadpy/d2/shape/types/utils/__init__.py +5 -0
  169. scadpy/d2/shape/types/utils/shapely_base_geometry_to_shapely_polygons.py +25 -0
  170. scadpy/d2/shape/utils/__init__.py +5 -0
  171. scadpy/d2/shape/utils/shapely_base_geometry_to_shapely_polygons.py +55 -0
  172. scadpy/d2/utils/__init__.py +3 -0
  173. scadpy/d2/utils/resolve_vector_2d.py +50 -0
  174. scadpy/d3/__init__.py +2 -0
  175. scadpy/d3/solid/__init__.py +8 -0
  176. scadpy/d3/solid/combinations/__init__.py +21 -0
  177. scadpy/d3/solid/combinations/are_solid_parts_intersecting.py +51 -0
  178. scadpy/d3/solid/combinations/concat_solid.py +48 -0
  179. scadpy/d3/solid/combinations/exclude_solid.py +71 -0
  180. scadpy/d3/solid/combinations/intersect_solid.py +64 -0
  181. scadpy/d3/solid/combinations/intersect_solid_parts.py +73 -0
  182. scadpy/d3/solid/combinations/subtract_solid.py +72 -0
  183. scadpy/d3/solid/combinations/subtract_solid_parts.py +68 -0
  184. scadpy/d3/solid/combinations/unify_solid.py +51 -0
  185. scadpy/d3/solid/combinations/unify_solid_parts.py +73 -0
  186. scadpy/d3/solid/exporters/__init__.py +11 -0
  187. scadpy/d3/solid/exporters/map_solid_to_html.py +318 -0
  188. scadpy/d3/solid/exporters/map_solid_to_html_file.py +58 -0
  189. scadpy/d3/solid/exporters/map_solid_to_screen.py +51 -0
  190. scadpy/d3/solid/exporters/map_solid_to_stl_file.py +48 -0
  191. scadpy/d3/solid/features/__init__.py +11 -0
  192. scadpy/d3/solid/features/get_solid_bounds.py +37 -0
  193. scadpy/d3/solid/features/get_solid_part_bounds.py +37 -0
  194. scadpy/d3/solid/features/get_solid_part_colors.py +39 -0
  195. scadpy/d3/solid/features/is_solid_empty.py +36 -0
  196. scadpy/d3/solid/importers/__init__.py +11 -0
  197. scadpy/d3/solid/importers/map_geometries_to_solid.py +42 -0
  198. scadpy/d3/solid/importers/map_geometry_to_solid.py +42 -0
  199. scadpy/d3/solid/importers/map_parts_to_solid.py +66 -0
  200. scadpy/d3/solid/importers/map_stl_to_solid.py +37 -0
  201. scadpy/d3/solid/primitives/__init__.py +7 -0
  202. scadpy/d3/solid/primitives/cone.py +70 -0
  203. scadpy/d3/solid/primitives/cuboid.py +75 -0
  204. scadpy/d3/solid/primitives/cylinder.py +73 -0
  205. scadpy/d3/solid/primitives/polyhedron.py +60 -0
  206. scadpy/d3/solid/primitives/sphere.py +58 -0
  207. scadpy/d3/solid/topologies/__init__.py +8 -0
  208. scadpy/d3/solid/topologies/triangle/__init__.py +5 -0
  209. scadpy/d3/solid/topologies/triangle/get_solid_triangle_to_vertex.py +49 -0
  210. scadpy/d3/solid/topologies/vertex/__init__.py +7 -0
  211. scadpy/d3/solid/topologies/vertex/get_solid_vertex_coordinates.py +39 -0
  212. scadpy/d3/solid/topologies/vertex/get_solid_vertex_to_part.py +37 -0
  213. scadpy/d3/solid/transformations/__init__.py +23 -0
  214. scadpy/d3/solid/transformations/color_solid.py +46 -0
  215. scadpy/d3/solid/transformations/convexify_solid.py +64 -0
  216. scadpy/d3/solid/transformations/mirror_solid.py +53 -0
  217. scadpy/d3/solid/transformations/pull_solid.py +67 -0
  218. scadpy/d3/solid/transformations/push_solid.py +67 -0
  219. scadpy/d3/solid/transformations/recoordinate_solid.py +68 -0
  220. scadpy/d3/solid/transformations/resize_solid.py +92 -0
  221. scadpy/d3/solid/transformations/rotate_solid.py +93 -0
  222. scadpy/d3/solid/transformations/scale_solid.py +58 -0
  223. scadpy/d3/solid/transformations/translate_solid.py +54 -0
  224. scadpy/d3/solid/types/__init__.py +3 -0
  225. scadpy/d3/solid/types/solid.py +448 -0
  226. scadpy/d3/utils/__init__.py +3 -0
  227. scadpy/d3/utils/resolve_vector_3d.py +50 -0
  228. scadpy/utils/__init__.py +6 -0
  229. scadpy/utils/resolve_vector.py +64 -0
  230. scadpy/utils/x.py +38 -0
  231. scadpy/utils/y.py +38 -0
  232. scadpy/utils/z.py +38 -0
  233. scadpy-0.1.0.dist-info/METADATA +282 -0
  234. scadpy-0.1.0.dist-info/RECORD +236 -0
  235. scadpy-0.1.0.dist-info/WHEEL +4 -0
  236. scadpy-0.1.0.dist-info/licenses/LICENSE.md +43 -0
@@ -0,0 +1,58 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterable
4
+ from typing import TYPE_CHECKING
5
+
6
+ from typeguard import typechecked
7
+
8
+ if TYPE_CHECKING:
9
+ from scadpy import Solid, TopologyFilter
10
+
11
+
12
+ @typechecked
13
+ def scale_solid(
14
+ solid: Solid,
15
+ scale: float | Iterable[float],
16
+ pivot: float | Iterable[float] = 0,
17
+ vertex_filter: TopologyFilter[Solid] | None = None,
18
+ ) -> Solid:
19
+ """Scale a solid by a given factor, relative to a pivot point.
20
+
21
+ Parameters
22
+ ----------
23
+ solid : Solid
24
+ The solid to scale.
25
+ scale : float | Iterable[float]
26
+ The scaling factor(s). If a single float is provided, it is broadcast
27
+ to all coordinate dimensions.
28
+ pivot : float | Iterable[float], default=0
29
+ The point relative to which scaling is performed. If a single float is
30
+ provided, it is broadcast to all coordinate dimensions. Defaults to the origin.
31
+ vertex_filter : TopologyFilter[Solid] | None, default=None
32
+ Boolean array or callable selecting which vertices are scaled. If ``None``, all
33
+ vertices are scaled.
34
+
35
+ Returns
36
+ -------
37
+ Solid
38
+ A new solid with the selected vertices scaled relative to the pivot.
39
+
40
+ Examples
41
+ --------
42
+ >>> from scadpy import cuboid, scale_solid
43
+
44
+ >>> scale_solid( # doctest: +SKIP
45
+ ... solid=cuboid(4), scale=2, pivot=[2, 2, 2]
46
+ ... )
47
+
48
+ .. render-example::
49
+ :name: scale_solid
50
+ :example: scale_solid(solid=cuboid(4), scale=2, pivot=[2, 2, 2])
51
+ :ghost: cuboid(4)
52
+ """
53
+ from scadpy import resolve_topology_filter, scale_vertex_coordinates
54
+
55
+ resolved_vertex_filter = resolve_topology_filter(solid, len(solid.vertex_coordinates), vertex_filter)
56
+ return solid.recoordinate(
57
+ scale_vertex_coordinates(solid.vertex_coordinates, scale, pivot, resolved_vertex_filter)
58
+ )
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterable
4
+ from typing import TYPE_CHECKING
5
+
6
+ from typeguard import typechecked
7
+
8
+ if TYPE_CHECKING:
9
+ from scadpy import Solid, TopologyFilter
10
+
11
+
12
+ @typechecked
13
+ def translate_solid(
14
+ solid: Solid,
15
+ translation: float | Iterable[float],
16
+ vertex_filter: TopologyFilter[Solid] | None = None,
17
+ ) -> Solid:
18
+ """Translate a solid by a given vector.
19
+
20
+ Parameters
21
+ ----------
22
+ solid : Solid
23
+ The solid to translate.
24
+ translation : float | Iterable[float]
25
+ The translation vector. If a single float is provided, it is broadcast
26
+ to all coordinate dimensions.
27
+ vertex_filter : TopologyFilter[Solid] | None, default=None
28
+ Boolean array or callable selecting which vertices are translated. If ``None``, all
29
+ vertices are translated.
30
+
31
+ Returns
32
+ -------
33
+ Solid
34
+ A new solid with the selected vertices shifted by the translation vector.
35
+
36
+ Examples
37
+ --------
38
+ >>> from scadpy import cuboid, translate_solid
39
+
40
+ >>> translate_solid( # doctest: +SKIP
41
+ ... solid=cuboid(4), translation=[3, 2, 1]
42
+ ... )
43
+
44
+ .. render-example::
45
+ :name: translate_solid
46
+ :example: translate_solid(solid=cuboid(4), translation=[3, 2, 1])
47
+ :ghost: cuboid(4)
48
+ """
49
+ from scadpy import resolve_topology_filter, translate_vertex_coordinates
50
+
51
+ resolved_vertex_filter = resolve_topology_filter(solid, len(solid.vertex_coordinates), vertex_filter)
52
+ return solid.recoordinate(
53
+ translate_vertex_coordinates(solid.vertex_coordinates, translation, resolved_vertex_filter)
54
+ )
@@ -0,0 +1,3 @@
1
+ __all__ = ["Solid"]
2
+
3
+ from .solid import Solid
@@ -0,0 +1,448 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterable, Sequence
4
+ from functools import cached_property
5
+ from pathlib import Path
6
+ from typing import TYPE_CHECKING, Any, Self, final
7
+
8
+ from scadpy.color.constants import BLACK, WHITE
9
+
10
+ if TYPE_CHECKING:
11
+ from scadpy.color import Color
12
+ from scadpy.core.part import Part
13
+ from scadpy import TopologyFilter
14
+
15
+ import numpy as np
16
+ from IPython.core.display import HTML
17
+ from numpy.typing import NDArray
18
+ from trimesh import Trimesh
19
+ from typeguard import typechecked
20
+
21
+ from scadpy.core.assembly import Assembly
22
+
23
+
24
+ @final
25
+ @typechecked
26
+ class Solid(Assembly[Trimesh]):
27
+ def __init__(self, *args: Any, **kwargs: Any) -> None: # pyright: ignore[reportExplicitAny, reportAny]
28
+ super().__init__(*args, **kwargs)
29
+
30
+ @classmethod
31
+ def dimensions(cls) -> int:
32
+ return 3
33
+
34
+ ##########
35
+ # vertex #
36
+ ##########
37
+
38
+ @cached_property
39
+ def vertex_coordinates(self: Self) -> NDArray[np.float64]:
40
+ """
41
+ Shortcut for :func:`get_solid_vertex_coordinates`.
42
+
43
+ See :func:`get_solid_vertex_coordinates` for full documentation.
44
+ """
45
+ from scadpy.d3.solid import get_solid_vertex_coordinates
46
+
47
+ return get_solid_vertex_coordinates(self)
48
+
49
+ @cached_property
50
+ def vertex_to_part(self: Self) -> NDArray[np.int64]:
51
+ """
52
+ Shortcut for :func:`get_solid_vertex_to_part`.
53
+
54
+ See :func:`get_solid_vertex_to_part` for full documentation.
55
+ """
56
+ from scadpy.d3.solid import get_solid_vertex_to_part
57
+
58
+ return get_solid_vertex_to_part(self)
59
+
60
+ ############
61
+ # features #
62
+ ############
63
+
64
+ @cached_property
65
+ def is_empty(self: Self) -> bool:
66
+ """
67
+ Shortcut for :func:`is_solid_empty`.
68
+
69
+ See :func:`is_solid_empty` for full documentation.
70
+ """
71
+ from scadpy.d3.solid import is_solid_empty
72
+
73
+ return is_solid_empty(self)
74
+
75
+ @cached_property
76
+ def bounds(self: Self) -> NDArray[np.float64]:
77
+ """
78
+ Shortcut for :func:`get_solid_bounds`.
79
+
80
+ See :func:`get_solid_bounds` for full documentation.
81
+ """
82
+ from scadpy.d3.solid import get_solid_bounds
83
+
84
+ return get_solid_bounds(self)
85
+
86
+ ##############
87
+ # topologies #
88
+ ##############
89
+
90
+ @cached_property
91
+ def part_colors(self: Self) -> NDArray[np.float64]:
92
+ """
93
+ Shortcut for :func:`get_assembly_part_colors`.
94
+
95
+ See :func:`get_assembly_part_colors` for full documentation.
96
+ """
97
+ from scadpy.d3.solid import get_solid_part_colors
98
+
99
+ return get_solid_part_colors(self)
100
+
101
+ @cached_property
102
+ def triangle_to_vertex(self: Self) -> NDArray[np.int64]:
103
+ """
104
+ Shortcut for :func:`get_solid_triangle_to_vertex`.
105
+
106
+ See :func:`get_solid_triangle_to_vertex` for full documentation.
107
+ """
108
+ from scadpy.d3.solid import get_solid_triangle_to_vertex
109
+
110
+ return get_solid_triangle_to_vertex(self)
111
+
112
+ ################
113
+ # combinations #
114
+ ################
115
+
116
+ def __add__(self: Self, other: Solid) -> Solid:
117
+ """Concatenate two solids. Shortcut for :func:`concat_solid`."""
118
+ from scadpy import concat_solid
119
+
120
+ return concat_solid(solids=[self, other])
121
+
122
+ def __or__(self: Self, other: Solid) -> Solid:
123
+ """Unite two solids. Shortcut for :func:`unify_solid`."""
124
+ from scadpy import unify_solid
125
+
126
+ return unify_solid(solids=[self, other])
127
+
128
+ def __and__(self: Self, other: Solid) -> Solid:
129
+ """Intersect two solids. Shortcut for :func:`intersect_solid`."""
130
+ from scadpy import intersect_solid
131
+
132
+ return intersect_solid(solids=[self, other])
133
+
134
+ def __sub__(self: Self, other: Solid) -> Solid:
135
+ """Subtract a solid from this solid. Shortcut for :func:`subtract_solid`."""
136
+ from scadpy import subtract_solid
137
+
138
+ return subtract_solid(to_be_subtracted=self, to_subtract=other)
139
+
140
+ def __xor__(self: Self, other: Solid) -> Solid:
141
+ """Compute symmetric difference with another solid. Shortcut for :func:`exclude_solid`."""
142
+ from scadpy import exclude_solid
143
+
144
+ return exclude_solid(solids=[self, other])
145
+
146
+ def concat(self: Self, solids: Sequence[Solid]) -> Solid:
147
+ """Concatenate this solid with others.
148
+
149
+ Shortcut for :func:`concat_solid`.
150
+ See :func:`concat_solid` for full documentation.
151
+ """
152
+ from scadpy import concat_solid
153
+
154
+ return concat_solid(solids=[self, *solids])
155
+
156
+ def unify(self: Self, solids: Sequence[Solid]) -> Solid:
157
+ """Unite this solid with others.
158
+
159
+ Shortcut for :func:`unify_solid`.
160
+ See :func:`unify_solid` for full documentation.
161
+ """
162
+ from scadpy import unify_solid
163
+
164
+ return unify_solid(solids=[self, *solids])
165
+
166
+ def intersect(self: Self, solids: Sequence[Solid]) -> Solid:
167
+ """Intersect this solid with others.
168
+
169
+ Shortcut for :func:`intersect_solid`.
170
+ See :func:`intersect_solid` for full documentation.
171
+ """
172
+ from scadpy import intersect_solid
173
+
174
+ return intersect_solid(solids=[self, *solids])
175
+
176
+ def subtract(self: Self, to_subtract: Solid) -> Solid:
177
+ """Subtract a solid from this solid.
178
+
179
+ Shortcut for :func:`subtract_solid`.
180
+ See :func:`subtract_solid` for full documentation.
181
+ """
182
+ from scadpy import subtract_solid
183
+
184
+ return subtract_solid(to_be_subtracted=self, to_subtract=to_subtract)
185
+
186
+ def exclude(self: Self, solids: Sequence[Solid]) -> Solid:
187
+ """Compute the symmetric difference of this solid with others.
188
+
189
+ Shortcut for :func:`exclude_solid`.
190
+ See :func:`exclude_solid` for full documentation.
191
+ """
192
+ from scadpy import exclude_solid
193
+
194
+ return exclude_solid(solids=[self, *solids])
195
+
196
+ ###################
197
+ # transformations #
198
+ ###################
199
+
200
+ def translate(
201
+ self: Self,
202
+ translation: float | Iterable[float],
203
+ vertex_filter: TopologyFilter[Solid] | None = None,
204
+ ) -> Solid:
205
+ """Translate this solid.
206
+
207
+ Shortcut for :func:`translate_solid`.
208
+ See :func:`translate_solid` for full documentation.
209
+ """
210
+ from scadpy.d3.solid import translate_solid
211
+
212
+ return translate_solid(solid=self, translation=translation, vertex_filter=vertex_filter)
213
+
214
+ def scale(
215
+ self: Self,
216
+ scale: float | Iterable[float],
217
+ pivot: float | Iterable[float] = 0,
218
+ vertex_filter: TopologyFilter[Solid] | None = None,
219
+ ) -> Solid:
220
+ """Scale this solid.
221
+
222
+ Shortcut for :func:`scale_solid`.
223
+ See :func:`scale_solid` for full documentation.
224
+ """
225
+ from scadpy.d3.solid import scale_solid
226
+
227
+ return scale_solid(solid=self, scale=scale, pivot=pivot, vertex_filter=vertex_filter)
228
+
229
+ def resize(
230
+ self: Self,
231
+ size: Iterable[float | None],
232
+ auto: bool = False,
233
+ pivot: float | Iterable[float] | None = None,
234
+ vertex_filter: TopologyFilter[Solid] | None = None,
235
+ ) -> Solid:
236
+ """Resize this solid.
237
+
238
+ Shortcut for :func:`resize_solid`.
239
+ See :func:`resize_solid` for full documentation.
240
+ """
241
+ from scadpy.d3.solid import resize_solid
242
+
243
+ return resize_solid(solid=self, size=size, auto=auto, pivot=pivot, vertex_filter=vertex_filter)
244
+
245
+ def mirror(
246
+ self: Self,
247
+ normal: float | Iterable[float],
248
+ pivot: float | Iterable[float] = 0,
249
+ ) -> Solid:
250
+ """Mirror this solid.
251
+
252
+ Shortcut for :func:`mirror_solid`.
253
+ See :func:`mirror_solid` for full documentation.
254
+ """
255
+ from scadpy.d3.solid import mirror_solid
256
+
257
+ return mirror_solid(solid=self, normal=normal, pivot=pivot)
258
+
259
+ def pull(
260
+ self: Self,
261
+ distance: float,
262
+ pivot: float | Iterable[float] = 0,
263
+ vertex_filter: TopologyFilter[Solid] | None = None,
264
+ ) -> Solid:
265
+ """Move vertices of this solid toward a pivot point.
266
+
267
+ Shortcut for :func:`pull_solid`.
268
+ See :func:`pull_solid` for full documentation.
269
+ """
270
+ from scadpy.d3.solid import pull_solid
271
+
272
+ return pull_solid(solid=self, distance=distance, pivot=pivot, vertex_filter=vertex_filter)
273
+
274
+ def push(
275
+ self: Self,
276
+ distance: float,
277
+ pivot: float | Iterable[float] = 0,
278
+ vertex_filter: TopologyFilter[Solid] | None = None,
279
+ ) -> Solid:
280
+ """Move vertices of this solid away from a pivot point.
281
+
282
+ Shortcut for :func:`push_solid`.
283
+ See :func:`push_solid` for full documentation.
284
+ """
285
+ from scadpy.d3.solid import push_solid
286
+
287
+ return push_solid(solid=self, distance=distance, pivot=pivot, vertex_filter=vertex_filter)
288
+
289
+ def rotate(
290
+ self: Self,
291
+ angle: float,
292
+ axis: float | Iterable[float],
293
+ pivot: float | Iterable[float] = 0,
294
+ vertex_filter: TopologyFilter[Solid] | None = None,
295
+ ) -> Solid:
296
+ """Rotate this solid around an axis.
297
+
298
+ Shortcut for :func:`rotate_solid`.
299
+ See :func:`rotate_solid` for full documentation.
300
+ """
301
+ from scadpy.d3.solid import rotate_solid
302
+
303
+ return rotate_solid(solid=self, angle=angle, axis=axis, pivot=pivot, vertex_filter=vertex_filter)
304
+
305
+ def color(self: Self, color: Color) -> Solid:
306
+ """Set the color of all parts in this solid.
307
+
308
+ Shortcut for :func:`color_solid`.
309
+ See :func:`color_solid` for full documentation.
310
+ """
311
+ from scadpy.d3.solid import color_solid
312
+
313
+ return color_solid(solid=self, color=color)
314
+
315
+ def convexify(
316
+ self: Self,
317
+ part_filter: TopologyFilter[Solid] | None = None,
318
+ ) -> Solid:
319
+ """Replace selected parts with their convex hull.
320
+
321
+ Shortcut for :func:`convexify_solid`.
322
+ See :func:`convexify_solid` for full documentation.
323
+ """
324
+ from scadpy.d3.solid import convexify_solid
325
+
326
+ return convexify_solid(solid=self, part_filter=part_filter)
327
+
328
+ def recoordinate(
329
+ self: Self, vertex_coordinates: NDArray[np.float64]
330
+ ) -> Solid:
331
+ """Rebuild this solid with new vertex coordinates.
332
+
333
+ Shortcut for :func:`recoordinate_solid`.
334
+ See :func:`recoordinate_solid` for full documentation.
335
+ """
336
+ from scadpy.d3.solid import recoordinate_solid
337
+
338
+ return recoordinate_solid(self, vertex_coordinates)
339
+
340
+ #############
341
+ # importers #
342
+ #############
343
+
344
+ @classmethod
345
+ def from_parts(cls, parts: Sequence[Part[Trimesh]]) -> Solid:
346
+ solid = Solid()
347
+ solid._parts = parts
348
+ return solid
349
+
350
+ @classmethod
351
+ def from_geometries(cls, geometries: Sequence[Trimesh]) -> Solid:
352
+ """Shortcut for :func:`map_geometries_to_solid`.
353
+
354
+ See :func:`map_geometries_to_solid` for full documentation.
355
+ """
356
+ from scadpy.d3.solid.importers import map_geometries_to_solid
357
+
358
+ return map_geometries_to_solid(geometries)
359
+
360
+ @classmethod
361
+ def from_geometry(cls, geometry: Trimesh) -> Solid:
362
+ """Shortcut for :func:`map_geometry_to_solid`.
363
+
364
+ See :func:`map_geometry_to_solid` for full documentation.
365
+ """
366
+ from scadpy.d3.solid.importers import map_geometry_to_solid
367
+
368
+ return map_geometry_to_solid(geometry)
369
+
370
+ @classmethod
371
+ def from_stl(cls, source: str | Path) -> Solid:
372
+ """Shortcut for :func:`map_stl_to_solid`.
373
+
374
+ See :func:`map_stl_to_solid` for full documentation.
375
+ """
376
+ from scadpy.d3.solid.importers import map_stl_to_solid
377
+
378
+ return map_stl_to_solid(source)
379
+
380
+ #############
381
+ # exporters #
382
+ #############
383
+
384
+ def to_html(
385
+ self: Self,
386
+ background_color: Color = WHITE,
387
+ foreground_color: Color = BLACK,
388
+ ) -> HTML:
389
+ """Render this solid to an interactive HTML widget.
390
+
391
+ Shortcut for :func:`map_solid_to_html`.
392
+ See :func:`map_solid_to_html` for full documentation.
393
+ """
394
+ from scadpy import map_solid_to_html
395
+
396
+ return map_solid_to_html(
397
+ solid=self,
398
+ background_color=background_color,
399
+ foreground_color=foreground_color,
400
+ )
401
+
402
+ def to_html_file(
403
+ self: Self,
404
+ path: str,
405
+ background_color: Color = WHITE,
406
+ foreground_color: Color = BLACK,
407
+ ) -> int:
408
+ """Write this solid to an HTML file.
409
+
410
+ Shortcut for :func:`map_solid_to_html_file`.
411
+ See :func:`map_solid_to_html_file` for full documentation.
412
+ """
413
+ from scadpy import map_solid_to_html_file
414
+
415
+ return map_solid_to_html_file(
416
+ solid=self,
417
+ path=path,
418
+ background_color=background_color,
419
+ foreground_color=foreground_color,
420
+ )
421
+
422
+ def to_screen(
423
+ self: Self,
424
+ background_color: Color = WHITE,
425
+ foreground_color: Color = BLACK,
426
+ ) -> None:
427
+ """Display this solid in an interactive viewer.
428
+
429
+ Shortcut for :func:`map_solid_to_screen`.
430
+ See :func:`map_solid_to_screen` for full documentation.
431
+ """
432
+ from scadpy import map_solid_to_screen
433
+
434
+ map_solid_to_screen(
435
+ solid=self,
436
+ background_color=background_color,
437
+ foreground_color=foreground_color,
438
+ )
439
+
440
+ def to_stl_file(self: Self, path: str | Path) -> int:
441
+ """Export this solid to an STL file.
442
+
443
+ Shortcut for :func:`map_solid_to_stl_file`.
444
+ See :func:`map_solid_to_stl_file` for full documentation.
445
+ """
446
+ from scadpy import map_solid_to_stl_file
447
+
448
+ return map_solid_to_stl_file(solid=self, path=path)
@@ -0,0 +1,3 @@
1
+ __all__ = ["resolve_vector_3d"]
2
+
3
+ from .resolve_vector_3d import resolve_vector_3d
@@ -0,0 +1,50 @@
1
+ from typing import Iterable
2
+
3
+ import numpy as np
4
+ from numpy.typing import NDArray
5
+ from typeguard import typechecked
6
+
7
+
8
+ @typechecked
9
+ def resolve_vector_3d(
10
+ values: float | Iterable[float],
11
+ default_value: float,
12
+ ) -> NDArray[np.float64]:
13
+ """
14
+ Resolves input into a 3D vector (NumPy array of length 3).
15
+
16
+ Parameters
17
+ ----------
18
+ values : float or Iterable[float]
19
+ The input values to resolve into a 3D vector. It can be:
20
+ - A single numeric value, repeated to fill the vector.
21
+ - An iterable of numeric values, extended or truncated to length 3.
22
+ default_value : float
23
+ The value used to pad the vector if `values` has fewer than 3 elements.
24
+
25
+ Returns
26
+ -------
27
+ NDArray[np.float64]
28
+ A NumPy array of shape (3,) containing the resolved 3D vector.
29
+
30
+ Notes
31
+ -----
32
+ - If `values` is a single number, the result will be `[values, values, values]`.
33
+ - If `values` has fewer than 3 elements, it is padded with `default_value`.
34
+ - If `values` has more than 3 elements, only the first three will be kept.
35
+
36
+ Examples
37
+ --------
38
+ >>> from scadpy import resolve_vector_3d
39
+ >>> resolve_vector_3d(5, 0)
40
+ array([5., 5., 5.])
41
+
42
+ >>> resolve_vector_3d([1, 2], 0)
43
+ array([1., 2., 0.])
44
+
45
+ >>> resolve_vector_3d([3, 4, 5, 6], 0)
46
+ array([3., 4., 5.])
47
+ """
48
+ from scadpy import resolve_vector
49
+
50
+ return resolve_vector(values, default_value, 3)
@@ -0,0 +1,6 @@
1
+ __all__ = ["resolve_vector", "x", "y", "z"]
2
+
3
+ from .resolve_vector import resolve_vector
4
+ from .x import x
5
+ from .y import y
6
+ from .z import z
@@ -0,0 +1,64 @@
1
+ from numbers import Real
2
+ from typing import Iterable
3
+
4
+ import numpy as np
5
+ from numpy.typing import NDArray
6
+ from typeguard import typechecked
7
+ from typing_extensions import cast
8
+
9
+
10
+ @typechecked
11
+ def resolve_vector(
12
+ values: float | Iterable[float], default_value: float, length: int
13
+ ) -> NDArray[np.float64]:
14
+ """
15
+ Resolves a given input into a NumPy array of a specified length.
16
+
17
+ Parameters
18
+ ----------
19
+ values : float or Iterable[float]
20
+ The input values to be resolved. This can be:
21
+
22
+ - A single numeric value, which will be repeated to fill the array.
23
+ - An iterable of numeric values, which will be extended or truncated to match the desired length.
24
+ default_value : float
25
+ The value to use for padding if the input `values` is shorter than
26
+ the required length.
27
+ length : int
28
+ The desired length of the output array.
29
+
30
+ Returns
31
+ -------
32
+ NDArray[np.float64]
33
+ A NumPy array of the specified length containing the resolved values.
34
+ If `values` is shorter than `length`, it is padded with `default_value`.
35
+ If it is longer, it is truncated.
36
+
37
+ Notes
38
+ -----
39
+ - The resulting array always has exactly `length` elements.
40
+
41
+ Examples
42
+ --------
43
+ >>> from scadpy import resolve_vector
44
+ >>> resolve_vector(5, 0, 3)
45
+ array([5., 5., 5.])
46
+
47
+ >>> resolve_vector([1, 2], 0, 5)
48
+ array([1., 2., 0., 0., 0.])
49
+
50
+ >>> resolve_vector([1, 2, 3, 4, 5, 6], 0, 4)
51
+ array([1., 2., 3., 4.])
52
+ """
53
+ result = np.full(length, default_value, dtype=float)
54
+
55
+ if isinstance(values, Real):
56
+ result[:] = float(values)
57
+ else:
58
+ vals = np.fromiter(cast(Iterable[float], values), dtype=float)
59
+ n = min(len(vals), length)
60
+ result[:n] = vals[:n]
61
+
62
+ # replace np.nan with default_value
63
+ result = np.where(np.isnan(result), default_value, result)
64
+ return result