engeom 0.2.9__cp38-abi3-macosx_11_0_arm64.whl → 0.2.11__cp38-abi3-macosx_11_0_arm64.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.
@@ -210,7 +210,7 @@ else:
210
210
 
211
211
  value = distance.value * scale_value
212
212
  box_style = dict(boxstyle="round,pad=0.3", ec="black", fc="white")
213
- 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)
214
214
 
215
215
  def _line_if_needed(self, pad: float, actual: Point2, leader_end: Point2):
216
216
  half_pad = pad * 0.5
@@ -221,31 +221,78 @@ else:
221
221
  t1 = work.scalar_projection(leader_end) + half_pad
222
222
  self.arrow(actual, work.at_distance(t1), arrow="-")
223
223
 
224
- 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):
225
226
  """
226
- Annotate a Matplotlib Axes object with text only.
227
+ Annotate a Matplotlib Axes object with text only, by default in the xy data plane.
227
228
  :param text: the text to annotate
228
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
229
233
  :param kwargs: keyword arguments to pass to the annotate function
230
234
  :return: the annotation object
231
235
  """
232
- 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])
233
240
 
234
- def arrow(self, start: PlotCoords, end: PlotCoords, arrow="-|>"):
241
+ return self.ax.annotate(text, xy=xy, ha=ha, va=va, **kwargs)
242
+
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):
235
251
  """
236
- Plot an arrow on a Matplotlib Axes object.
237
- :param start: the start point of the arrow
238
- :param end: the end point of the arrow
239
- :param arrow: the style of arrow to use
240
- :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:
264
+ """
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="-"):
241
276
  """
242
- return self.ax.annotate(
243
- "",
244
- xy=_tuplefy(end),
245
- xytext=_tuplefy(start),
246
- arrowprops=dict(arrowstyle=arrow, fc="black"),
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,
247
292
  )
248
293
 
294
+ return self.ax.annotate("", xy=_tuplefy(end), xytext=_tuplefy(start), arrowprops=props)
295
+
249
296
  def _font_height(self, font_size: int) -> float:
250
297
  # Get the height of a font in data units
251
298
  fig_dpi = self.ax.figure.dpi
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
  """
@@ -445,6 +461,29 @@ class Iso3:
445
461
  """
446
462
  ...
447
463
 
464
+ @staticmethod
465
+ def from_xyzwpr(x: float, y: float, z: float, w: float, p: float, r: float) -> Iso3:
466
+ """
467
+ Create an isometry from the specified translation and rotation angles in yaw, pitch, and roll format, following
468
+ the convention typically used in robotics. The angles are specified in degrees.
469
+ :param x:
470
+ :param y:
471
+ :param z:
472
+ :param w:
473
+ :param p:
474
+ :param r:
475
+ :return:
476
+ """
477
+ ...
478
+
479
+ def to_xyzwpr(self) -> List[float]:
480
+ """
481
+ Convert the isometry to a list of translation and rotation angles in yaw, pitch, and roll format, following the
482
+ convention typically used in robotics. The angles are returned in degrees.
483
+ :return: a list of 6 floats representing the translation and rotation angles.
484
+ """
485
+ ...
486
+
448
487
  def __matmul__(self, other: Transformable3) -> Transformable3:
449
488
  """
450
489
  Multiply another object by the isometry, transforming it and returning a new object of the same type.
