engeom 0.2.8__cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl → 0.2.10__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.
@@ -1,10 +1,13 @@
1
1
  from typing import List, Iterable, Tuple, Union
2
2
  import numpy
3
+
3
4
  from .common import LabelPlace
4
5
  from engeom.geom2 import Curve2, Circle2, Aabb2, Point2, Vector2, SurfacePoint2
6
+ from engeom.geom3 import Vector3, Mesh, Point3
5
7
  from engeom.metrology import Distance2
6
8
 
7
9
  PlotCoords = Union[Point2, Vector2, Iterable[float]]
10
+ PointLike = Union[Point2, Tuple[float, float], Point3]
8
11
 
9
12
  try:
10
13
  from matplotlib.pyplot import Axes, Circle
@@ -207,7 +210,7 @@ else:
207
210
 
208
211
  value = distance.value * scale_value
209
212
  box_style = dict(boxstyle="round,pad=0.3", ec="black", fc="white")
210
- self.annotate_text_only(template.format(value=value), label_coords, bbox=box_style, **kwargs)
213
+ self.text(template.format(value=value), label_coords, bbox=box_style, **kwargs)
211
214
 
212
215
  def _line_if_needed(self, pad: float, actual: Point2, leader_end: Point2):
213
216
  half_pad = pad * 0.5
@@ -218,31 +221,78 @@ else:
218
221
  t1 = work.scalar_projection(leader_end) + half_pad
219
222
  self.arrow(actual, work.at_distance(t1), arrow="-")
220
223
 
221
- def annotate_text_only(self, text: str, pos: PlotCoords, **kwargs):
224
+ def text(self, text: str, pos: PlotCoords, shift: PlotCoords | None = None, ha: str = "center",
225
+ va: str = "center", **kwargs):
222
226
  """
223
- Annotate a Matplotlib Axes object with text only.
227
+ Annotate a Matplotlib Axes object with text only, by default in the xy data plane.
224
228
  :param text: the text to annotate
225
229
  :param pos: the position of the annotation
230
+ :param shift: an optional shift vector to apply to the position
231
+ :param ha: horizontal alignment
232
+ :param va: vertical alignment
226
233
  :param kwargs: keyword arguments to pass to the annotate function
227
234
  :return: the annotation object
228
235
  """
229
- return self.ax.annotate(text, xy=_tuplefy(pos), **kwargs)
236
+ xy = _tuplefy(pos)
237
+ if shift is not None:
238
+ shift = _tuplefy(shift)
239
+ xy = (xy[0] + shift[0], xy[1] + shift[1])
240
+
241
+ return self.ax.annotate(text, xy=xy, ha=ha, va=va, **kwargs)
230
242
 
231
- def arrow(self, start: PlotCoords, end: PlotCoords, arrow="-|>"):
243
+ def points(self, *points: PlotCoords, marker="o", markersize="5", **kwargs):
244
+ x, y = zip(*[_tuplefy(p) for p in points])
245
+ return self.ax.plot(x, y, marker, markersize=markersize, **kwargs)
246
+
247
+ def labeled_arrow(self, start: PlotCoords, end: PlotCoords, text: str, fraction: float = 0.5,
248
+ shift: PlotCoords | None = None,
249
+ arrow="->", color="black", linewidth: float | None = None, linestyle="-",
250
+ **text_kwargs):
232
251
  """
233
- Plot an arrow on a Matplotlib Axes object.
234
- :param start: the start point of the arrow
235
- :param end: the end point of the arrow
236
- :param arrow: the style of arrow to use
237
- :return: the annotation object
252
+
253
+ :param start:
254
+ :param end:
255
+ :param text:
256
+ :param shift:
257
+ :param fraction:
258
+ :param arrow:
259
+ :param color:
260
+ :param linewidth:
261
+ :param linestyle:
262
+ :param text_kwargs: parameters to pass to the text function
263
+ :return:
238
264
  """
