engeom 0.2.14__cp38-abi3-win_amd64.whl → 0.2.16__cp38-abi3-win_amd64.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/align.pyi CHANGED
@@ -29,4 +29,25 @@ def points_to_cloud(
29
29
  search_radius: float,
30
30
  initial: Iso3,
31
31
  ) -> Iso3:
32
+ ...
33
+
34
+ def mesh_to_mesh_iterative(
35
+ mesh: Mesh,
36
+ reference: Mesh,
37
+ sample_spacing: float,
38
+ initial: Iso3,
39
+ mode: DeviationMode,
40
+ max_iter: int
41
+ ) -> Iso3:
42
+ """
43
+ Perform an iterative alignment of a mesh to a reference mesh using the specified parameters.
44
+
45
+ :param mesh: the mesh to align.
46
+ :param reference: the reference mesh to align to.
47
+ :param sample_spacing: the spacing between samples for the alignment.
48
+ :param initial: the initial guess for the isometry.
49
+ :param mode: the mode to use for the deviation calculation.
50
+ :param max_iter: the maximum number of iterations to perform.
51
+ :return: the isometry that best aligns the mesh to the reference mesh.
52
+ """
32
53
  ...
engeom/engeom.pyd CHANGED
Binary file
engeom/geom3.pyi CHANGED
@@ -11,6 +11,50 @@ import metrology
11
11
  Transformable3 = TypeVar("Transformable3", Vector3, Point3, Plane3, Iso3, SurfacePoint3)
12
12
  PointOrVector3 = TypeVar("PointOrVector3", Vector3, Point3)
13
13
 
14
+ type Lptf3LoadEnum = Lptf3Load.All | Lptf3Load.TakeEveryN | Lptf3Load.SmoothSample
15
+
16
+
17
+ class Lptf3Load:
18
+ """
19
+ An enumeration representing the different load types that can be used when loading LPTF3 files.
20
+ """
21
+
22
+ class All:
23
+ def __init__(self):
24
+ """
25
+ Load all points from the file
26
+ """
27
+ ...
28
+
29
+ class TakeEveryN:
30
+ def __init__(self, n: int):
31
+ """
32
+ Load every nth row from the file. The loader will attempt to roughly match the inter-row spacing when
33
+ loading the individual points, resulting in an approximate grid-like array of points.
34
+ :param n: the interval at which to take rows from the file.
35
+ """
36
+ ...
37
+
38
+ class SmoothSample:
39
+ def __init__(self, take_every: int, look_scale: float, weight_scale: float, max_move: float):
40
+ """
41
+ Load the points using a downsampling filter, which downsamples the point cloud similar to the `TakeEveryN`
42
+ method, but also performs a gaussian smoothing step using the full original cloud. This takes the longest
43
+ time, but can remove a significant amount of noise from the data by making use of an adjacency structure
44
+ that will be lost once the points are turned into a cloud.
45
+
46
+ :param take_every: the interval at which to take rows from the file.
47
+ :param look_scale: smoothing will use a sampling window relative to the `take_every` spacing, so a value
48
+ of 1 will use the same spacing as `take_every`, while a value of 2 will use twice that spacing. A reasonable
49
+ default for preserving detail is 0.5.
50
+ :param weight_scale: during the gaussian smoothing, neighboring points will be weighted by their distance
51
+ from the point being smoothed. At `weight_scale` of 1, the standard deviation of the gaussian will be
52
+ slightly larger than the `look_scale` distance.
53
+ :param max_move: the maximum distance a point can move when smoothing. If a point attempts to move more
54
+ than 10x this distance, it will not be moved at all. Otherwise, it will be clamped to within this distance.
55
+ """
56
+ ...
57
+
14
58
 
15
59
  class Vector3(Iterable[float]):
16
60
  """
@@ -487,6 +531,21 @@ class Iso3:
487
531
  """ Return the identity isometry. """
488
532
  ...
489
533
 
534
+ @staticmethod
535
+ def from_quaternion(tx: float, ty: float, tz: float, i: float, j: float, k: float, w: float) -> Iso3:
536
+ """
537
+ Create an isometry from a translation and a quaternion representing the rotation.
538
+ :return: an isometry containing both translation and rotation components.
539
+ """
540
+ ...
541
+
542
+ def to_quaternion(self) -> Tuple[float, float, float, float, float, float, float]:
543
+ """
544
+ Convert the isometry to a tuple containing the translation and quaternion components.
545
+ :return: a tuple of 7 floats in the order (tx, ty, tz, i, j, k, w)
546
+ """
547
+ ...
548
+
490
549
  @staticmethod
491
550
  def from_translation(x: float, y: float, z: float) -> Iso3:
492
551
  """
