engeom 0.2.13__cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl → 0.2.14__cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.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.
- engeom/_plot/pyvista.py +20 -2
- engeom/align.pyi +9 -1
- engeom/engeom.abi3.so +0 -0
- engeom/geom3.pyi +150 -0
- engeom/sensors/__init__.py +6 -0
- engeom/sensors.pyi +90 -0
- {engeom-0.2.13.dist-info → engeom-0.2.14.dist-info}/METADATA +1 -7
- {engeom-0.2.13.dist-info → engeom-0.2.14.dist-info}/RECORD +9 -9
- {engeom-0.2.13.dist-info → engeom-0.2.14.dist-info}/WHEEL +1 -1
- engeom/sensor/__init__.py +0 -6
- engeom/sensor.pyi +0 -58
engeom/_plot/pyvista.py
CHANGED
@@ -8,7 +8,7 @@ from typing import List, Any, Dict, Union, Iterable, Tuple
|
|
8
8
|
|
9
9
|
import numpy
|
10
10
|
|
11
|
-
from engeom.geom3 import Mesh, Curve3, Vector3, Point3, Iso3, SurfacePoint3
|
11
|
+
from engeom.geom3 import Mesh, Curve3, Vector3, Point3, Iso3, SurfacePoint3, PointCloud
|
12
12
|
from engeom.metrology import Distance3
|
13
13
|
from .common import LabelPlace
|
14
14
|
|
@@ -43,7 +43,7 @@ else:
|
|
43
43
|
def add_points(self, *points, color: pyvista.ColorLike = "b", point_size: float = 5.0,
|
44
44
|
render_points_as_spheres: bool = True, **kwargs) -> pyvista.vtkActor:
|
45
45
|
"""
|
46
|
-
Add one or more points to be plotted.
|
46
|
+
Add one or more discrete points to be plotted.
|
47
47
|
:param points: The points to add.
|
48
48
|
:param color: The color to use for the point(s).
|
49
49
|
:param point_size: The size of the point(s).
|
@@ -111,6 +111,24 @@ else:
|
|
111
111
|
data = pyvista.PolyData(mesh.vertices, faces)
|
112
112
|
return self.plotter.add_mesh(data, **kwargs)
|
113
113
|
|
114
|
+
def add_point_cloud(self, cloud: PointCloud, use_colors: bool = True, normal_arrow_size: float = 0.0, **kwargs):
|
115
|
+
actors = []
|
116
|
+
if normal_arrow_size >= 0.0 and cloud.normals is not None:
|
117
|
+
arrow_color = kwargs.get("color", "gray")
|
118
|
+
arrow_actor = self.plotter.add_arrows(cloud.points, cloud.normals, mag=normal_arrow_size,
|
119
|
+
color=arrow_color, reset_camera=False)
|
120
|
+
actors.append(arrow_actor)
|
121
|
+
|
122
|
+
if use_colors and cloud.colors is not None:
|
123
|
+
kwargs.pop("color", None) # Remove color if it's set, as colors will be used from the cloud
|
124
|
+
kwargs["scalars"] = cloud.colors
|
125
|
+
kwargs["rgba"] = True
|
126
|
+
|
127
|
+
point_actor = self.plotter.add_points(cloud.points, **kwargs)
|
128
|
+
actors.append(point_actor)
|
129
|
+
|
130
|
+
return actors
|
131
|
+
|
114
132
|
def distance(
|
115
133
|
self,
|
116
134
|
distance: Distance3,
|
engeom/align.pyi
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
import numpy
|
3
3
|
from .engeom import DeviationMode
|
4
|
-
from .geom3 import Mesh, Iso3
|
4
|
+
from .geom3 import Mesh, Iso3, PointCloud
|
5
5
|
|
6
6
|
|
7
7
|
def points_to_mesh(
|
@@ -21,4 +21,12 @@ def points_to_mesh(
|
|
21
21
|
and the mesh is calculated.
|
22
22
|
:return: the isometry that best aligns the points to the mesh.
|
23
23
|
"""
|
24
|
+
...
|
25
|
+
|
26
|
+
def points_to_cloud(
|
27
|
+
points: numpy.ndarray[float],
|
28
|
+
cloud: PointCloud,
|
29
|
+
search_radius: float,
|
30
|
+
initial: Iso3,
|
31
|
+
) -> Iso3:
|
24
32
|
...
|
engeom/engeom.abi3.so
CHANGED
Binary file
|
engeom/geom3.pyi
CHANGED
@@ -1796,3 +1796,153 @@ class RayBundle3:
|
|
1796
1796
|
:return:
|
1797
1797
|
"""
|
1798
1798
|
...
|
1799
|
+
|
1800
|
+
|
1801
|
+
class PointCloud:
|
1802
|
+
"""
|
1803
|
+
|
1804
|
+
"""
|
1805
|
+
|
1806
|
+
def __init__(self, points: NDArray[float], normals: NDArray[float] | None = None,
|
1807
|
+
colors: NDArray[numpy.uint8] | None = None):
|
1808
|
+
...
|
1809
|
+
|
1810
|
+
@property
|
1811
|
+
def points(self) -> NDArray[float]:
|
1812
|
+
"""
|
1813
|
+
Get the points of the point cloud as a numpy array of shape (n, 3).
|
1814
|
+
:return: a numpy array of shape (n, 3) containing the points of the point cloud.
|
1815
|
+
"""
|
1816
|
+
...
|
1817
|
+
|
1818
|
+
@property
|
1819
|
+
def normals(self) -> NDArray[float] | None:
|
1820
|
+
"""
|
1821
|
+
Get the normals of the point cloud as a numpy array of shape (n, 3). If no normals were provided, this will
|
1822
|
+
return None.
|
1823
|
+
:return: a numpy array of shape (n, 3) containing the normals of the point cloud, or None if no normals were
|
1824
|
+
provided.
|
1825
|
+
"""
|
1826
|
+
...
|
1827
|
+
|
1828
|
+
@property
|
1829
|
+
def colors(self) -> NDArray[numpy.uint8] | None:
|
1830
|
+
"""
|
1831
|
+
Get the colors of the point cloud as a numpy array of shape (n, 3). If no colors were provided, this will
|
1832
|
+
return None.
|
1833
|
+
:return: a numpy array of shape (n, 3) containing the colors of the point cloud, or None if no colors were
|
1834
|
+
provided.
|
1835
|
+
"""
|
1836
|
+
...
|
1837
|
+
|
1838
|
+
def cloned(self) -> PointCloud:
|
1839
|
+
"""
|
1840
|
+
Create a copy of the point cloud. This will return a new `PointCloud` object with the same points, normals, and
|
1841
|
+
colors as the original.
|
1842
|
+
|
1843
|
+
:return: a new `PointCloud` object with the same points, normals, and colors as the original.
|
1844
|
+
"""
|
1845
|
+
...
|
1846
|
+
|
1847
|
+
@staticmethod
|
1848
|
+
def load_lptf3(path: str | Path, take_every : int | None = None) -> PointCloud:
|
1849
|
+
"""
|
1850
|
+
Load a point cloud from a LPTF3 file. The LPTF3 format is a binary format used to store measurements from a
|
1851
|
+
triangulation-based laser profile sensor.
|
1852
|
+
|
1853
|
+
:param path: the path to the LPTF3 file to load.
|
1854
|
+
:param take_every: if provided, this will take every nth row from the file, and will be used to estimate the
|
1855
|
+
spacing of the points along the profile to also sample at a rough distance
|
1856
|
+
:return: a `PointCloud` object containing the points, normals, and colors from the file.
|
1857
|
+
"""
|
1858
|
+
...
|
1859
|
+
|
1860
|
+
def append(self, other: PointCloud) -> PointCloud:
|
1861
|
+
"""
|
1862
|
+
Append another point cloud to this one. The points, normals, and colors from the other point cloud will be
|
1863
|
+
added to this point cloud.
|
1864
|
+
|
1865
|
+
Will throw an error if the other point cloud has a different combination of normals and colors than this one.
|
1866
|
+
|
1867
|
+
:param other: the other point cloud to append.
|
1868
|
+
:return: a new `PointCloud` object containing the combined points, normals, and colors.
|
1869
|
+
"""
|
1870
|
+
...
|
1871
|
+
|
1872
|
+
def sample_poisson_disk(self, radius: float) -> list[int]:
|
1873
|
+
"""
|
1874
|
+
Sample a subset of points from the point cloud using a Poisson disk sampling algorithm. This will return a list
|
1875
|
+
of indices of the points that were preserved. The points will be selected such that no two points are closer
|
1876
|
+
than the given radius.
|
1877
|
+
|
1878
|
+
:param radius: the minimum distance between sampled points.
|
1879
|
+
:return: a list of indices of the points that were selected.
|
1880
|
+
"""
|
1881
|
+
...
|
1882
|
+
|
1883
|
+
def create_from_indices(self, indices: list[int]) -> PointCloud:
|
1884
|
+
"""
|
1885
|
+
Create a new point cloud from a subset of the points in this point cloud, specified by the given indices.
|
1886
|
+
The normals and colors will also be subsetted to match the points.
|
1887
|
+
|
1888
|
+
:param indices: a list of indices to select from the point cloud.
|
1889
|
+
:return: a new `PointCloud` object containing the selected points, normals, and colors.
|
1890
|
+
"""
|
1891
|
+
...
|
1892
|
+
|
1893
|
+
def create_from_poisson_sample(self, radius: float) -> PointCloud:
|
1894
|
+
"""
|
1895
|
+
Create a new point cloud from a Poisson disk sampling of the points in this point cloud. The points will be
|
1896
|
+
selected such that no two points are closer than the given radius.
|
1897
|
+
|
1898
|
+
:param radius: the minimum distance between sampled points.
|
1899
|
+
:return: a new `PointCloud` object containing the sampled points, normals, and colors.
|
1900
|
+
"""
|
1901
|
+
...
|
1902
|
+
|
1903
|
+
def transform_by(self, iso: Iso3) -> PointCloud:
|
1904
|
+
"""
|
1905
|
+
Transform the point cloud by an isometry. This will return a new `PointCloud` object with the transformed
|
1906
|
+
points, normals, and colors.
|
1907
|
+
|
1908
|
+
:param iso: the isometry to transform the point cloud by.
|
1909
|
+
:return: a new `PointCloud` object with the transformed points, normals, and colors.
|
1910
|
+
"""
|
1911
|
+
...
|
1912
|
+
|
1913
|
+
def overlap_points_by_reciprocity(self, other: PointCloud, max_distance: float) -> list[int]:
|
1914
|
+
"""
|
1915
|
+
Find the indices of points in this point cloud that "overlap" with points in another point
|
1916
|
+
cloud by looking for reciprocity in the closest point in each direction.
|
1917
|
+
|
1918
|
+
For each point in this point cloud "p_this", we will find the closest point in the other
|
1919
|
+
point cloud "p_other". Then we take "p_other" and find the closest point to it in this
|
1920
|
+
point cloud, "p_recip".
|
1921
|
+
|
1922
|
+
In an ideally overlapping point cloud, "p_recip" should be the same as "p_this". We will
|
1923
|
+
use a maximum distance tolerance to determine if "p_recip" is close enough to "p_this" that
|
1924
|
+
"p_this" is considered to be overlapping with the other point cloud.
|
1925
|
+
|
1926
|
+
:param other: the other point cloud to check for overlap.
|
1927
|
+
:param max_distance: the maximum distance to consider a point as overlapping.
|
1928
|
+
:return: a list of indices of points in this point cloud that overlap with points in the other point cloud.
|
1929
|
+
"""
|
1930
|
+
...
|
1931
|
+
|
1932
|
+
def overlap_mesh_by_reciprocity(self, mesh: Mesh, max_distance: float) -> list[int]:
|
1933
|
+
"""
|
1934
|
+
Find the indices of points in this point cloud that "overlap" with triangles in a mesh by looking for
|
1935
|
+
reciprocity in the closest point in each direction.
|
1936
|
+
|
1937
|
+
For each point in this point cloud "p_this", we will find the closest point on the surface of the mesh
|
1938
|
+
"p_other". Then we will take "p_other" and find the closest point in the point cloud, "p_recip".
|
1939
|
+
|
1940
|
+
In an ideally overlapping point cloud, "p_this" should be the same as "p_recip". We will use a maximum
|
1941
|
+
distance tolerance instead to determine if "p_recip" is close enough to "p_this" that "p_this" is
|
1942
|
+
considered to be overlapping with the mesh.
|
1943
|
+
|
1944
|
+
:param mesh: the mesh to check for overlap.
|
1945
|
+
:param max_distance: the maximum distance to consider a point as overlapping.
|
1946
|
+
:return: a list of indices of points in this point cloud that overlap with triangles in the mesh.
|
1947
|
+
"""
|
1948
|
+
...
|
engeom/sensors.pyi
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from .geom3 import Point3, Mesh, Iso3, Vector3, PointCloud
|
4
|
+
|
5
|
+
|
6
|
+
class LaserProfile:
|
7
|
+
def __init__(
|
8
|
+
self,
|
9
|
+
emitter_z: float,
|
10
|
+
detector_y: float,
|
11
|
+
detector_z: float,
|
12
|
+
volume_width: float,
|
13
|
+
volume_z_min: float,
|
14
|
+
volume_z_max: float,
|
15
|
+
resolution: int,
|
16
|
+
angle_limit: float | None = None,
|
17
|
+
):
|
18
|
+
"""
|
19
|
+
Create the base geometry of a laser profile line sensor, which emits a laser line into a
|
20
|
+
scene and detects the reflection of that line to triangulate the distance to points on a
|
21
|
+
surface.
|
22
|
+
|
23
|
+
The general coordinate system is specified in X and Z. The center of the detection volume
|
24
|
+
is at the origin, with the laser line ranging from the -X direction to the +X direction.
|
25
|
+
The +Z direction points directly up towards the emitter. The +Y direction is orthogonal to
|
26
|
+
laser line and is typically the direction which the sensor will be panned.
|
27
|
+
|
28
|
+
The geometry is specified with the following assumptions:
|
29
|
+
- The laser line is emitted from a point directly on the +Z axis, with no offset in
|
30
|
+
the X or Y direction.
|
31
|
+
- The detector is not offset in the X direction, and can be specified with a Y and
|
32
|
+
Z offset from the center of the detection volume.
|
33
|
+
- The detection volume is trapezoidal, and its flat top and bottom are specified by a
|
34
|
+
maximum and minimum Z value.
|
35
|
+
- The detection volume's with is specified at Z=0, and is symmetrical around X=0.
|
36
|
+
|
37
|
+
# Arguments
|
38
|
+
|
39
|
+
:param emitter_z: The Z coordinate of the laser emitter. This is the height from the volume
|
40
|
+
center where the laser fans into a triangle.
|
41
|
+
:param detector_y: The Y coordinate of the detector's optical center. This is the out-of-plane
|
42
|
+
offset from the plane of the laser line.
|
43
|
+
:param detector_z: The Z coordinate of the detector's optical center. This is the height from
|
44
|
+
the volume center where the detector's optical center is located.
|
45
|
+
:param volume_width: The width of the detection volume at Z=0. The volume is assumed to be
|
46
|
+
symmetrical around the X axis, ranging from -volume_width/2 to +volume_width/2.
|
47
|
+
:param volume_z_min: The minimum Z value of the detection volume. This is the bottom of the
|
48
|
+
trapezoidal volume, the farthest distance from the emitter where the sensor will still
|
49
|
+
return points.
|
50
|
+
:param volume_z_max: The maximum Z value of the detection volume. This is the top of the
|
51
|
+
trapezoidal volume, the closest distance to the emitter where the sensor will still
|
52
|
+
return points.
|
53
|
+
:param resolution: The number of rays to cast across the laser line. This is the number of
|
54
|
+
points that will be returned in the point cloud.
|
55
|
+
:param angle_limit: An optional angle limit in radians. If specified, the sensor will only
|
56
|
+
return a point if the angle between the surface normal at the point and the detector is
|
57
|
+
less than this limit.
|
58
|
+
"""
|
59
|
+
...
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
def get_points(self, target: Mesh, obstruction: Mesh | None, iso: Iso3) -> PointCloud:
|
64
|
+
"""
|
65
|
+
|
66
|
+
:param target:
|
67
|
+
:param obstruction:
|
68
|
+
:param iso:
|
69
|
+
:return:
|
70
|
+
"""
|
71
|
+
...
|
72
|
+
|
73
|
+
|
74
|
+
class PanningLaserProfile:
|
75
|
+
def __init__(self, laser_line: LaserProfile, y_step: float, steps: int):
|
76
|
+
"""
|
77
|
+
:param laser_line:
|
78
|
+
:param y_step:
|
79
|
+
:param steps:
|
80
|
+
"""
|
81
|
+
...
|
82
|
+
|
83
|
+
def get_points(self, target: Mesh, obstruction: Mesh | None, iso: Iso3) -> PointCloud:
|
84
|
+
"""
|
85
|
+
:param target:
|
86
|
+
:param obstruction:
|
87
|
+
:param iso:
|
88
|
+
:return:
|
89
|
+
"""
|
90
|
+
...
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: engeom
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.14
|
4
4
|
Classifier: Programming Language :: Rust
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
@@ -8,9 +8,3 @@ Requires-Dist: numpy
|
|
8
8
|
Requires-Dist: pytest ; extra == 'tests'
|
9
9
|
Provides-Extra: tests
|
10
10
|
Requires-Python: >=3.8
|
11
|
-
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
12
|
-
|
13
|
-
# Engeom Python Bindings
|
14
|
-
|
15
|
-
Full documentation at https://mattj23.github.io/py-engeom/
|
16
|
-
|
@@ -1,25 +1,25 @@
|
|
1
|
-
engeom-0.2.
|
2
|
-
engeom-0.2.
|
1
|
+
engeom-0.2.14.dist-info/METADATA,sha256=oStO5eN3cCvP72aY8o0l-qTLhp91P8-0yG9ASVBFpaA,340
|
2
|
+
engeom-0.2.14.dist-info/WHEEL,sha256=9u0jSXl_m-TIQSYFMWCr0jbsFV_asy5EUcTos8UaOwU,129
|
3
3
|
engeom/__init__.py,sha256=QN5uETqrN442w41foyrcCPV_x6NP-mrxkPJhdvdey1g,109
|
4
4
|
engeom/_plot/__init__.py,sha256=F_KviZtxzZGwfEjjn8Ep46N4UVl8VpFJWBzbBUE_J7A,30
|
5
5
|
engeom/_plot/common.py,sha256=Py78ufN3yi59hPwv21SoGcqyZUJS-_PmK8tlAKgSG7Q,517
|
6
6
|
engeom/_plot/matplotlib.py,sha256=ahLfgE3QHUFcNig6cHkFu9mwSwfMbDcNqkZmGaBh4Zk,15267
|
7
|
-
engeom/_plot/pyvista.py,sha256=
|
7
|
+
engeom/_plot/pyvista.py,sha256=lzwDWUFTbq1cR46nwVtuK4nn_hzbZnXiJPdoxHcKVDU,13930
|
8
8
|
engeom/airfoil.pyi,sha256=SivSrUo3LZSVgXwIFJtgUUejhPh71y8rekzBwaX6exI,24165
|
9
9
|
engeom/airfoil/__init__.py,sha256=gpS9pVepUu90XJ-ePndNupbUMKI0RGxNXPxD9x0iVHY,274
|
10
|
-
engeom/align.pyi,sha256=
|
10
|
+
engeom/align.pyi,sha256=OffG6hHhUt8ujWnE2iaH50TxoQ-B-p0Go1DcrftpUYc,1176
|
11
11
|
engeom/align/__init__.py,sha256=SEeMqeqLKqJC73Mg8GwPwd9NwWnl-dcCqJ4rPdh8yyc,196
|
12
|
-
engeom/engeom.abi3.so,sha256=
|
12
|
+
engeom/engeom.abi3.so,sha256=SiD5gdDrS_4ocD7JcsilIYaElRaRBeb2o9TozNfL9F8,4829144
|
13
13
|
engeom/engeom.pyi,sha256=BtUBtYZ_MX8Xk2x_FyzVxRXjJQIazQ1xscbCLO_Y3HA,1516
|
14
14
|
engeom/geom2.pyi,sha256=oUSner8BEJzJLv82POfOGyjAESw-McZzPq51o9VbdYg,51601
|
15
15
|
engeom/geom2/__init__.py,sha256=JFpiLyROUh6vyakG-7JDSlCMCn4QB2MQ8bz3uVCaAIk,373
|
16
|
-
engeom/geom3.pyi,sha256=
|
16
|
+
engeom/geom3.pyi,sha256=yU5Z85XQtr9YlN3fhhi_DQyd-gYNkkL0zb4asscLsaU,84476
|
17
17
|
engeom/geom3/__init__.py,sha256=l8B0iDhJ4YiRbslJLN791XWai2DWrpmZptnzIETMS9g,370
|
18
18
|
engeom/metrology.pyi,sha256=9I5un86VB_2gmQBrVYhX8JzILTUADMLB9Em8ttJxrWg,4044
|
19
19
|
engeom/metrology/__init__.py,sha256=XvEhG8uDm1olWwZHDDrQv9LFP5zXhbsGx27PqRq8WE0,304
|
20
20
|
engeom/plot.py,sha256=LTqqO-h1EJL6wanM0hB79s9ohWwaCIijMOHVplY3vmc,1079
|
21
21
|
engeom/raster3.pyi,sha256=sBXXYXcDBiDU_OFDQiwa7Q3GcwSiUc4CLy6nJ1MwFqM,790
|
22
22
|
engeom/raster3/__init__.py,sha256=iaayLrvco-ZMZPyeK47ox7rYne_51DNb2T2Q0iNNeKE,289
|
23
|
-
engeom/
|
24
|
-
engeom/
|
25
|
-
engeom-0.2.
|
23
|
+
engeom/sensors.pyi,sha256=cnCQLCNq43zkWeIGWNvX409RPhE9T7zhTCu9lvxXF_c,3933
|
24
|
+
engeom/sensors/__init__.py,sha256=vy1CXX3gQcaBL25imYmpSAJhlc8v5aDBEBtF6L0PVCs,182
|
25
|
+
engeom-0.2.14.dist-info/RECORD,,
|
engeom/sensor/__init__.py
DELETED
engeom/sensor.pyi
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
from .geom3 import Point3, Mesh, Iso3, Vector3
|
3
|
-
from numpy.typing import NDArray
|
4
|
-
|
5
|
-
|
6
|
-
class LaserLine:
|
7
|
-
def __init__(
|
8
|
-
self,
|
9
|
-
ray_origin: Point3,
|
10
|
-
detect_origin: Point3,
|
11
|
-
line_start: Point3,
|
12
|
-
line_end: Point3,
|
13
|
-
min_range: float,
|
14
|
-
max_range: float,
|
15
|
-
rays: int,
|
16
|
-
angle_limit: float | None = None,
|
17
|
-
):
|
18
|
-
"""
|
19
|
-
|
20
|
-
:param ray_origin:
|
21
|
-
:param detect_origin:
|
22
|
-
:param line_start:
|
23
|
-
:param line_end:
|
24
|
-
:param min_range:
|
25
|
-
:param max_range:
|
26
|
-
:param rays:
|
27
|
-
:param angle_limit:
|
28
|
-
"""
|
29
|
-
...
|
30
|
-
|
31
|
-
def get_points(self, target: Mesh, obstruction: Mesh | None, iso: Iso3) -> NDArray[float]:
|
32
|
-
"""
|
33
|
-
|
34
|
-
:param target:
|
35
|
-
:param obstruction:
|
36
|
-
:param iso:
|
37
|
-
:return:
|
38
|
-
"""
|
39
|
-
...
|
40
|
-
|
41
|
-
|
42
|
-
class PanningLaserLine:
|
43
|
-
def __init__(self, laser_line: LaserLine, pan_vector: Vector3, steps: int):
|
44
|
-
"""
|
45
|
-
:param laser_line:
|
46
|
-
:param pan_vector:
|
47
|
-
:param steps:
|
48
|
-
"""
|
49
|
-
...
|
50
|
-
|
51
|
-
def get_points(self, target: Mesh, obstruction: Mesh | None, iso: Iso3) -> NDArray[float]:
|
52
|
-
"""
|
53
|
-
:param target:
|
54
|
-
:param obstruction:
|
55
|
-
:param iso:
|
56
|
-
:return:
|
57
|
-
"""
|
58
|
-
...
|