@@ -521,6 +560,161 @@ class Iso3:
521
560
  """
522
561
  ...
523
562
 
563
+ @property
564
+ def origin(self) -> Point3:
565
+ """
566
+ Get the origin of the isometry as a Point3 object.
567
+ :return: a Point3 object representing the origin of the isometry.
568
+ """
569
+ ...
570
+
571
+ def translation(self) -> Iso3:
572
+ """
573
+ Return the translation component of the isometry as a separate isometry.
574
+ """
575
+ ...
576
+
577
+ def rotation(self) -> Iso3:
578
+ """
579
+ Return the rotation component of the isometry as a separate isometry.
580
+ """
581
+ ...
582
+
583
+ @staticmethod
584
+ def from_rx(angle: float) -> Iso3:
585
+ """
586
+ Create an isometry representing a rotation around the x-axis by the specified angle in radians.
587
+ :param angle: the angle to rotate by in radians.
588
+ :return: an isometry containing only a rotation component
589
+ """
590
+ ...
591
+
592
+ @staticmethod
593
+ def from_ry(angle: float) -> Iso3:
594
+ """
595
+ Create an isometry representing a rotation around the y-axis by the specified angle in radians.
596
+ :param angle: the angle to rotate by in radians.
597
+ :return: an isometry containing only a rotation component
598
+ """
599
+ ...
600
+
601
+ @staticmethod
602
+ def from_rz(angle: float) -> Iso3:
603
+ """
604
+ Create an isometry representing a rotation around the z-axis by the specified angle in radians.
605
+ :param angle: the angle to rotate by in radians.
606
+ :return: an isometry containing only a rotation component
607
+ """
608
+ ...
609
+
610
+ @staticmethod
611
+ def from_basis_xy(e0: Vector3, e1: Vector3, origin: Point3 | None = None) -> Iso3:
612
+ """
613
+ Create an isometry from two vectors defining the X and Y axes.
614
+
615
+ This method creates an isometry where:
616
+ - The X axis aligns with e0 (normalized)
617
+ - The Y axis aligns with e1 (normalized and adjusted to be orthogonal to e0)
618
+ - The Z axis is calculated as the cross product of X and Y
619
+
620
+ :param e0: Vector defining the X axis direction
621
+ :param e1: Vector defining the approximate Y axis direction (will be orthogonalized)
622
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
623
+ :return: A new Iso3 representing the coordinate system
624
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
625
+ """
626
+ ...
627
+
628
+ @staticmethod
629
+ def from_basis_xz(e0: Vector3, e2: Vector3, origin: Point3 | None = None) -> Iso3:
630
+ """
631
+ Create an isometry from two vectors defining the X and Z axes.
632
+
633
+ This method creates an isometry where:
634
+ - The X axis aligns with e0 (normalized)
635
+ - The Z axis aligns with e2 (normalized and adjusted to be orthogonal to e0)
636
+ - The Y axis is calculated as the cross product of Z and X
637
+
638
+ :param e0: Vector defining the X axis direction
639
+ :param e2: Vector defining the approximate Z axis direction (will be orthogonalized)
640
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
641
+ :return: A new Iso3 representing the coordinate system
642
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
643
+ """
644
+ ...
645
+
646
+ @staticmethod
647
+ def from_basis_yz(e1: Vector3, e2: Vector3, origin: Point3 | None = None) -> Iso3:
648
+ """
649
+ Create an isometry from two vectors defining the Y and Z axes.
650
+
651
+ This method creates an isometry where:
652
+ - The Y axis aligns with e1 (normalized)
653
+ - The Z axis aligns with e2 (normalized and adjusted to be orthogonal to e1)
654
+ - The X axis is calculated as the cross product of Y and Z
655
+
656
+ :param e1: Vector defining the Y axis direction
657
+ :param e2: Vector defining the approximate Z axis direction (will be orthogonalized)
658
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
659
+ :return: A new Iso3 representing the coordinate system
660
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
661
+ """
662
+ ...
663
+
664
+ @staticmethod
665
+ def from_basis_yx(e1: Vector3, e0: Vector3, origin: Point3 | None = None) -> Iso3:
666
+ """
667
+ Create an isometry from two vectors defining the Y and X axes.
668
+
669
+ This method creates an isometry where:
670
+ - The Y axis aligns with e1 (normalized)
671
+ - The X axis aligns with e0 (normalized and adjusted to be orthogonal to e1)
672
+ - The Z axis is calculated as the cross product of X and Y
673
+
674
+ :param e1: Vector defining the Y axis direction
675
+ :param e0: Vector defining the approximate X axis direction (will be orthogonalized)
676
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
677
+ :return: A new Iso3 representing the coordinate system
678
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
679
+ """
680
+ ...
681
+
682
+ @staticmethod
683
+ def from_basis_zx(e2: Vector3, e0: Vector3, origin: Point3 | None = None) -> Iso3:
684
+ """
685
+ Create an isometry from two vectors defining the Z and X axes.
686
+
687
+ This method creates an isometry where:
688
+ - The Z axis aligns with e2 (normalized)
689
+ - The X axis aligns with e0 (normalized and adjusted to be orthogonal to e2)
690
+ - The Y axis is calculated as the cross product of Z and X
691
+
692
+ :param e2: Vector defining the Z axis direction
693
+ :param e0: Vector defining the approximate X axis direction (will be orthogonalized)
694
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
695
+ :return: A new Iso3 representing the coordinate system
696
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
697
+ """
698
+ ...
699
+
700
+ @staticmethod
701
+ def from_basis_zy(e2: Vector3, e1: Vector3, origin: Point3 | None = None) -> Iso3:
702
+ """
703
+ Create an isometry from two vectors defining the Z and Y axes.
704
+
705
+ This method creates an isometry where:
706
+ - The Z axis aligns with e2 (normalized)
707
+ - The Y axis aligns with e1 (normalized and adjusted to be orthogonal to e2)
708
+ - The X axis is calculated as the cross product of Y and Z
709
+
710
+ :param e2: Vector defining the Z axis direction
711
+ :param e1: Vector defining the approximate Y axis direction (will be orthogonalized)
712
+ :param origin: Optional point to use as the origin of the isometry (defaults to world origin)
713
+ :return: A new Iso3 representing the coordinate system
714
+ :raises: ValueError if the vectors are parallel or too small to create a valid basis
715
+ """
716
+ ...
717
+
524
718
 
525
719
  class SvdBasis3:
526
720
  """