@@ -956,6 +1015,36 @@ class Mesh:
956
1015
  """
957
1016
  ...
958
1017
 
1018
+ @staticmethod
1019
+ def load_lptf3(path: str | Path, params: Lptf3LoadEnum) -> Mesh:
1020
+ """
1021
+ This function reads a LPTF3 file, which is a compact file format for storing 3D point data
1022
+ taken from a laser profile triangulation scanner. The format is simple and compact, capable
1023
+ of practically storing about 200k points (with an 8-bit color value each) per MB when using a
1024
+ 16-bit coordinate format, or half that when using a 32-bit coordinate format.
1025
+
1026
+ There are a few different ways to load the data, controlled by the `Lptf3Load` enum:
1027
+ - `Lptf3Load.All`: Load all points from the file.
1028
+ - `Lptf3Load.TakeEveryN(n)`: Load every Nth row from the file. The loader will attempt to
1029
+ roughly match the x spacing of the points to the gap distance between rows, resulting in a
1030
+ grid-like point cloud with an approximately uniform point spacing when viewed from the
1031
+ X-Y plane. This is a very fast method of retrieving a downsampled set of points.
1032
+ - `Lptf3Load.SmoothSample(params)`: Load the points using a downsampling filter, which
1033
+ downsamples the point cloud similar to the `TakeEveryN` method, but also performs a gaussian
1034
+ smoothing step using the full original cloud. This takes the longest time, but can remove
1035
+ a significant amount of noise from the data by making use of an adjacency structure that
1036
+ will be lost once the points are turned into a mesh.
1037
+
1038
+ Once the points are loaded, they will be converted into a triangle mesh by connecting points in adjacent
1039
+ rows with triangles that meet certain edge length criterial. The result is a fast mesh that can be built
1040
+ using knowledge of the LPTF3's internal structure rather than having to rely on more general techniques
1041
+ that can build meshes from arbitrary point clouds.
1042
+
1043
+ :param path: the path to the LPTF3 file to load.
1044
+ :param params: the method and parameters to use when loading the LPTF3 file.
1045
+ """
1046
+ ...
1047
+
959
1048
  def write_stl(self, path: str | Path):
960
1049
  """
961
1050
  Write the mesh to an STL file. This will write the vertices and triangles of the mesh to the file in binary
@@ -1082,6 +1171,35 @@ class Mesh:
1082
1171
  """
1083
1172
  ...
1084
1173
 
1174
+ def sample_alignment_points(
1175
+ self,
1176
+ reference: Mesh,
1177
+ iso: Iso3,
1178
+ max_spacing: float,
1179
+ max_neighbor_angle: float,
1180
+ out_of_plane_ratio: float,
1181
+ centroid_ratio: float,
1182
+ filter_distances: float | None
1183
+ ) -> NDArray[float]:
1184
+ """
1185
+ This is a very specialized, highly selective sampling method used to identify high quality points for
1186
+ the alignment between two meshes. It begins with a Poisson disk sampling of the mesh, and then inspects the
1187
+ individual points to evaluate the quality and consistency of their local neighborhood, before projecting their
1188
+ local neighborhood onto the reference mesh and looking for the same qualities in the projections.
1189
+
1190
+ This method will return a numpy array of points which are spaced at least `max_spacing` apart, and which lie
1191
+ on areas of the mesh of low curvature, away from corners and edges, and which plausibly overlap with a
1192
+ correspondingly low-curvature area of the reference mesh away from its corners and edges.
1193
+
1194
+ :param max_spacing: a Poisson disk sampling radius used to start sampling the mesh. This value is also used to
1195
+ derive a set of physical limits which will selectively filter different aspects of the sample points.
1196
+ :param reference: the reference mesh that the alignment candidates will be sampled against. Assuming these
1197
+ points will be used to perform an alignment, this mesh should be the one that is being aligned to.
1198
+ :param iso: an isometry to apply to the sampled points before checking against the reference mesh.
1199
+ :return: a numpy array of shape (n, 3) containing the sampled points.
1200
+ """
1201
+ ...
1202
+
1085
1203
  def section(self, plane: Plane3, tol: float | None = None) -> List[Curve3]:
1086
1204
  """
1087
1205
  Calculate and return the intersection curves between the mesh and a plane.