239
- return self.ax.annotate(
240
- "",
241
- xy=_tuplefy(end),
242
- xytext=_tuplefy(start),
243
- arrowprops=dict(arrowstyle=arrow, fc="black"),
265
+ start = Point2(*_tuplefy(start))
266
+ end = Point2(*_tuplefy(end))
267
+
268
+ self.arrow(start, end, arrow=arrow, color=color, linewidth=linewidth, linestyle=linestyle)
269
+
270
+ v: Vector2 = end - start
271
+ position = start + v * fraction
272
+ self.text(text, position, shift=shift, color=color, **text_kwargs)
273
+
274
+ def arrow(self, start: PlotCoords, end: PlotCoords, arrow="->", color="black", linewidth: float | None = None,
275
+ linestyle="-"):
276
+ """
277
+ Draw an arrow on a Matplotlib Axes object from `start` to `end`.
278
+ :param start:
279
+ :param end:
280
+ :param arrow:
281
+ :param color:
282
+ :param linewidth:
283
+ :param linestyle:
284
+ :return:
285
+ """
286
+ props = dict(
287
+ arrowstyle=arrow,
288
+ fc=color,
289
+ ec=color,
290
+ linewidth=linewidth,
291
+ linestyle=linestyle,
244
292
  )
245
293
 
294
+ return self.ax.annotate("", xy=_tuplefy(end), xytext=_tuplefy(start), arrowprops=props)
295
+
246
296
  def _font_height(self, font_size: int) -> float:
247
297
  # Get the height of a font in data units
248
298
  fig_dpi = self.ax.figure.dpi
@@ -273,3 +323,50 @@ def _tuplefy(item: PlotCoords) -> Tuple[float, float]:
273
323
  else:
274
324
  x, y, *_ = item
275
325
  return x, y
326
+
327
+
328
+ class TraceBuilder:
329
+ def __init__(self):
330
+ self.xs = []
331
+ self.ys = []
332
+ self.c = []
333
+
334
+ def bounds(self) -> Aabb2:
335
+ xs = [x for x in self.xs if x is not None]
336
+ ys = [y for y in self.ys if y is not None]
337
+ return Aabb2(
338
+ x_min=min(xs),
339
+ x_max=max(xs),
340
+ y_min=min(ys),
341
+ y_max=max(ys),
342
+ )
343
+
344
+ def add_segment(self, *points: PointLike):
345
+ self.add_points(*points)
346
+ self.add_blank()
347
+
348
+ def add_blank(self):
349
+ self.xs.append(None)
350
+ self.ys.append(None)
351
+ self.c.append(None)
352
+
353
+ def add_points(self, *points: PointLike):
354
+ for x, y, *_ in points:
355
+ self.xs.append(x)
356
+ self.ys.append(y)
357
+
358
+ def add_point_and_color(self, point: PointLike, color: float):
359
+ self.xs.append(point[0])
360
+ self.ys.append(point[1])
361
+ self.c.append(color)
362
+
363
+ def invert_y(self):
364
+ self.ys = [-y if y is not None else None for y in self.ys]
365
+
366
+ @property
367
+ def kwargs(self):
368
+ return dict(x=self.xs, y=self.ys)
369
+
370
+ @property
371
+ def xy(self):
372
+ return self.xs, self.ys
engeom/_plot/pyvista.py CHANGED
@@ -40,6 +40,25 @@ else:
40
40
  """
41
41
  self.plotter = plotter
42
42
 
43
+ def add_points(self, *points, color: pyvista.ColorLike = "b", point_size: float = 5.0,
44
+ render_points_as_spheres: bool = True, **kwargs) -> pyvista.vtkActor:
45
+ """
46
+ Add one or more points to be plotted.
47
+ :param points: The points to add.
48
+ :param color: The color to use for the point(s).
49
+ :param point_size: The size of the point(s).
50
+ :param render_points_as_spheres: Whether to render the points as spheres or not.
51
+ :param kwargs: Additional keyword arguments to pass to the PyVista `Plotter.add_points` method.
52
+ :return: The PyVista actor that was added to the plotter.
53
+ """
54
+ return self.plotter.add_points(
55
+ numpy.array([_tuplefy(p) for p in points], dtype=numpy.float64),
56
+ color=color,
57
+ point_size=point_size,
58
+ render_points_as_spheres=render_points_as_spheres,
59
+ **kwargs
60
+ )
61
+
43
62
  def add_curves(
44
63
  self,
45
64
  *curves: Curve3,
@@ -204,12 +223,12 @@ else:
204
223
  points = numpy.array([[0, 0, 0], [size, 0, 0], [0, size, 0], [0, 0, size]], dtype=numpy.float64)
205
224
  points = iso.transform_points(points)
206
225
 
207
- self.plotter.add_lines(points[[0, 1]], color="red", width=line_width)
208
- self.plotter.add_lines(points[[0, 2]], color="green", width=line_width)
209
- self.plotter.add_lines(points[[0, 3]], color="blue", width=line_width)
226
+ actors = [self.plotter.add_lines(points[[0, 1]], color="red", width=line_width),
227
+ self.plotter.add_lines(points[[0, 2]], color="green", width=line_width),
228
+ self.plotter.add_lines(points[[0, 3]], color="blue", width=line_width)]
210
229
 
211
230
  if label:
212
- self.plotter.add_point_labels(
231
+ actors.append(self.plotter.add_point_labels(
213
232
  [points[0]],
214
233
  [label],
215
234
  show_points=False,
@@ -217,7 +236,9 @@ else:
217
236
  font_family="courier",
218
237
  font_size=label_size,
219
238
  bold=False,
220
- )
239
+ ))
240
+
241
+ return actors
221
242
 
222
243
  def label(self, point: PlotCoords, text: str, **kwargs):
223
244
  """
engeom/engeom.abi3.so CHANGED
Binary file
engeom/geom2.pyi CHANGED
@@ -236,6 +236,13 @@ class Point2(Iterable[float]):
236
236
  """
237
237
  ...
238
238
 
239
+ @staticmethod
240
+ def mid(a: Point2, b: Point2) -> Point2:
241
+ """
242
+ Return the midpoint between two points. This is the average of the x and y components of the two points.
243
+ """
244
+ ...
245
+
239
246
 
240
247
  class SurfacePoint2:
241
248
  """
@@ -377,6 +384,23 @@ class SurfacePoint2:
377
384
  """
378
385
  ...
379
386
 
387
+ def offset(self, offset: Vector2) -> SurfacePoint2:
388
+ """
389
+ Offset the surface point by a given vector. The normal vector is not affected.
390
+ :param offset: the vector to offset the surface point by.
391
+ :return: a new surface point with the position offset by the given vector.
392
+ """
393
+ ...
394
+
395
+ def shift(self, distance: float) -> SurfacePoint2:
396
+ """
397
+ Shift the surface point by a given distance along the normal vector. The position of the surface point is
398
+ affected, but the normal vector is not.
399
+ :param distance: the distance to shift the surface point.
400
+ :return: a new surface point with the position shifted by the given distance.
401
+ """
402
+ ...
403
+
380
404
 
381
405
  class Iso2:
382
406
  """
@@ -855,6 +879,14 @@ class Curve2:
855
879
  """
856
880
  ...
857
881
 
882
+ @property
883
+ def aabb(self) -> Aabb2:
884
+ """
885
+ Get the axis-aligned bounding box of the curve.
886
+ :return: the axis-aligned bounding box of the curve.
887
+ """
888
+ ...
889
+
858
890
 
859
891
  class Circle2:
860
892
  """
@@ -910,6 +942,14 @@ class Circle2:
910
942
  """
911
943
  ...
912
944
 
945
+ def point_at_angle(self, angle: float) -> Point2:
946
+ """
947
+ Get the point on the circle at a given angle.
948
+ :param angle: the angle in radians.
949
+ :return: the point on the circle at the given angle.
950
+ """
951
+ ...
952
+
913
953
 
914
954
  class Arc2:
915
955
  """
engeom/geom3.pyi CHANGED
@@ -260,6 +260,13 @@ class Point3(Iterable[float]):
260
260
  """
261
261
  ...
262
262
 
263
+ @staticmethod
264
+ def mid(a: Point3, b: Point3) -> Point3:
265
+ """
266
+ Return the midpoint between two points. This is the average of the x, y, and z coordinates of the two points.
267
+ """
268
+ ...
269
+
263
270
 
264
271
  class SurfacePoint3:
265
272
  """
@@ -389,6 +396,15 @@ class SurfacePoint3:
389
396
  """
390
397
  ...
391
398
 
399
+ def shift(self, offset: float) -> SurfacePoint3:
400
+ """
401
+ Return a new surface point with the position shifted by the specified distance along the normal vector. The
402
+ normal vector is unchanged.
403
+ :param offset: the distance to shift the position by along the normal vector.
404
+ :return:
405
+ """
406
+ ...
407
+
392
408
 
393
409
  class Iso3:
394
410
  """
@@ -521,6 +537,153 @@ class Iso3:
521
537
  """
522
538
  ...
523
539
 
540
+ def translation(self) -> Iso3:
541
+ """
542
+ Return the translation component of the isometry as a separate isometry.
543
+ """
544
+ ...
545
+
546
+ def rotation(self) -> Iso3:
547
+ """
548
+ Return the rotation component of the isometry as a separate isometry.
549
+ """
550
+ ...
551
+
552
+ @staticmethod
553
+ def from_rx(angle: float) -> Iso3:
554
+ """
555
+ Create an isometry representing a rotation around the x-axis by the specified angle in radians.
556
+ :param angle: the angle to rotate by in radians.
557
+ :return: an isometry containing only a rotation component
558
+ """
559
+ ...
560
+
561
+ @staticmethod
562
+ def from_ry(angle: float) -> Iso3:
563
+ """
564
+ Create an isometry representing a rotation around the y-axis by the specified angle in radians.
565
+ :param angle: the angle to rotate by in radians.
566
+ :return: an isometry containing only a rotation component
567
+ """
568
+ ...
569
+
570
+ @staticmethod
571
+ def from_rz(angle: float) -> Iso3:
572
+ """
573
+ Create an isometry representing a rotation around the z-axis by the specified angle in radians.
574
+ :param angle: the angle to rotate by in radians.
575
+ :return: an isometry containing only a rotation component
576
+ """
577
+ ...
578
+
579
+ @staticmethod
580
+ def from_basis_xy(e0: Vector3, e1: Vector3, origin: Point3 | None = None) -> Iso3:
581
+ """
582
+ Create an isometry from two vectors defining the X and Y axes.
583
+
584
+ This method creates an isometry where:
585
+ - The X axis aligns with e0 (normalized)
586
+ - The Y axis aligns with e1 (normalized and adjusted to be orthogonal to e0)
587
+ - The Z axis is calculated as the cross product of X and Y
588
+
589
+ :param e0: Vector defining the X axis direction
590
+ :param e1: Vector defining the approximate Y axis direction (will be orthogonalized)
591
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
592
+ :return: A new Iso3 representing the coordinate system
593
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
594
+ """
595
+ ...
596
+
597
+ @staticmethod
598
+ def from_basis_xz(e0: Vector3, e2: Vector3, origin: Point3 | None = None) -> Iso3:
599
+ """
600
+ Create an isometry from two vectors defining the X and Z axes.
601
+
602
+ This method creates an isometry where:
603
+ - The X axis aligns with e0 (normalized)
604
+ - The Z axis aligns with e2 (normalized and adjusted to be orthogonal to e0)
605
+ - The Y axis is calculated as the cross product of Z and X
606
+
607
+ :param e0: Vector defining the X axis direction
608
+ :param e2: Vector defining the approximate Z axis direction (will be orthogonalized)
609
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
610
+ :return: A new Iso3 representing the coordinate system
611
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
612
+ """
613
+ ...
614
+
615
+ @staticmethod
616
+ def from_basis_yz(e1: Vector3, e2: Vector3, origin: Point3 | None = None) -> Iso3:
617
+ """
618
+ Create an isometry from two vectors defining the Y and Z axes.
619
+
620
+ This method creates an isometry where:
621
+ - The Y axis aligns with e1 (normalized)
622
+ - The Z axis aligns with e2 (normalized and adjusted to be orthogonal to e1)
623
+ - The X axis is calculated as the cross product of Y and Z
624
+
625
+ :param e1: Vector defining the Y axis direction
626
+ :param e2: Vector defining the approximate Z axis direction (will be orthogonalized)
627
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
628
+ :return: A new Iso3 representing the coordinate system
629
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
630
+ """
631
+ ...
632
+
633
+ @staticmethod
634
+ def from_basis_yx(e1: Vector3, e0: Vector3, origin: Point3 | None = None) -> Iso3:
635
+ """
636
+ Create an isometry from two vectors defining the Y and X axes.
637
+
638
+ This method creates an isometry where:
639
+ - The Y axis aligns with e1 (normalized)
640
+ - The X axis aligns with e0 (normalized and adjusted to be orthogonal to e1)
641
+ - The Z axis is calculated as the cross product of X and Y
642
+
643
+ :param e1: Vector defining the Y axis direction
644
+ :param e0: Vector defining the approximate X axis direction (will be orthogonalized)
645
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
646
+ :return: A new Iso3 representing the coordinate system
647
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
648
+ """
649
+ ...
650
+
651
+ @staticmethod
652
+ def from_basis_zx(e2: Vector3, e0: Vector3, origin: Point3 | None = None) -> Iso3:
653
+ """
654
+ Create an isometry from two vectors defining the Z and X axes.
655
+
656
+ This method creates an isometry where:
657
+ - The Z axis aligns with e2 (normalized)
658
+ - The X axis aligns with e0 (normalized and adjusted to be orthogonal to e2)
659
+ - The Y axis is calculated as the cross product of Z and X
660
+
661
+ :param e2: Vector defining the Z axis direction
662
+ :param e0: Vector defining the approximate X axis direction (will be orthogonalized)
663
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
664
+ :return: A new Iso3 representing the coordinate system
665
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
666
+ """
667
+ ...
668
+
669
+ @staticmethod
670
+ def from_basis_zy(e2: Vector3, e1: Vector3, origin: Point3 | None = None) -> Iso3:
671
+ """
672
+ Create an isometry from two vectors defining the Z and Y axes.
673
+
674
+ This method creates an isometry where:
675
+ - The Z axis aligns with e2 (normalized)
676
+ - The Y axis aligns with e1 (normalized and adjusted to be orthogonal to e2)
677
+ - The X axis is calculated as the cross product of Y and Z
678
+
679
+ :param e2: Vector defining the Z axis direction
680
+ :param e1: Vector defining the approximate Y axis direction (will be orthogonalized)
681
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
682
+ :return: A new Iso3 representing the coordinate system
683
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
684
+ """
685
+ ...
686
+
524
687
 
525
688
  class SvdBasis3:
526
689
  """
@@ -646,6 +809,14 @@ class Plane3:
646
809
  """
647
810
  ...
648
811
 
812
+ def intersection_distance(self, sp: SurfacePoint3) -> float | None:
813
+ """
814
+
815
+ :param sp:
816
+ :return:
817
+ """
818
+ ...
819
+
649
820
 
650
821
  class Mesh:
651
822
  """
@@ -745,6 +916,25 @@ class Mesh:
745
916
  """
746
917
  ...
747
918
 
919
+ @property
920
+ def face_normals(self) -> NDArray[float]:
921
+ """
922
+ Will return an immutable view of the face normals of the mesh as a numpy array of shape (m, 3), where m is the
923
+ number of triangles in the mesh.
924
+ :return: a numpy array of shape (m, 3) containing the normals of the triangles of the mesh.
925
+ """
926
+ ...
927
+
928
+ @property
929
+ def vertex_normals(self) -> NDArray[float]:
930
+ """
931
+ Will return an immutable view of the vertex normals of the mesh as a numpy array of shape (n, 3), where n is the
932
+ number of vertices in the mesh. If a vertex has no faces, the normal will be (0, 0, 0), otherwise the normal
933
+ will have been averaged from the normals of the faces that share the vertex.
934
+ :return: a numpy array of shape (n, 3) containing the normals of the vertices of the mesh.
935
+ """
936
+ ...
937
+
748
938
  @property
749
939
  def faces(self) -> NDArray[numpy.uint32]:
750
940
  """
@@ -933,6 +1123,66 @@ class Mesh:
933
1123
  """
934
1124
  ...
935
1125
 
1126
+ def visual_outline(
1127
+ self,
1128
+ facing: Vector3,
1129
+ max_edge_length: float,
1130
+ corner_angle: float | None = None
1131
+ ) -> Tuple[NDArray[float], NDArray[numpy.uint8]]:
1132
+ """
1133
+ Capture the edges of a visual outline of the mesh, used to draw a line diagram of the mesh in a 2D space. The
1134
+ returned results will consist of two numpy arrays. The first will be a floating point array of shape (N, 6)
1135
+ where N is the number of edges in the outline. The first three columns will be the start point of the edge, and
1136
+ the last three columns will be the end point of the edge. The second array will be a numpy array of shape (N,)
1137
+ containing a 0 or 1 for each edge at the associated index. A 0 indicates that the edge is unobstructed in the
1138
+ view direction, while a 1 indicates that the edge is obstructed by the mesh.
1139
+
1140
+ :param facing: A vector with the direction to look at the mesh
1141
+ :param max_edge_length: The maximum length of an edge to be included in the outline. Edges longer than this
1142
+ will be broken up into smaller edges.
1143
+ :param corner_angle: The minimum angle between two adjacent faces for the common edge to be considered a corner
1144
+ and included in the outline. If None, the default value is 45 degrees.
1145
+ :return: a tuple of two numpy arrays. The first array is the outline edges, and the second array is a mask
1146
+ indicating whether the edge is obstructed or not.
1147
+ """
1148
+ ...
1149
+
1150
+ def convex_hull(self) -> Mesh:
1151
+ """
1152
+ Calculate the convex hull of the mesh. The convex hull is the smallest convex shape that contains all the
1153
+ vertices of the mesh. This will return a new mesh object containing the vertices and triangles of the convex
1154
+ hull. This method will not modify the original mesh.
1155
+ :return: a new mesh object containing the convex hull of the original mesh.
1156
+ """
1157
+ ...
1158
+
1159
+ @staticmethod
1160
+ def create_box(width: float, height: float, depth: float) -> Mesh:
1161
+ """
1162
+ Creates a box with the corner at the origin and the specified width, height, and depth all positive.
1163
+
1164
+ :param width:
1165
+ :param height:
1166
+ :param depth:
1167
+ :return:
1168
+ """
1169
+ ...
1170
+
1171
+ @staticmethod
1172
+ def create_cylinder(radius: float, height: float, steps: int) -> Mesh:
1173
+ """
1174
+ Creates a cylinder with a radius and height. The cylinder will be centered at the origin and oriented along the
1175
+ Z-axis. The bottom of the cylinder will be at Z = 0 and the top will be at Z = height. The cylinder will be
1176
+ created with a number of steps around the circumference, which will determine the number of vertices used to
1177
+ create the cylinder. The number of steps should be at least 3. The first set of vertices will be at X = radius,
1178
+ Y = 0.
1179
+ :param radius:
1180
+ :param height:
1181
+ :param steps:
1182
+ :return:
1183
+ """
1184
+ ...
1185
+
936
1186
 
937
1187
  class FaceFilterHandle:
938
1188
  """
@@ -1009,6 +1259,51 @@ class FaceFilterHandle:
1009
1259
  ...
1010
1260
 
1011
1261
 
1262
+ class MeshCollisionSet:
1263
+ """
1264
+ A class holding a set of meshes for collision detection. This class is used to perform collision detection between
1265
+ a set of moving and stationary meshes in 3D space.
1266
+ """
1267
+
1268
+ def __init__(self):
1269
+ """
1270
+ Creates an empty collision set.
1271
+ """
1272
+ ...
1273
+
1274
+ def add_stationary(self, mesh: Mesh) -> int:
1275
+ """
1276
+ Add a stationary mesh to the collision set. This mesh will be used as a reference for collision detection.
1277
+ :param mesh: the mesh to add to the collision set.
1278
+ :return: the ID of the mesh in the collision set.
1279
+ """
1280
+ ...
1281
+
1282
+ def add_moving(self, mesh: Mesh) -> int:
1283
+ """
1284
+ Add a moving mesh to the collision set. This mesh will be used to check for collisions against the stationary
1285
+ meshes in the set.
1286
+ :param mesh: the mesh to add to the collision set.
1287
+ :return: the ID of the mesh in the collision set.
1288
+ """
1289
+ ...
1290
+
1291
+ def add_exception(self, id1: int, id2: int):
1292
+ """
1293
+ Add an exception to the collision set. This will prevent the two meshes from being checked for collisions.
1294
+ :param id1: the ID of the first mesh.
1295
+ :param id2: the ID of the second mesh.
1296
+ """
1297
+ ...
1298
+
1299
+ def check_all(self, transforms: List[Tuple[int, Iso3]], stop_at_first: bool) -> List[Tuple[int, int]]:
1300
+ """
1301
+ Check all moving meshes against all stationary meshes for collisions. This will return a list of tuples
1302
+ containing the IDs of the two meshes that are colliding.
1303
+ :return: a list of tuples containing the IDs of the colliding meshes.
1304
+ """
1305
+ ...
1306
+
1012
1307
  class CurveStation3:
1013
1308
  """
1014
1309
  A class representing a station along a curve in 3D space. The station is represented by a point on the curve, a
engeom/plot.py CHANGED
@@ -21,6 +21,6 @@ except ImportError:
21
21
  pass
22
22
 
23
23
  try:
24
- from ._plot.matplotlib import GOM_CMAP, GomColorMap, MatplotlibAxesHelper
24
+ from ._plot.matplotlib import GOM_CMAP, GomColorMap, MatplotlibAxesHelper, TraceBuilder
25
25
  except ImportError:
26
26
  pass
@@ -0,0 +1,6 @@
1
+
2
+ from ..engeom import _sensor
3
+
4
+ # Global import of all functions
5
+ for name in [n for n in dir(_sensor) if not n.startswith("_")]:
6
+ globals()[name] = getattr(_sensor, name)
engeom/sensor.pyi ADDED
@@ -0,0 +1,58 @@
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
+ ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: engeom
3
- Version: 0.2.8
3
+ Version: 0.2.10
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -1,23 +1,25 @@
1
- engeom-0.2.8.dist-info/METADATA,sha256=JEVnOcfRIqLGQ4lLnjmICd0plsKM9yq-GCYZi1K4L1g,494
2
- engeom-0.2.8.dist-info/WHEEL,sha256=k0er-u5m64P9DpEYbKzvuotgEtd5z5FLn8Li8lnOqEs,129
3
- engeom/metrology/__init__.py,sha256=XvEhG8uDm1olWwZHDDrQv9LFP5zXhbsGx27PqRq8WE0,304
4
- engeom/plot.py,sha256=2b81-dW7aKKC1TjoDtRmppFKpzQOia7w6c4T2pExN0E,1065
5
- engeom/airfoil/__init__.py,sha256=gpS9pVepUu90XJ-ePndNupbUMKI0RGxNXPxD9x0iVHY,274
6
- engeom/_plot/common.py,sha256=Py78ufN3yi59hPwv21SoGcqyZUJS-_PmK8tlAKgSG7Q,517
7
- engeom/_plot/matplotlib.py,sha256=tTk4Fu6hDVxP1655koeT9B0JxkoURTr30ZyBV_jzTi8,11643
8
- engeom/_plot/pyvista.py,sha256=COVgiw4XlcbGjiLYE-eJjK_TJgONMGdW54pFsLczFm4,11879
9
- engeom/_plot/__init__.py,sha256=F_KviZtxzZGwfEjjn8Ep46N4UVl8VpFJWBzbBUE_J7A,30
10
- engeom/__init__.py,sha256=QN5uETqrN442w41foyrcCPV_x6NP-mrxkPJhdvdey1g,109
1
+ engeom-0.2.10.dist-info/METADATA,sha256=pspg1fX2bXgPBv5Ohzo6PabHa0gSDMki855BQddwTOo,495
2
+ engeom-0.2.10.dist-info/WHEEL,sha256=k0er-u5m64P9DpEYbKzvuotgEtd5z5FLn8Li8lnOqEs,129
11
3
  engeom/align/__init__.py,sha256=SEeMqeqLKqJC73Mg8GwPwd9NwWnl-dcCqJ4rPdh8yyc,196
12
- engeom/geom3.pyi,sha256=fcWaBcwVp76enp9aZrpnmVhIDpWxgay8eBauLR9T1Lk,56105
13
- engeom/geom3/__init__.py,sha256=l8B0iDhJ4YiRbslJLN791XWai2DWrpmZptnzIETMS9g,370
14
- engeom/raster3.pyi,sha256=sBXXYXcDBiDU_OFDQiwa7Q3GcwSiUc4CLy6nJ1MwFqM,790
15
- engeom/airfoil.pyi,sha256=VTeJBoS9Iij7p-92R7jCqzPasHmvAUocyzc6BSx7mvM,23557
16
- engeom/metrology.pyi,sha256=9I5un86VB_2gmQBrVYhX8JzILTUADMLB9Em8ttJxrWg,4044
17
- engeom/geom2.pyi,sha256=508YJVNAJcZxEIZcWi4upcGtiZKoRnGtAW7TfTU3b3A,42922
18
- engeom/engeom.pyi,sha256=BtUBtYZ_MX8Xk2x_FyzVxRXjJQIazQ1xscbCLO_Y3HA,1516
4
+ engeom/plot.py,sha256=LTqqO-h1EJL6wanM0hB79s9ohWwaCIijMOHVplY3vmc,1079
5
+ engeom/sensor.pyi,sha256=a9y62FqhG-CFFHnJiC03PqBpFtxtfkH0zoDkk9LXWnU,1399
19
6
  engeom/geom2/__init__.py,sha256=JFpiLyROUh6vyakG-7JDSlCMCn4QB2MQ8bz3uVCaAIk,373
7
+ engeom/raster3.pyi,sha256=sBXXYXcDBiDU_OFDQiwa7Q3GcwSiUc4CLy6nJ1MwFqM,790
8
+ engeom/sensor/__init__.py,sha256=p-1osXrlBX_hXSSlvySszSimMv_4_n273joBcTFx2V0,179
9
+ engeom/__init__.py,sha256=QN5uETqrN442w41foyrcCPV_x6NP-mrxkPJhdvdey1g,109
20
10
  engeom/align.pyi,sha256=QCSKrTLkCoaIubcrPU9J-wDZe1lRP0GbPgWZmonXjo0,997
11
+ engeom/geom3.pyi,sha256=VYxc9kZQhfHNN13E1DpAzea9z6R6gvpKtxyL8Wm9oWU,69140
12
+ engeom/engeom.pyi,sha256=BtUBtYZ_MX8Xk2x_FyzVxRXjJQIazQ1xscbCLO_Y3HA,1516
21
13
  engeom/raster3/__init__.py,sha256=iaayLrvco-ZMZPyeK47ox7rYne_51DNb2T2Q0iNNeKE,289
22
- engeom/engeom.abi3.so,sha256=AacYClSMsRGWHVP6i4qsugKaLlnRW4MEjIbiSKgXNWo,3169120
23
- engeom-0.2.8.dist-info/RECORD,,
14
+ engeom/geom3/__init__.py,sha256=l8B0iDhJ4YiRbslJLN791XWai2DWrpmZptnzIETMS9g,370
15
+ engeom/airfoil/__init__.py,sha256=gpS9pVepUu90XJ-ePndNupbUMKI0RGxNXPxD9x0iVHY,274
16
+ engeom/_plot/matplotlib.py,sha256=rFL1CPNMUqGO-fwD45V3-shektBMeNq5U15Zxp96hYw,14824
17
+ engeom/_plot/__init__.py,sha256=F_KviZtxzZGwfEjjn8Ep46N4UVl8VpFJWBzbBUE_J7A,30
18
+ engeom/_plot/common.py,sha256=Py78ufN3yi59hPwv21SoGcqyZUJS-_PmK8tlAKgSG7Q,517
19
+ engeom/_plot/pyvista.py,sha256=PylGVOa9RtRIYPyHLy969eyW8yIgAk-URVZT0R7WoQ8,12980
20
+ engeom/airfoil.pyi,sha256=VTeJBoS9Iij7p-92R7jCqzPasHmvAUocyzc6BSx7mvM,23557
21
+ engeom/geom2.pyi,sha256=uMi4WD6-DtFx8H-RZsKIi-p1fN4p8SzOfBZmEuvNGDU,44357
22
+ engeom/metrology/__init__.py,sha256=XvEhG8uDm1olWwZHDDrQv9LFP5zXhbsGx27PqRq8WE0,304
23
+ engeom/metrology.pyi,sha256=9I5un86VB_2gmQBrVYhX8JzILTUADMLB9Em8ttJxrWg,4044
24
+ engeom/engeom.abi3.so,sha256=m4xlDeIQKUnCbYyD6-GnL36dHsx84zTPNfFeY4BdUSo,3534872
25
+ engeom-0.2.10.dist-info/RECORD,,