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.
- scadpy/__init__.py +5 -0
- scadpy/color/__init__.py +3 -0
- scadpy/color/constants/BEIGE.py +3 -0
- scadpy/color/constants/BLACK.py +3 -0
- scadpy/color/constants/BLUE.py +3 -0
- scadpy/color/constants/BROWN.py +3 -0
- scadpy/color/constants/DARK_GRAY.py +3 -0
- scadpy/color/constants/DEFAULT_COLOR.py +3 -0
- scadpy/color/constants/DEFAULT_OPACITY.py +1 -0
- scadpy/color/constants/GRAY.py +3 -0
- scadpy/color/constants/GREEN.py +3 -0
- scadpy/color/constants/ORANGE.py +3 -0
- scadpy/color/constants/RED.py +3 -0
- scadpy/color/constants/WHITE.py +3 -0
- scadpy/color/constants/YELLOW.py +3 -0
- scadpy/color/constants/__init__.py +29 -0
- scadpy/color/type/__init__.py +3 -0
- scadpy/color/type/color.py +3 -0
- scadpy/color/utils/__init__.py +3 -0
- scadpy/color/utils/get_random_color.py +36 -0
- scadpy/core/__init__.py +3 -0
- scadpy/core/assembly/__init__.py +5 -0
- scadpy/core/assembly/combinations/__init__.py +13 -0
- scadpy/core/assembly/combinations/concat_assemblies.py +50 -0
- scadpy/core/assembly/combinations/exclude_assemblies.py +135 -0
- scadpy/core/assembly/combinations/intersect_assemblies.py +128 -0
- scadpy/core/assembly/combinations/subtract_assemblies.py +151 -0
- scadpy/core/assembly/combinations/unify_assemblies.py +59 -0
- scadpy/core/assembly/topologies/__init__.py +41 -0
- scadpy/core/assembly/topologies/directed_edge/__init__.py +9 -0
- scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_directions.py +70 -0
- scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_to_edge.py +49 -0
- scadpy/core/assembly/topologies/directed_edge/get_assembly_directed_edge_to_vertex.py +54 -0
- scadpy/core/assembly/topologies/edge/__init__.py +9 -0
- scadpy/core/assembly/topologies/edge/get_assembly_edge_lengths.py +46 -0
- scadpy/core/assembly/topologies/edge/get_assembly_edge_midpoints.py +51 -0
- scadpy/core/assembly/topologies/edge/get_assembly_edge_normals.py +67 -0
- scadpy/core/assembly/topologies/face_corner/__init__.py +13 -0
- scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_angles.py +72 -0
- scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_normals.py +103 -0
- scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_to_incoming_directed_edge.py +65 -0
- scadpy/core/assembly/topologies/face_corner/get_assembly_face_corner_to_outgoing_directed_edge.py +65 -0
- scadpy/core/assembly/topologies/face_corner/get_assembly_face_directed_edge_to_corner.py +79 -0
- scadpy/core/assembly/topologies/part/__init__.py +5 -0
- scadpy/core/assembly/topologies/part/get_assembly_part_colors.py +55 -0
- scadpy/core/assembly/topologies/vertex/__init__.py +7 -0
- scadpy/core/assembly/topologies/vertex/get_assembly_vertex_coordinates.py +70 -0
- scadpy/core/assembly/topologies/vertex/get_assembly_vertex_to_part.py +62 -0
- scadpy/core/assembly/transformations/__init__.py +19 -0
- scadpy/core/assembly/transformations/color_assembly.py +24 -0
- scadpy/core/assembly/transformations/mirror_vertex_coordinates.py +68 -0
- scadpy/core/assembly/transformations/pull_vertex_coordinates.py +64 -0
- scadpy/core/assembly/transformations/push_vertex_coordinates.py +64 -0
- scadpy/core/assembly/transformations/resize_vertex_coordinates.py +121 -0
- scadpy/core/assembly/transformations/rotate_vertex_coordinates.py +73 -0
- scadpy/core/assembly/transformations/scale_vertex_coordinates.py +76 -0
- scadpy/core/assembly/transformations/translate_vertex_coordinates.py +70 -0
- scadpy/core/assembly/types/__init__.py +7 -0
- scadpy/core/assembly/types/assembly.py +14 -0
- scadpy/core/assembly/types/topology_filter.py +6 -0
- scadpy/core/assembly/utils/__init__.py +9 -0
- scadpy/core/assembly/utils/lookup_pairs.py +56 -0
- scadpy/core/assembly/utils/resolve_topology_filter.py +84 -0
- scadpy/core/assembly/utils/transform_filtered_parts.py +55 -0
- scadpy/core/component/__init__.py +3 -0
- scadpy/core/component/exporters/__init__.py +7 -0
- scadpy/core/component/exporters/map_component_to_html_file.py +47 -0
- scadpy/core/component/exporters/map_component_to_screen.py +63 -0
- scadpy/core/component/features/__init__.py +5 -0
- scadpy/core/component/features/get_component_bounds.py +38 -0
- scadpy/core/component/utils/__init__.py +9 -0
- scadpy/core/component/utils/blend_component_colors.py +77 -0
- scadpy/core/component/utils/get_intersecting_component_index_groups.py +108 -0
- scadpy/core/part/__init__.py +3 -0
- scadpy/core/part/combinations/__init__.py +11 -0
- scadpy/core/part/combinations/concat_parts.py +48 -0
- scadpy/core/part/combinations/intersect_parts.py +147 -0
- scadpy/core/part/combinations/subtract_parts.py +94 -0
- scadpy/core/part/combinations/unify_parts.py +143 -0
- scadpy/core/part/types/__init__.py +5 -0
- scadpy/core/part/types/part.py +34 -0
- scadpy/core/part/utils/__init__.py +5 -0
- scadpy/core/part/utils/blend_part_colors.py +32 -0
- scadpy/d2/__init__.py +2 -0
- scadpy/d2/shape/__init__.py +9 -0
- scadpy/d2/shape/combinations/__init__.py +21 -0
- scadpy/d2/shape/combinations/are_shape_parts_intersecting.py +49 -0
- scadpy/d2/shape/combinations/concat_shape.py +48 -0
- scadpy/d2/shape/combinations/exclude_shape.py +71 -0
- scadpy/d2/shape/combinations/intersect_shape.py +64 -0
- scadpy/d2/shape/combinations/intersect_shape_parts.py +71 -0
- scadpy/d2/shape/combinations/subtract_shape.py +72 -0
- scadpy/d2/shape/combinations/subtract_shape_parts.py +66 -0
- scadpy/d2/shape/combinations/unify_shape.py +51 -0
- scadpy/d2/shape/combinations/unify_shape_parts.py +74 -0
- scadpy/d2/shape/exporters/__init__.py +17 -0
- scadpy/d2/shape/exporters/map_shape_to_dxf.py +43 -0
- scadpy/d2/shape/exporters/map_shape_to_dxf_file.py +38 -0
- scadpy/d2/shape/exporters/map_shape_to_html.py +117 -0
- scadpy/d2/shape/exporters/map_shape_to_html_file.py +58 -0
- scadpy/d2/shape/exporters/map_shape_to_screen.py +51 -0
- scadpy/d2/shape/exporters/map_shape_to_svg.py +40 -0
- scadpy/d2/shape/exporters/map_shape_to_svg_file.py +38 -0
- scadpy/d2/shape/features/__init__.py +9 -0
- scadpy/d2/shape/features/get_shape_bounds.py +40 -0
- scadpy/d2/shape/features/get_shape_part_bounds.py +37 -0
- scadpy/d2/shape/features/is_shape_empty.py +38 -0
- scadpy/d2/shape/importers/__init__.py +13 -0
- scadpy/d2/shape/importers/map_dxf_to_shape.py +55 -0
- scadpy/d2/shape/importers/map_geometries_to_shape.py +45 -0
- scadpy/d2/shape/importers/map_geometry_to_shape.py +43 -0
- scadpy/d2/shape/importers/map_parts_to_shape.py +62 -0
- scadpy/d2/shape/importers/map_svg_to_shape.py +55 -0
- scadpy/d2/shape/primitives/__init__.py +6 -0
- scadpy/d2/shape/primitives/circle.py +68 -0
- scadpy/d2/shape/primitives/polygon.py +86 -0
- scadpy/d2/shape/primitives/rectangle.py +85 -0
- scadpy/d2/shape/primitives/square.py +57 -0
- scadpy/d2/shape/topologies/__init__.py +53 -0
- scadpy/d2/shape/topologies/corner/__init__.py +15 -0
- scadpy/d2/shape/topologies/corner/are_shape_corners_convex.py +75 -0
- scadpy/d2/shape/topologies/corner/get_shape_corner_angles.py +58 -0
- scadpy/d2/shape/topologies/corner/get_shape_corner_normals.py +82 -0
- scadpy/d2/shape/topologies/corner/get_shape_corner_to_incoming_directed_edge.py +39 -0
- scadpy/d2/shape/topologies/corner/get_shape_corner_to_outgoing_directed_edge.py +39 -0
- scadpy/d2/shape/topologies/corner/get_shape_corner_to_vertex.py +65 -0
- scadpy/d2/shape/topologies/directed_edge/__init__.py +11 -0
- scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_directions.py +44 -0
- scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_corner.py +41 -0
- scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_edge.py +51 -0
- scadpy/d2/shape/topologies/directed_edge/get_shape_directed_edge_to_vertex.py +63 -0
- scadpy/d2/shape/topologies/edge/__init__.py +11 -0
- scadpy/d2/shape/topologies/edge/get_shape_edge_lengths.py +43 -0
- scadpy/d2/shape/topologies/edge/get_shape_edge_midpoints.py +46 -0
- scadpy/d2/shape/topologies/edge/get_shape_edge_normals.py +40 -0
- scadpy/d2/shape/topologies/edge/get_shape_edge_to_vertex.py +71 -0
- scadpy/d2/shape/topologies/ring/__init__.py +7 -0
- scadpy/d2/shape/topologies/ring/get_shape_ring_to_part.py +46 -0
- scadpy/d2/shape/topologies/ring/get_shape_ring_types.py +46 -0
- scadpy/d2/shape/topologies/vertex/__init__.py +11 -0
- scadpy/d2/shape/topologies/vertex/get_shape_part_vertex_coordinates.py +62 -0
- scadpy/d2/shape/topologies/vertex/get_shape_vertex_coordinates.py +44 -0
- scadpy/d2/shape/topologies/vertex/get_shape_vertex_to_part.py +42 -0
- scadpy/d2/shape/topologies/vertex/get_shape_vertex_to_ring.py +63 -0
- scadpy/d2/shape/transformations/__init__.py +43 -0
- scadpy/d2/shape/transformations/chamfer_shape.py +259 -0
- scadpy/d2/shape/transformations/color_shape.py +46 -0
- scadpy/d2/shape/transformations/convexify_shape.py +79 -0
- scadpy/d2/shape/transformations/fill_shape.py +68 -0
- scadpy/d2/shape/transformations/fillet_shape.py +289 -0
- scadpy/d2/shape/transformations/grow_shape.py +82 -0
- scadpy/d2/shape/transformations/linear_cut_shape.py +116 -0
- scadpy/d2/shape/transformations/linear_extrude_shape.py +60 -0
- scadpy/d2/shape/transformations/linear_slice_shape.py +144 -0
- scadpy/d2/shape/transformations/mirror_shape.py +53 -0
- scadpy/d2/shape/transformations/pull_shape.py +67 -0
- scadpy/d2/shape/transformations/push_shape.py +67 -0
- scadpy/d2/shape/transformations/radial_extrude_shape.py +285 -0
- scadpy/d2/shape/transformations/radial_slice_shape.py +132 -0
- scadpy/d2/shape/transformations/recoordinate_shape.py +82 -0
- scadpy/d2/shape/transformations/resize_shape.py +91 -0
- scadpy/d2/shape/transformations/rotate_shape.py +63 -0
- scadpy/d2/shape/transformations/scale_shape.py +58 -0
- scadpy/d2/shape/transformations/shrink_shape.py +69 -0
- scadpy/d2/shape/transformations/translate_shape.py +54 -0
- scadpy/d2/shape/types/__init__.py +3 -0
- scadpy/d2/shape/types/shape.py +792 -0
- scadpy/d2/shape/types/utils/__init__.py +5 -0
- scadpy/d2/shape/types/utils/shapely_base_geometry_to_shapely_polygons.py +25 -0
- scadpy/d2/shape/utils/__init__.py +5 -0
- scadpy/d2/shape/utils/shapely_base_geometry_to_shapely_polygons.py +55 -0
- scadpy/d2/utils/__init__.py +3 -0
- scadpy/d2/utils/resolve_vector_2d.py +50 -0
- scadpy/d3/__init__.py +2 -0
- scadpy/d3/solid/__init__.py +8 -0
- scadpy/d3/solid/combinations/__init__.py +21 -0
- scadpy/d3/solid/combinations/are_solid_parts_intersecting.py +51 -0
- scadpy/d3/solid/combinations/concat_solid.py +48 -0
- scadpy/d3/solid/combinations/exclude_solid.py +71 -0
- scadpy/d3/solid/combinations/intersect_solid.py +64 -0
- scadpy/d3/solid/combinations/intersect_solid_parts.py +73 -0
- scadpy/d3/solid/combinations/subtract_solid.py +72 -0
- scadpy/d3/solid/combinations/subtract_solid_parts.py +68 -0
- scadpy/d3/solid/combinations/unify_solid.py +51 -0
- scadpy/d3/solid/combinations/unify_solid_parts.py +73 -0
- scadpy/d3/solid/exporters/__init__.py +11 -0
- scadpy/d3/solid/exporters/map_solid_to_html.py +318 -0
- scadpy/d3/solid/exporters/map_solid_to_html_file.py +58 -0
- scadpy/d3/solid/exporters/map_solid_to_screen.py +51 -0
- scadpy/d3/solid/exporters/map_solid_to_stl_file.py +48 -0
- scadpy/d3/solid/features/__init__.py +11 -0
- scadpy/d3/solid/features/get_solid_bounds.py +37 -0
- scadpy/d3/solid/features/get_solid_part_bounds.py +37 -0
- scadpy/d3/solid/features/get_solid_part_colors.py +39 -0
- scadpy/d3/solid/features/is_solid_empty.py +36 -0
- scadpy/d3/solid/importers/__init__.py +11 -0
- scadpy/d3/solid/importers/map_geometries_to_solid.py +42 -0
- scadpy/d3/solid/importers/map_geometry_to_solid.py +42 -0
- scadpy/d3/solid/importers/map_parts_to_solid.py +66 -0
- scadpy/d3/solid/importers/map_stl_to_solid.py +37 -0
- scadpy/d3/solid/primitives/__init__.py +7 -0
- scadpy/d3/solid/primitives/cone.py +70 -0
- scadpy/d3/solid/primitives/cuboid.py +75 -0
- scadpy/d3/solid/primitives/cylinder.py +73 -0
- scadpy/d3/solid/primitives/polyhedron.py +60 -0
- scadpy/d3/solid/primitives/sphere.py +58 -0
- scadpy/d3/solid/topologies/__init__.py +8 -0
- scadpy/d3/solid/topologies/triangle/__init__.py +5 -0
- scadpy/d3/solid/topologies/triangle/get_solid_triangle_to_vertex.py +49 -0
- scadpy/d3/solid/topologies/vertex/__init__.py +7 -0
- scadpy/d3/solid/topologies/vertex/get_solid_vertex_coordinates.py +39 -0
- scadpy/d3/solid/topologies/vertex/get_solid_vertex_to_part.py +37 -0
- scadpy/d3/solid/transformations/__init__.py +23 -0
- scadpy/d3/solid/transformations/color_solid.py +46 -0
- scadpy/d3/solid/transformations/convexify_solid.py +64 -0
- scadpy/d3/solid/transformations/mirror_solid.py +53 -0
- scadpy/d3/solid/transformations/pull_solid.py +67 -0
- scadpy/d3/solid/transformations/push_solid.py +67 -0
- scadpy/d3/solid/transformations/recoordinate_solid.py +68 -0
- scadpy/d3/solid/transformations/resize_solid.py +92 -0
- scadpy/d3/solid/transformations/rotate_solid.py +93 -0
- scadpy/d3/solid/transformations/scale_solid.py +58 -0
- scadpy/d3/solid/transformations/translate_solid.py +54 -0
- scadpy/d3/solid/types/__init__.py +3 -0
- scadpy/d3/solid/types/solid.py +448 -0
- scadpy/d3/utils/__init__.py +3 -0
- scadpy/d3/utils/resolve_vector_3d.py +50 -0
- scadpy/utils/__init__.py +6 -0
- scadpy/utils/resolve_vector.py +64 -0
- scadpy/utils/x.py +38 -0
- scadpy/utils/y.py +38 -0
- scadpy/utils/z.py +38 -0
- scadpy-0.1.0.dist-info/METADATA +282 -0
- scadpy-0.1.0.dist-info/RECORD +236 -0
- scadpy-0.1.0.dist-info/WHEEL +4 -0
- 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,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,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)
|
scadpy/utils/__init__.py
ADDED
|
@@ -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
|