@@ -1208,6 +1326,27 @@ class Mesh:
1208
1326
  """
1209
1327
  ...
1210
1328
 
1329
+ def barycentric_closest_to(self, x: float, y: float, z: float) -> Tuple[int, List[float]]:
1330
+ """
1331
+ Find the closest point on the surface of the mesh to a given point in space, returning the triangle index and
1332
+ the barycentric coordinates of the closest point within that triangle.
1333
+ :param x: the x coordinate of the point to find the closest point to
1334
+ :param y: the y coordinate of the point to find the closest point to
1335
+ :param z: the z coordinate of the point to find the closest point to
1336
+ :return: a tuple containing the triangle index and a list of three barycentric coordinates
1337
+ """
1338
+ ...
1339
+
1340
+ def point_closest_to(self, x: float, y: float, z: float) -> Point3:
1341
+ """
1342
+ Find the closest point on the surface of the mesh to a given point in space, returning the point
1343
+ :param x: the x coordinate of the point to find the closest point to
1344
+ :param y: the y coordinate of the point to find the closest point to
1345
+ :param z: the z coordinate of the point to find the closest point to
1346
+ :return: a `Point3` object containing the closest point and normal
1347
+ """
1348
+ ...
1349
+
1211
1350
  def visual_outline(
1212
1351
  self,
1213
1352
  facing: Vector3,
@@ -1241,6 +1380,16 @@ class Mesh:
1241
1380
  """
1242
1381
  ...
1243
1382
 
1383
+ def boundary_curves(self) -> List[Curve3]:
1384
+ """
1385
+ Extract the boundary curves of the mesh. This will return a list of `Curve3` objects representing the
1386
+ boundaries of the mesh. The curves will be ordered in a way that they can be used to reconstruct the boundary
1387
+ of the mesh.
1388
+
1389
+ :return: a list of `Curve3` objects representing the boundary curves of the mesh.
1390
+ """
1391
+ ...
1392
+
1244
1393
  @staticmethod
1245
1394
  def create_box(length: float, width: float, height: float) -> Mesh:
1246
1395
  """
@@ -1845,15 +1994,38 @@ class PointCloud:
1845
1994
  ...
1846
1995
 
1847
1996
  @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.
1997
+ def load_lptf3(path: str | Path, params: Lptf3LoadEnum) -> PointCloud:
1998
+ """
1999
+ This function reads a LPTF3 file, which is a compact file format for storing 3D point data
2000
+ taken from a laser profile triangulation scanner. The format is simple and compact, capable
2001
+ of practically storing about 200k points (with an 8-bit color value each) per MB when using a
2002
+ 16-bit coordinate format, or half that when using a 32-bit coordinate format.
2003
+
2004
+ There are a few different ways to load the data, controlled by the `Lptf3Load` enum:
2005
+ - `Lptf3Load.All`: Load all points from the file.
2006
+ - `Lptf3Load.TakeEveryN(n)`: Load every Nth row from the file. The loader will attempt to
2007
+ roughly match the x spacing of the points to the gap distance between rows, resulting in a
2008
+ grid-like point cloud with an approximately uniform point spacing when viewed from the
2009
+ X-Y plane. This is a very fast method of retrieving a downsampled point cloud.
2010
+ - `Lptf3Load.SmoothSample(params)`: Load the points using a downsampling filter, which
2011
+ downsamples the point cloud similar to the `TakeEveryN` method, but also performs a gaussian
2012
+ smoothing step using the full original cloud. This takes the longest time, but can remove
2013
+ a significant amount of noise from the data by making use of an adjacency structure that
2014
+ will be lost once the points are turned into a cloud.
1852
2015
 
1853
2016
  :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.
2017
+ :param params: the method and parameters to use when loading the LPTF3 file.
2018
+ """
2019
+ ...
2020
+
2021
+ @staticmethod
2022
+ def load_bxyz(path: str | Path) -> PointCloud:
2023
+ """
2024
+ Load a point cloud from a BXYZ file. The BXYZ format is a binary format for storing 3D point clouds with
2025
+ optional normals and colors.
2026
+
2027
+ :param path: the path to the BXYZ file to load.
2028
+ :return: a new `PointCloud` object containing the points, normals, and colors from the BXYZ file.
1857
2029
  """
1858
2030
  ...
1859
2031
 
@@ -1928,7 +2100,7 @@ class PointCloud:
1928
2100
  :return: a list of indices of points in this point cloud that overlap with points in the other point cloud.
1929
2101
  """
1930
2102
  ...
1931
-
2103
+
1932
2104
  def overlap_mesh_by_reciprocity(self, mesh: Mesh, max_distance: float) -> list[int]:
1933
2105
  """
1934
2106
  Find the indices of points in this point cloud that "overlap" with triangles in a mesh by looking for
engeom/sensors.pyi CHANGED
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from pathlib import Path
4
+
3
5
  from .geom3 import Point3, Mesh, Iso3, Vector3, PointCloud
4
6
 
5
7
 
@@ -57,8 +59,6 @@ class LaserProfile:
57
59
  less than this limit.
58
60
  """
59
61
  ...
60
-
61
-
62
62
 
63
63
  def get_points(self, target: Mesh, obstruction: Mesh | None, iso: Iso3) -> PointCloud:
64
64
  """
@@ -70,6 +70,19 @@ class LaserProfile:
70
70
  """
71
71
  ...
72
72
 
73
+ def load_lptf3(self, path: str | Path, take_every: int | None = None,
74
+ normal_neighborhood: float | None = None) -> PointCloud:
75
+ """
76
+ Load a laser profile from a LPTF3 file.
77
+
78
+ :param path: The path to the LPTF3 file.
79
+ :param take_every: Optional parameter to take every nth row/col from the file.
80
+ :param normal_neighborhood: Optional parameter to specify the neighborhood size for normal
81
+ calculation.
82
+ :return: A PointCloud containing the points from the LPTF3 file.
83
+ """
84
+ ...
85
+
73
86
 
74
87
  class PanningLaserProfile:
75
88
  def __init__(self, laser_line: LaserProfile, y_step: float, steps: int):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: engeom
3
- Version: 0.2.14
3
+ Version: 0.2.16
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -1,5 +1,5 @@
1
- engeom-0.2.14.dist-info/METADATA,sha256=oStO5eN3cCvP72aY8o0l-qTLhp91P8-0yG9ASVBFpaA,340
2
- engeom-0.2.14.dist-info/WHEEL,sha256=fUMUCU57hCqRM9lAdoyg0PVMCOUk2MQLaFVqt4-GBRk,94
1
+ engeom-0.2.16.dist-info/METADATA,sha256=sX-tpGK0jbTlLML0_gcyGd-VcC_Y6Zw7ZdCgHKNnfp0,340
2
+ engeom-0.2.16.dist-info/WHEEL,sha256=F7HFsRl56IeLjGhxiHeG3IpurHNaGNHQJeIy7gdwTO4,94
3
3
  engeom/__init__.py,sha256=kYgFq3jq1quDfV013wEYQMlUBz4QNSpP6u8lFiuTHvc,115
4
4
  engeom/_plot/__init__.py,sha256=F_KviZtxzZGwfEjjn8Ep46N4UVl8VpFJWBzbBUE_J7A,30
5
5
  engeom/_plot/common.py,sha256=Py78ufN3yi59hPwv21SoGcqyZUJS-_PmK8tlAKgSG7Q,517
@@ -7,19 +7,19 @@ engeom/_plot/matplotlib.py,sha256=ahLfgE3QHUFcNig6cHkFu9mwSwfMbDcNqkZmGaBh4Zk,15
7
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=OffG6hHhUt8ujWnE2iaH50TxoQ-B-p0Go1DcrftpUYc,1176
10
+ engeom/align.pyi,sha256=SaC46l0mqANzp3JAtIk4DdXTLtKBrEr9_xW21algMTk,1935
11
11
  engeom/align/__init__.py,sha256=SEeMqeqLKqJC73Mg8GwPwd9NwWnl-dcCqJ4rPdh8yyc,196
12
- engeom/engeom.pyd,sha256=SBTV_V58YvXUKpPEt2Hm70XzLQYGeNbS5hZgoLRCGOQ,5931008
12
+ engeom/engeom.pyd,sha256=Mich0vgPnElHMKuVb-LLTDY_6UGDCOf0KUQWh1yx8x0,6128640
13
13
  engeom/engeom.pyi,sha256=J0L_D-Sc2laJHL36nUAvIP3eN9BDryAxd_6aMQarlZc,1561
14
14
  engeom/geom2.pyi,sha256=oUSner8BEJzJLv82POfOGyjAESw-McZzPq51o9VbdYg,51601
15
15
  engeom/geom2/__init__.py,sha256=JFpiLyROUh6vyakG-7JDSlCMCn4QB2MQ8bz3uVCaAIk,373
16
- engeom/geom3.pyi,sha256=yU5Z85XQtr9YlN3fhhi_DQyd-gYNkkL0zb4asscLsaU,84476
16
+ engeom/geom3.pyi,sha256=aO8kj5POqXtHpwV5kNxLJg1yLB9ZhlHadONfgM0NlBw,94397
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/sensors.pyi,sha256=cnCQLCNq43zkWeIGWNvX409RPhE9T7zhTCu9lvxXF_c,3933
23
+ engeom/sensors.pyi,sha256=8dQS6PVkbBOdbO17x9UskBOIIh6cP0EILhJXxPVXDNw,4525
24
24
  engeom/sensors/__init__.py,sha256=vy1CXX3gQcaBL25imYmpSAJhlc8v5aDBEBtF6L0PVCs,182
25
- engeom-0.2.14.dist-info/RECORD,,
25
+ engeom-0.2.16.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: maturin (1.9.0)
2
+ Generator: maturin (1.9.5)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp38-abi3-win_amd64