engeom 0.1.1__cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.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/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ from .engeom import *
2
+
3
+
4
+ __doc__ = engeom.__doc__
5
+ if hasattr(engeom, "__all__"):
6
+ __all__ = engeom.__all__
@@ -0,0 +1,5 @@
1
+ from ..engeom import _align
2
+
3
+ # Global import of all functions from the align module
4
+ for name in [n for n in dir(_align) if not n.startswith("_")]:
5
+ globals()[name] = getattr(_align, name)
engeom/align.pyi ADDED
@@ -0,0 +1,24 @@
1
+ from __future__ import annotations
2
+ import numpy
3
+ from typing import Any, List, Tuple, Union
4
+ from .engeom import DeviationMode, Iso3, Mesh
5
+
6
+
7
+ def points_to_mesh(
8
+ points: numpy.ndarray[float],
9
+ mesh: Mesh,
10
+ initial: Iso3,
11
+ mode: DeviationMode
12
+ ) -> Iso3:
13
+ """
14
+ Perform a Levenberg-Marquardt, least squares optimization to align a set of points to a mesh. This will return the
15
+ isometry that best aligns the points to the mesh, or will throw an exception if the optimization fails.
16
+
17
+ :param points: a numpy array of shape (n, 3) containing the points to align.
18
+ :param mesh: the mesh to align the points to.
19
+ :param initial: the initial guess for the isometry. This will be used as the starting point for the optimization.
20
+ :param mode: the mode to use for the deviation calculation. This will determine how the deviation between the points
21
+ and the mesh is calculated.
22
+ :return: the isometry that best aligns the points to the mesh.
23
+ """
24
+ ...
engeom/engeom.abi3.so ADDED
Binary file
engeom/engeom.pyi ADDED
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import Any, List, Tuple, Union
5
+ from enum import Enum
6
+
7
+ import numpy
8
+
9
+
10
+ class DeviationMode(Enum):
11
+ Absolute = 0
12
+ Normal = 1
13
+
14
+
@@ -0,0 +1,5 @@
1
+ from ..engeom import _geom2
2
+
3
+ # Global import of all functions
4
+ for name in [n for n in dir(_geom2) if not n.startswith("_")]:
5
+ globals()[name] = getattr(_geom2, name)
engeom/geom2.pyi ADDED
@@ -0,0 +1,139 @@
1
+ from __future__ import annotations
2
+ import numpy
3
+
4
+
5
+ class Vector2:
6
+ def __init__(self, x: float, y: float):
7
+ """
8
+
9
+ :param x:
10
+ :param y:
11
+ """
12
+ ...
13
+
14
+ @property
15
+ def x(self) -> float:
16
+ ...
17
+
18
+ @property
19
+ def y(self) -> float:
20
+ ...
21
+
22
+ def __rmul__(self, other: float) -> Vector2:
23
+ ...
24
+
25
+ def __add__(self, other: Vector2 | Point2) -> Vector2 | Point2:
26
+ ...
27
+
28
+ def __sub__(self, other: Vector2) -> Vector2:
29
+ ...
30
+
31
+ def __neg__(self) -> Vector2:
32
+ ...
33
+
34
+ def __mul__(self, x: float) -> Vector2:
35
+ ...
36
+
37
+ def as_numpy(self) -> numpy.ndarray[float]:
38
+ """
39
+ Create a numpy array of shape (2,) from the vector.
40
+ """
41
+ ...
42
+
43
+
44
+ class Point2:
45
+ def __init__(self, x: float, y: float):
46
+ """
47
+
48
+ :param x:
49
+ :param y:
50
+ """
51
+ ...
52
+
53
+ @property
54
+ def x(self) -> float:
55
+ ...
56
+
57
+ @property
58
+ def y(self) -> float:
59
+ ...
60
+
61
+ @property
62
+ def coords(self) -> Vector2:
63
+ """
64
+ Get the coordinates of the point as a Vector2 object.
65
+ :return: a Vector2 object
66
+ """
67
+ ...
68
+
69
+ def __sub__(self, other: Vector2 | Point2) -> Vector2 | Point2:
70
+ ...
71
+
72
+ def __add__(self, other: Vector2) -> Vector2:
73
+ ...
74
+
75
+ def as_numpy(self) -> numpy.ndarray[float]:
76
+ """
77
+ Create a numpy array of shape (2,) from the point.
78
+ """
79
+ ...
80
+
81
+
82
+ class Iso2:
83
+ def __init__(self, tx: float, ty: float, r: float):
84
+ """
85
+
86
+ :param tx:
87
+ :param ty:
88
+ :param r:
89
+ """
90
+ ...
91
+
92
+ @staticmethod
93
+ def identity() -> Iso2:
94
+ """
95
+ Create the identity isometry.
96
+ """
97
+ ...
98
+
99
+ def __matmul__(self, other: Iso2 | Vector2 | Point2) -> Iso2 | Vector2 | Point2:
100
+ ...
101
+
102
+ def inverse(self) -> Iso2:
103
+ """
104
+ Get the inverse of the isometry.
105
+ """
106
+ ...
107
+
108
+ def as_numpy(self) -> numpy.ndarray[float]:
109
+ """
110
+ Create a numpy array of shape (3, 3) from the isometry.
111
+ """
112
+ ...
113
+
114
+ def transform_points(self, points: numpy.ndarray[float]) -> numpy.ndarray[float]:
115
+ """
116
+ Transform an array of points using the isometry.
117
+ :param points: a numpy array of shape (N, 2)
118
+ :return: a numpy array of shape (N, 2)
119
+ """
120
+ ...
121
+
122
+ def transform_vectors(self, vectors: numpy.ndarray[float]) -> numpy.ndarray[float]:
123
+ """
124
+ Transform an array of vectors using the isometry. The translation part of the isometry is ignored.
125
+ :param vectors:
126
+ :return:
127
+ """
128
+ ...
129
+
130
+
131
+ class SvdBasis2:
132
+
133
+ def __init__(self, points: numpy.ndarray[float], weights: numpy.ndarray[float] | None):
134
+ """
135
+
136
+ :param points:
137
+ :param weights:
138
+ """
139
+ ...
@@ -0,0 +1,5 @@
1
+ from ..engeom import _geom3
2
+
3
+ # Global import of all functions
4
+ for name in [n for n in dir(_geom3) if not n.startswith("_")]:
5
+ globals()[name] = getattr(_geom3, name)
engeom/geom3.pyi ADDED
@@ -0,0 +1,425 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import Tuple
5
+
6
+ import numpy
7
+
8
+ from engeom import DeviationMode
9
+
10
+ type Transformable3 = Vector3 | Point3 | Plane3 | Iso3
11
+
12
+
13
+ class Vector3:
14
+ def __init__(self, x: float, y: float, z: float):
15
+ """
16
+
17
+ :param x:
18
+ :param y:
19
+ :param z:
20
+ """
21
+ ...
22
+
23
+ @property
24
+ def x(self) -> float:
25
+ ...
26
+
27
+ @property
28
+ def y(self) -> float:
29
+ ...
30
+
31
+ @property
32
+ def z(self) -> float:
33
+ ...
34
+
35
+ def __rmul__(self, other: float) -> Vector3:
36
+ ...
37
+
38
+ def __add__(self, other: Vector3 | Point3) -> Vector3 | Point3:
39
+ ...
40
+
41
+ def __sub__(self, other: Vector3) -> Vector3:
42
+ ...
43
+
44
+ def __neg__(self) -> Vector3:
45
+ ...
46
+
47
+ def __mul__(self, x: float) -> Vector3:
48
+ ...
49
+
50
+ def as_numpy(self) -> numpy.ndarray[float]:
51
+ """
52
+ Create a numpy array of shape (3,) from the vector.
53
+ """
54
+ ...
55
+
56
+
57
+ class Point3:
58
+ def __init__(self, x: float, y: float, z: float):
59
+ """
60
+
61
+ :param x:
62
+ :param y:
63
+ :param z:
64
+ """
65
+ ...
66
+
67
+ @property
68
+ def x(self) -> float:
69
+ ...
70
+
71
+ @property
72
+ def y(self) -> float:
73
+ ...
74
+
75
+ @property
76
+ def z(self) -> float:
77
+ ...
78
+
79
+ @property
80
+ def coords(self) -> Vector3:
81
+ """
82
+ Get the coordinates of the point as a Vector3 object.
83
+ :return: a Vector3 object
84
+ """
85
+ ...
86
+
87
+ def __sub__(self, other: Vector3 | Point3) -> Vector3 | Point3:
88
+ ...
89
+
90
+ def __add__(self, other: Vector3) -> Vector3:
91
+ ...
92
+
93
+ def as_numpy(self) -> numpy.ndarray[float]:
94
+ """
95
+ Create a numpy array of shape (2,) from the point.
96
+ """
97
+ ...
98
+
99
+
100
+ class Iso3:
101
+ """ An isometry (rigid body transformation) in 3D space. """
102
+
103
+ def __init__(self, matrix: numpy.ndarray[float]):
104
+ """ Create an isometry from a 4x4 matrix. """
105
+ ...
106
+
107
+ @staticmethod
108
+ def identity() -> Iso3:
109
+ """ Return the identity isometry. """
110
+ ...
111
+
112
+ @staticmethod
113
+ def from_translation(x: float, y: float, z: float) -> Iso3:
114
+ """ Create an isometry representing a translation. """
115
+ ...
116
+
117
+ @staticmethod
118
+ def from_rotation(angle: float, a: float, b: float, c: float) -> Iso3:
119
+ """
120
+ Create an isometry representing a rotation around an axis. The axis will be normalized before the rotation is
121
+ applied.
122
+ :param angle: the angle to rotate by in radians.
123
+ :param a: the x component of the rotation axis.
124
+ :param b: the y component of the rotation axis.
125
+ :param c: the z component of the rotation axis.
126
+ :return: the isometry representing the rotation.
127
+ """
128
+ ...
129
+
130
+ def __matmul__(self, other: Transformable3) -> Transformable3:
131
+ """
132
+ Multiply another object by the isometry, transforming it and returning a new object of the same type.
133
+ :param other: an object of one of the transformable types
134
+ :return: a new object of the same type as the input object, transformed by the isometry.
135
+ """
136
+ ...
137
+
138
+ def inverse(self) -> Iso3:
139
+ """ Return the inverse of the isometry. """
140
+ ...
141
+
142
+ def transform_points(self, points: numpy.ndarray[float]) -> numpy.ndarray[float]:
143
+ """ Transform a set of points by the isometry. This will transform the points by the rotation and translation
144
+ of the isometry.
145
+
146
+ :param points: a numpy array of shape (n, 3) containing the points to transform.
147
+ :return: a numpy array of shape (n, 3) containing the transformed points.
148
+ """
149
+ ...
150
+
151
+ def transform_vectors(self, vector: numpy.ndarray[float]) -> numpy.ndarray[float]:
152
+ """ Transform a set of vectors by the isometry. This will only transform the direction of the vectors, not
153
+ their magnitude.
154
+
155
+ :param vector: a numpy array of shape (n, 3) containing the vectors to transform.
156
+ :return: a numpy array of shape (n, 3) containing the transformed vectors.
157
+ """
158
+ ...
159
+
160
+ def as_numpy(self) -> numpy.ndarray[float]:
161
+ """ Return a copy of the 4x4 matrix representation of the isometry. This is a copy operation. """
162
+ ...
163
+
164
+ def flip_around_x(self) -> Iso3:
165
+ """ Return a new isometry that flips the isometry 180° around the x-axis. The origin of the isometry will be
166
+ preserved, but the y and z axes will point in the opposite directions. """
167
+ ...
168
+
169
+ def flip_around_y(self) -> Iso3:
170
+ """ Return a new isometry that flips the isometry 180° around the y-axis. The origin of the isometry will be
171
+ preserved, but the x and z axes will point in the opposite directions. """
172
+ ...
173
+
174
+ def flip_around_z(self) -> Iso3:
175
+ """ Return a new isometry that flips the isometry 180° around the z-axis. The origin of the isometry will be
176
+ preserved, but the x and y axes will point in the opposite directions. """
177
+ ...
178
+
179
+
180
+ class SvdBasis3:
181
+ """
182
+ A class representing a basis in 3D space. This class is created from a set of points and will calculate the best
183
+ fitting basis for the points using a singular value decomposition.
184
+ """
185
+
186
+ def __init__(self, points: numpy.ndarray[float], weights: numpy.ndarray[float] | None):
187
+ """
188
+ Create a basis from a set of points. The basis will be calculated using a singular value decomposition of the
189
+ points.
190
+
191
+ :param points: a numpy array of shape (n, 3) containing the points to calculate the basis from.
192
+ :param weights: a numpy array of shape (n,) containing the weights of the points. If None, all points will be
193
+ weighted equally.
194
+ """
195
+ ...
196
+
197
+ def to_iso3(self) -> Iso3:
198
+ """
199
+ Produce an isometry which will transform from the world space to the basis space.
200
+
201
+ For example, if the basis is created from a set of points that lie in an arbitrary plane, transforming the
202
+ original points by this isometry will move the points such that all points lie on the XY plane.
203
+ :return: the isometry that transforms from the world space to the basis space.
204
+ """
205
+ ...
206
+
207
+ def largest(self) -> numpy.ndarray[float]:
208
+ """
209
+ Return the largest normalized basis vector.
210
+ :return: a numpy array of shape (3,) containing the largest basis vector.
211
+ """
212
+ ...
213
+
214
+ def smallest(self) -> numpy.ndarray[float]:
215
+ """
216
+ Return the smallest normalized basis vector.
217
+ :return: a numpy array of shape (3,) containing the smallest basis vector.
218
+ """
219
+ ...
220
+
221
+ def basis_variances(self) -> numpy.ndarray[float]:
222
+ """
223
+ Return the variances of the basis vectors.
224
+ :return: a numpy array of shape (3,) containing the variances of the basis vectors.
225
+ """
226
+ ...
227
+
228
+ def basis_stdevs(self) -> numpy.ndarray[float]:
229
+ """
230
+ Return the standard deviations of the basis vectors.
231
+ :return: a numpy array of shape (3,) containing the standard deviations of the basis vectors.
232
+ """
233
+ ...
234
+
235
+ def rank(self, tol: float) -> int:
236
+ """
237
+ Retrieve the rank of the decomposition by counting the number of singular values that are
238
+ greater than the provided tolerance. A rank of 0 indicates that all singular values are
239
+ less than the tolerance, and thus the point set is essentially a single point. A rank of 1
240
+ indicates that the point set is essentially a line. A rank of 2 indicates that the point
241
+ set exists roughly in a plane. The maximum rank is 3, which indicates that the point set
242
+ cannot be reduced to a lower dimension.
243
+
244
+ The singular values do not directly have a clear physical meaning. They are square roots of
245
+ the variance multiplied by the number of points used to compute the basis. Thus, they can
246
+ be interpreted in relation to each other, and when they are very small.
247
+
248
+ This method should be used either when you know roughly what a cutoff tolerance for the
249
+ problem you're working on should be, or when you know the cutoff value should be very
250
+ small. Otherwise, consider examining the standard deviations of the basis vectors
251
+ instead, as they will be easier to interpret (`basis_stdevs()`).
252
+ :param tol: the tolerance to use when determining the rank.
253
+ :return: the rank of the decomposition.
254
+ """
255
+ ...
256
+
257
+
258
+ class Plane3:
259
+ """
260
+ A class representing a plane in 3D space. The plane is represented by a unit normal vector and a distance from the
261
+ origin along the normal vector.
262
+ """
263
+
264
+ def __init__(self, a: float, b: float, c: float, d: float):
265
+ """
266
+ Create a plane from the equation ax + by + cz + d = 0.
267
+ :param a: the x value of the unit normal vector.
268
+ :param b: the y value of the unit normal vector.
269
+ :param c: the z value of the unit normal vector.
270
+ :param d: the distance from the origin along the normal vector.
271
+ """
272
+ ...
273
+
274
+ def inverted_normal(self) -> Plane3:
275
+ """
276
+ Return a new plane with the normal vector inverted.
277
+ :return: a new plane with the inverted normal vector.
278
+ """
279
+ ...
280
+
281
+ def signed_distance_to_point(self, point: Point3) -> float:
282
+ """
283
+ Calculate the signed distance from the plane to a point. The distance will be positive if the point is on the
284
+ same side of the plane as the normal vector, and negative if the point is on the opposite side.
285
+ :param point: the point to calculate the distance to.
286
+ :return: the signed distance from the plane to the point.
287
+ """
288
+ ...
289
+
290
+ def project_point(self, point: Point3) -> Point3:
291
+ """
292
+ Project a point onto the plane. The projected point will be the closest point on the plane to the input point.
293
+ :param point: the point to project.
294
+ :return: the projected point.
295
+ """
296
+ ...
297
+
298
+
299
+ class Mesh:
300
+ """
301
+ A class holding an unstructured, 3-dimensional mesh of triangles.
302
+ """
303
+
304
+ def __init__(
305
+ self,
306
+ vertices: numpy.ndarray[float],
307
+ triangles: numpy.ndarray[numpy.uint32],
308
+ ):
309
+ """
310
+ Create an engeom mesh from vertices and triangles. The vertices should be a numpy array of shape (n, 3), while
311
+ the triangles should be a numpy array of shape (m, 3) containing the indices of the vertices that make up each
312
+ triangle. The triangles should be specified in counter-clockwise order when looking at the triangle from the
313
+ front/outside.
314
+
315
+ :param vertices: a numpy array of shape (n, 3) containing the vertices of the mesh.
316
+ :param triangles: a numpy array of shape (m, 3) containing the triangles of the mesh, should be uint.
317
+ """
318
+ ...
319
+
320
+ @staticmethod
321
+ def load_stl(path: str | Path) -> Mesh:
322
+ """
323
+ Load a mesh from an STL file. This will return a new mesh object containing the vertices and triangles from the
324
+ file.
325
+
326
+ :param path: the path to the STL file to load.
327
+ :return: the mesh object containing the data from the file.
328
+ """
329
+ ...
330
+
331
+ def write_stl(self, path: str | Path):
332
+ """
333
+ Write the mesh to an STL file. This will write the vertices and triangles of the mesh to the file in binary
334
+ format.
335
+
336
+ :param path: the path to the STL file to write.
337
+ """
338
+ ...
339
+
340
+ def clone(self) -> Mesh:
341
+ """
342
+ Will return a copy of the mesh. This is a copy of the data, so modifying the returned mesh will not modify the
343
+ original mesh.
344
+
345
+ :return:
346
+ """
347
+
348
+ def transform_by(self, iso: Iso3):
349
+ """
350
+ Transforms the vertices of the mesh by an isometry. This will modify the mesh in place. Any copies made of
351
+ the vertices will no longer match the mesh after this operation.
352
+ :param iso: the isometry to transform the mesh by.
353
+ :return: None
354
+ """
355
+ ...
356
+
357
+ def append(self, other: Mesh):
358
+ """
359
+ Append another mesh to this mesh. This will add the vertices and triangles from the other mesh to this mesh,
360
+ changing this one and leaving the other one unmodified.
361
+
362
+ :param other: the mesh to append to this mesh, will not be modified in this operation
363
+ """
364
+ ...
365
+
366
+ def clone_vertices(self) -> numpy.ndarray[float]:
367
+ """
368
+ Will return a copy of the vertices of the mesh as a numpy array. If the mesh has not been modified, this will
369
+ be the same as the original vertices. This is a copy of the data, so modifying the returned array will not
370
+ modify the mesh.
371
+ :return: a numpy array of shape (n, 3) containing the vertices of the mesh.
372
+ """
373
+ ...
374
+
375
+ def clone_triangles(self) -> numpy.ndarray[numpy.uint32]:
376
+ """
377
+ Will return a copy of the triangles of the mesh as a numpy array. If the mesh has not been modified, this will
378
+ be the same as the original triangles. This is a copy of the data, so modifying the returned array will not
379
+ modify the mesh.
380
+
381
+ :return: a numpy array of shape (m, 3) containing the triangles of the mesh.
382
+ """
383
+ ...
384
+
385
+ def split(self, plane: Plane3) -> Tuple[Mesh | None, Mesh | None]:
386
+ """
387
+ Split the mesh by a plane. The plane will divide the mesh into two possible parts and return them as two new
388
+ objects. If the part lies entirely on one side of the plane, the other part will be None.
389
+
390
+ :param plane: the plane to split the mesh by.
391
+
392
+ :return: a tuple of two optional meshes, the first being that on the negative side of the plane, the second being
393
+ that on the positive side of the plane.
394
+ """
395
+ ...
396
+
397
+ def deviation(self, points: numpy.ndarray[float], mode: DeviationMode) -> numpy.ndarray[float]:
398
+ """
399
+ Calculate the deviation between a set of points and their respective closest points on the mesh surface. The
400
+ deviation can be calculated in two modes: absolute and normal. In the absolute mode, the deviation is the
401
+ linear distance between the point and the closest point on the mesh. In the normal mode, the deviation is the
402
+ distance along the normal of the closest point on the mesh. In both cases, the deviation will be positive if
403
+ the point is outside the surface and negative if the point is inside the surface.
404
+
405
+ :param points: a numpy array of shape (n, 3) containing the points to calculate the deviation for.
406
+ :param mode: the mode to calculate the deviation in.
407
+ :return: a numpy array of shape (n,) containing the deviation for each point.
408
+ """
409
+ ...
410
+
411
+ def sample_poisson(self, radius: float) -> numpy.ndarray[float]:
412
+ """
413
+ Sample the surface of the mesh using a Poisson disk sampling algorithm. This will return a numpy array of points
414
+ and their normals that are approximately evenly distributed across the surface of the mesh. The radius parameter
415
+ controls the minimum distance between points.
416
+
417
+ Internally, this algorithm will first re-sample each triangle of the mesh with a dense array of points at a
418
+ maximum distance of radius/2, before applying a random poisson disk sampling algorithm to thin the resampled
419
+ points. This means that the output points are not based on the mesh vertices, so large triangles will not be
420
+ under-represented and small triangles will not be over-represented.
421
+
422
+ :param radius: the minimum distance between points.
423
+ :return: a numpy array of shape (n, 6) containing the sampled points.
424
+ """
425
+ ...
engeom/matplotlib.py ADDED
@@ -0,0 +1,44 @@
1
+ import numpy
2
+
3
+ try:
4
+ from matplotlib.pyplot import Axes, Circle
5
+ except ImportError:
6
+ pass
7
+ else:
8
+
9
+ def set_aspect_fill(ax: Axes):
10
+ """
11
+ Set the aspect ratio of a Matplotlib Axes (subplot) object to be 1:1 in x and y, while also having it expand
12
+ to fill all available space.
13
+
14
+ In comparison to the set_aspect('equal') method, this method will also expand the plot to prevent the overall
15
+ figure from shrinking. It does this by manually re-checking the x and y limits and adjusting whichever is the
16
+ limiting value. Essentially, it will honor the larger of the two existing limits which were set before this
17
+ function was called, and will only expand the limits on the other axis to fill the remaining space.
18
+
19
+ Call this function after all visual elements have been added to the plot and any manual adjustments to the axis
20
+ limits are performed. If you use fig.tight_layout(), call this function after that.
21
+ :param ax: a Matplotlib Axes object
22
+ :return: None
23
+ """
24
+ x0, x1 = ax.get_xlim()
25
+ y0, y1 = ax.get_ylim()
26
+
27
+ bbox = ax.get_window_extent()
28
+ width, height = bbox.width, bbox.height
29
+
30
+ x_scale = width / (x1 - x0)
31
+ y_scale = height / (y1 - y0)
32
+
33
+ if y_scale > x_scale:
34
+ y_range = y_scale / x_scale * (y1 - y0)
35
+ y_mid = (y0 + y1) / 2
36
+ ax.set_ylim(y_mid - y_range / 2, y_mid + y_range / 2)
37
+ else:
38
+ x_range = x_scale / y_scale * (x1 - x0)
39
+ x_mid = (x0 + x1) / 2
40
+ ax.set_xlim(x_mid - x_range / 2, x_mid + x_range / 2)
41
+
42
+
43
+
44
+
engeom/pyvista.py ADDED
@@ -0,0 +1,26 @@
1
+ """
2
+ This module contains helper functions for working with PyVista.
3
+ """
4
+ import numpy
5
+ from .geom3 import Mesh
6
+
7
+ try:
8
+ import pyvista
9
+ except ImportError:
10
+ pass
11
+ else:
12
+
13
+ def mesh_polydata(mesh: Mesh) -> pyvista.PolyData:
14
+ """
15
+ Creates a PyVista PolyData object from a Mesh object.
16
+ :param mesh: a Mesh object
17
+ :return: a PyVista PolyData object
18
+ """
19
+
20
+ if pyvista is None:
21
+ raise ImportError("PyVista is not installed.")
22
+
23
+ vertices = mesh.clone_vertices()
24
+ faces = mesh.clone_triangles()
25
+ faces = numpy.hstack((numpy.ones((faces.shape[0], 1), dtype=faces.dtype) * 3, faces))
26
+ return pyvista.PolyData(vertices, faces)
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.4
2
+ Name: engeom
3
+ Version: 0.1.1
4
+ Classifier: Programming Language :: Rust
5
+ Classifier: Programming Language :: Python :: Implementation :: CPython
6
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
7
+ Requires-Dist: numpy
8
+ Requires-Dist: pytest ; extra == 'tests'
9
+ Provides-Extra: tests
10
+ Requires-Python: >=3.8
@@ -0,0 +1,14 @@
1
+ engeom-0.1.1.dist-info/METADATA,sha256=z8XmJMWeTVLOwcvkJvmggeYXlOUJKfEjA4NfrS8GlX0,339
2
+ engeom-0.1.1.dist-info/WHEEL,sha256=1jk6Pyj4H6zT_Hox5RAAsXMc4iG45kQzjuSbAz0vxzI,129
3
+ engeom/geom2/__init__.py,sha256=mRu8Zh6DE-EQyhxScoxszPqDjGVzGWVJEQO6RIAtS4A,174
4
+ engeom/align/__init__.py,sha256=SEeMqeqLKqJC73Mg8GwPwd9NwWnl-dcCqJ4rPdh8yyc,196
5
+ engeom/engeom.pyi,sha256=flbU5LWg6szeBLTaxa1eNvN8wBhLCf9qdFNgxOYS1ng,203
6
+ engeom/__init__.py,sha256=QN5uETqrN442w41foyrcCPV_x6NP-mrxkPJhdvdey1g,109
7
+ engeom/align.pyi,sha256=KBC0nwcyp4YMfY2hRN1gr3DqFah-unqAd_o1KYwJAqc,1022
8
+ engeom/geom2.pyi,sha256=nwZ8Isy-PdvNIIyZyNuo78Us95CXd1FaWllqnF9MKbE,2978
9
+ engeom/matplotlib.py,sha256=N3CkAtQjh9xZ1hx6_piFGRNzLRLEMh9OVvWDKx5yiL8,1676
10
+ engeom/geom3/__init__.py,sha256=DG5jt2xgS9WRNb58ZkkrcKQQO6bIG-irg-uV_BkHEj4,174
11
+ engeom/geom3.pyi,sha256=PjDbjM3d20PUbP5pmlb8OqpZ7gM0RQL_f7gEVTbr7kE,16198
12
+ engeom/pyvista.py,sha256=zJ-FFwbzxVhhhrh4rfn26iaOK95Tw0L2QZsDNK8MXzg,729
13
+ engeom/engeom.abi3.so,sha256=MaLHka2geUg99tkroeIh_prsCh0PM09WVFFMHQN_uc8,1789656
14
+ engeom-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.8.1)
3
+ Root-Is-Purelib: false
4
+ Tag: cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le