@@ -646,6 +840,14 @@ class Plane3:
646
840
  """
647
841
  ...
648
842
 
843
+ def intersection_distance(self, sp: SurfacePoint3) -> float | None:
844
+ """
845
+
846
+ :param sp:
847
+ :return:
848
+ """
849
+ ...
850
+
649
851
 
650
852
  class Mesh:
651
853
  """
@@ -952,6 +1154,143 @@ class Mesh:
952
1154
  """
953
1155
  ...
954
1156
 
1157
+ def visual_outline(
1158
+ self,
1159
+ facing: Vector3,
1160
+ max_edge_length: float,
1161
+ corner_angle: float | None = None
1162
+ ) -> Tuple[NDArray[float], NDArray[numpy.uint8]]:
1163
+ """
1164
+ Capture the edges of a visual outline of the mesh, used to draw a line diagram of the mesh in a 2D space. The
1165
+ returned results will consist of two numpy arrays. The first will be a floating point array of shape (N, 6)
1166
+ where N is the number of edges in the outline. The first three columns will be the start point of the edge, and
1167
+ the last three columns will be the end point of the edge. The second array will be a numpy array of shape (N,)
1168
+ containing a 0 or 1 for each edge at the associated index. A 0 indicates that the edge is unobstructed in the
1169
+ view direction, while a 1 indicates that the edge is obstructed by the mesh.
1170
+
1171
+ :param facing: A vector with the direction to look at the mesh
1172
+ :param max_edge_length: The maximum length of an edge to be included in the outline. Edges longer than this
1173
+ will be broken up into smaller edges.
1174
+ :param corner_angle: The minimum angle between two adjacent faces for the common edge to be considered a corner
1175
+ and included in the outline. If None, the default value is 45 degrees.
1176
+ :return: a tuple of two numpy arrays. The first array is the outline edges, and the second array is a mask
1177
+ indicating whether the edge is obstructed or not.
1178
+ """
1179
+ ...
1180
+
1181
+ def convex_hull(self) -> Mesh:
1182
+ """
1183
+ Calculate the convex hull of the mesh. The convex hull is the smallest convex shape that contains all the
1184
+ vertices of the mesh. This will return a new mesh object containing the vertices and triangles of the convex
1185
+ hull. This method will not modify the original mesh.
1186
+ :return: a new mesh object containing the convex hull of the original mesh.
1187
+ """
1188
+ ...
1189
+
1190
+ @staticmethod
1191
+ def create_box(length: float, width: float, height: float) -> Mesh:
1192
+ """
1193
+ Creates a box with the center at the origin and the specified length, width, and height
1194
+
1195
+ :param length: the size of the box along the X-axis
1196
+ :param width: the size of the box along the Y-axis
1197
+ :param height: the size of the box along the Z-axis
1198
+ :return: a new `Mesh` object representing the box
1199
+ """
1200
+ ...
1201
+
1202
+ @staticmethod
1203
+ def create_cylinder(radius: float, height: float, steps: int) -> Mesh:
1204
+ """
1205
+ Creates a cylinder with a radius and height. The cylinder will be centered at the origin and oriented along the
1206
+ Y-axis.
1207
+
1208
+ :param radius: the radius of the cylinder
1209
+ :param height: the size of the cylinder along the Y-axis
1210
+ :param steps: the number of subdivisions to create vertices around the cylinder. The more steps the smoother the
1211
+ cylinder will be.
1212
+ :return: a new `Mesh` object representing the cylinder
1213
+ """
1214
+ ...
1215
+
1216
+ @staticmethod
1217
+ def create_sphere(radius: float, n_theta: int, n_phi: int) -> Mesh:
1218
+ """
1219
+ Creates a sphere with a radius. The sphere will be centered at the origin. The step counts `n_theta` and `n_phi`
1220
+ will determine the smoothness of the sphere in the radial (n_theta) and polar (n_phi) directions. The poles
1221
+ will be located at Y=+radius and Y=-radius, and the equator will lie in the XZ plane.
1222
+
1223
+ :param radius: the radius of the sphere
1224
+ :param n_theta: the number of subdivisions to create vertices around the sphere in the theta direction
1225
+ :param n_phi: the number of subdivisions to create vertices around the sphere in the phi direction
1226
+ :return: a new `Mesh` object representing the sphere
1227
+ """
1228
+ ...
1229
+
1230
+ @staticmethod
1231
+ def create_cone(radius: float, height: float, steps: int) -> Mesh:
1232
+ """
1233
+ Creates a cone with a radius and height. The cone will be centered at the origin and oriented so that the
1234
+ point of the cone is located at Y=height/2 and the base is located at Y=-height/2.
1235
+
1236
+ :param radius: the radius of the base of the cone
1237
+ :param height: the size of the cone along the Y-axis
1238
+ :param steps: the number of subdivisions to create vertices around the cone. The more steps the smoother the
1239
+ cone will be.
1240
+ :return: a new `Mesh` object representing the cone
1241
+ """
1242
+ ...
1243
+
1244
+ @staticmethod
1245
+ def create_capsule(p0: Point3, p1: Point3, radius: float, n_theta: int, n_phi: int) -> Mesh:
1246
+ """
1247
+ Creates a capsule shape between two points with a specified radius. The capsule will be centered between the two
1248
+ points and oriented along the line connecting them. The step counts `n_theta` and `n_phi` will determine the
1249
+ smoothness of the sphere in the radial (n_theta) and polar (n_phi) directions.
1250
+
1251
+ :param p0: the first point of the capsule
1252
+ :param p1: the second point of the capsule
1253
+ :param radius: the radius of the capsule
1254
+ :param n_theta: the number of subdivisions to create vertices around the sphere in the theta direction
1255
+ :param n_phi: the number of subdivisions to create vertices around the sphere in the phi direction
1256
+ :return: a new `Mesh` object representing the capsule
1257
+ """
1258
+ ...
1259
+
1260
+ @staticmethod
1261
+ def create_cylinder_between(p0: Point3, p1: Point3, radius: float, steps: int) -> Mesh:
1262
+ """
1263
+ Creates a cylinder between two points with a specified radius. The cylinder will be centered between the two
1264
+ points and oriented along the line connecting them.
1265
+
1266
+ :param p0: the first point of the cylinder
1267
+ :param p1: the second point of the cylinder
1268
+ :param radius: the radius of the cylinder
1269
+ :param steps: the number of subdivisions to create vertices around the cylinder. The more steps the smoother the
1270
+ cylinder will be.
1271
+ :return: a new `Mesh` object representing the cylinder
1272
+ """
1273
+ ...
1274
+
1275
+ @staticmethod
1276
+ def create_rect_beam_between(p0: Point3, p1: Point3, width: float, height: float, up: Vector3 | None = None) -> Mesh:
1277
+ """
1278
+ Create a rectangular cross-sectioned prism between two points with a specified width and height. The prism will
1279
+ be centered between the two points and oriented along the line connecting them. The up vector's projection onto
1280
+ the line connecting the two end points will determine the direction of the height of the prism. If None, the
1281
+ height will be aligned with the projection of the Z-axis.
1282
+
1283
+ If the up vector is parallel to the line connecting the two points, an error will be thrown.
1284
+
1285
+ :param p0: the first point of the prism
1286
+ :param p1: the second point of the prism
1287
+ :param width: the width of the prism
1288
+ :param height: the height of the prism
1289
+ :param up: the up vector to use for the height direction. If None, the Z-axis will be used
1290
+ :return: a new `Mesh` object representing the prism
1291
+ """
1292
+ ...
1293
+
955
1294
 
956
1295
  class FaceFilterHandle:
957
1296
  """
@@ -1028,6 +1367,52 @@ class FaceFilterHandle:
1028
1367
  ...
1029
1368
 
1030
1369
 
1370
+ class MeshCollisionSet:
1371
+ """
1372
+ A class holding a set of meshes for collision detection. This class is used to perform collision detection between
1373
+ a set of moving and stationary meshes in 3D space.
1374
+ """
1375
+
1376
+ def __init__(self):
1377
+ """
1378
+ Creates an empty collision set.
1379
+ """
1380
+ ...
1381
+
1382
+ def add_stationary(self, mesh: Mesh) -> int:
1383
+ """
1384
+ Add a stationary mesh to the collision set. This mesh will be used as a reference for collision detection.
1385
+ :param mesh: the mesh to add to the collision set.
1386
+ :return: the ID of the mesh in the collision set.
1387
+ """
1388
+ ...
1389
+
1390
+ def add_moving(self, mesh: Mesh) -> int:
1391
+ """
1392
+ Add a moving mesh to the collision set. This mesh will be used to check for collisions against the stationary
1393
+ meshes in the set.
1394
+ :param mesh: the mesh to add to the collision set.
1395
+ :return: the ID of the mesh in the collision set.
1396
+ """
1397
+ ...
1398
+
1399
+ def add_exception(self, id1: int, id2: int):
1400
+ """
1401
+ Add an exception to the collision set. This will prevent the two meshes from being checked for collisions.
1402
+ :param id1: the ID of the first mesh.
1403
+ :param id2: the ID of the second mesh.
1404
+ """
1405
+ ...
1406
+
1407
+ def check_all(self, transforms: List[Tuple[int, Iso3]], stop_at_first: bool) -> List[Tuple[int, int]]:
1408
+ """
1409
+ Check all moving meshes against all stationary meshes for collisions. This will return a list of tuples
1410
+ containing the IDs of the two meshes that are colliding.
1411
+ :return: a list of tuples containing the IDs of the colliding meshes.
1412
+ """
1413
+ ...
1414
+
1415
+
1031
1416
  class CurveStation3:
1032
1417
  """
1033
1418
  A class representing a station along a curve in 3D space. The station is represented by a point on the curve, a
@@ -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.9
3
+ Version: 0.2.11
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.9.dist-info/METADATA,sha256=cIC-cxGiEWFVrpL6LFpB6eH0mLwaXusvyhT6oth9npc,494
2
- engeom-0.2.9.dist-info/WHEEL,sha256=KOb2uEsUFKFV_GOdT9ev2YJZGn1-e8xqWy3VUx4M6FQ,102
1
+ engeom-0.2.11.dist-info/METADATA,sha256=5HzRqmB7GaZATKRSG5c-8GvZ2q1UTQezhfRYpi-6PKU,495
2
+ engeom-0.2.11.dist-info/WHEEL,sha256=KOb2uEsUFKFV_GOdT9ev2YJZGn1-e8xqWy3VUx4M6FQ,102
3
3
  engeom/raster3.pyi,sha256=sBXXYXcDBiDU_OFDQiwa7Q3GcwSiUc4CLy6nJ1MwFqM,790
4
- engeom/geom2.pyi,sha256=508YJVNAJcZxEIZcWi4upcGtiZKoRnGtAW7TfTU3b3A,42922
5
- engeom/geom3.pyi,sha256=EFVmO1VaR5EHQeGR0FZCR-XqXQA9_XUP9kky7o3kovI,57003
4
+ engeom/geom2.pyi,sha256=uMi4WD6-DtFx8H-RZsKIi-p1fN4p8SzOfBZmEuvNGDU,44357
5
+ engeom/geom3.pyi,sha256=XQKy3lEDybh-81uN7y6DNncj7w6LpR2haF7YTg8TwXg,74421
6
6
  engeom/geom3/__init__.py,sha256=l8B0iDhJ4YiRbslJLN791XWai2DWrpmZptnzIETMS9g,370
7
7
  engeom/geom2/__init__.py,sha256=JFpiLyROUh6vyakG-7JDSlCMCn4QB2MQ8bz3uVCaAIk,373
8
8
  engeom/plot.py,sha256=LTqqO-h1EJL6wanM0hB79s9ohWwaCIijMOHVplY3vmc,1079
9
9
  engeom/metrology/__init__.py,sha256=XvEhG8uDm1olWwZHDDrQv9LFP5zXhbsGx27PqRq8WE0,304
10
10
  engeom/airfoil.pyi,sha256=VTeJBoS9Iij7p-92R7jCqzPasHmvAUocyzc6BSx7mvM,23557
11
- engeom/_plot/pyvista.py,sha256=COVgiw4XlcbGjiLYE-eJjK_TJgONMGdW54pFsLczFm4,11879
12
- engeom/_plot/matplotlib.py,sha256=eqZsm-Lhq2svFSusW6_09T4UuxW9F0hBEbmMj6ZMywI,12934
11
+ engeom/_plot/pyvista.py,sha256=PylGVOa9RtRIYPyHLy969eyW8yIgAk-URVZT0R7WoQ8,12980
12
+ engeom/_plot/matplotlib.py,sha256=rFL1CPNMUqGO-fwD45V3-shektBMeNq5U15Zxp96hYw,14824
13
13
  engeom/_plot/__init__.py,sha256=F_KviZtxzZGwfEjjn8Ep46N4UVl8VpFJWBzbBUE_J7A,30
14
14
  engeom/_plot/common.py,sha256=Py78ufN3yi59hPwv21SoGcqyZUJS-_PmK8tlAKgSG7Q,517
15
15
  engeom/airfoil/__init__.py,sha256=gpS9pVepUu90XJ-ePndNupbUMKI0RGxNXPxD9x0iVHY,274
16
16
  engeom/raster3/__init__.py,sha256=iaayLrvco-ZMZPyeK47ox7rYne_51DNb2T2Q0iNNeKE,289
17
17
  engeom/__init__.py,sha256=QN5uETqrN442w41foyrcCPV_x6NP-mrxkPJhdvdey1g,109
18
18
  engeom/align/__init__.py,sha256=SEeMqeqLKqJC73Mg8GwPwd9NwWnl-dcCqJ4rPdh8yyc,196
19
+ engeom/sensor/__init__.py,sha256=p-1osXrlBX_hXSSlvySszSimMv_4_n273joBcTFx2V0,179
19
20
  engeom/engeom.pyi,sha256=BtUBtYZ_MX8Xk2x_FyzVxRXjJQIazQ1xscbCLO_Y3HA,1516
21
+ engeom/sensor.pyi,sha256=a9y62FqhG-CFFHnJiC03PqBpFtxtfkH0zoDkk9LXWnU,1399
20
22
  engeom/metrology.pyi,sha256=9I5un86VB_2gmQBrVYhX8JzILTUADMLB9Em8ttJxrWg,4044
21
23
  engeom/align.pyi,sha256=QCSKrTLkCoaIubcrPU9J-wDZe1lRP0GbPgWZmonXjo0,997
22
- engeom/engeom.abi3.so,sha256=jtwveIkwJz8P0heXQq73lTogLGA1W21P--bKA38XxVE,2751360
23
- engeom-0.2.9.dist-info/RECORD,,
24
+ engeom/engeom.abi3.so,sha256=uSudNNla1mUDVfz7eSrMqfO30TtY70oZdI2SovkuOms,3024176
25
+ engeom-0.2.11.dist-info/RECORD,,