pytetwild 0.1.dev0__cp312-cp312-win_amd64.whl → 0.1.1__cp312-cp312-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.
Binary file
pytetwild/__init__.py CHANGED
@@ -2,16 +2,15 @@
2
2
 
3
3
 
4
4
  # start delvewheel patch
5
- def _delvewheel_patch_1_5_2():
5
+ def _delvewheel_patch_1_11_2():
6
6
  import os
7
- libs_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'pytetwild.libs'))
8
- if os.path.isdir(libs_dir):
7
+ if os.path.isdir(libs_dir := os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'pytetwild.libs'))):
9
8
  os.add_dll_directory(libs_dir)
10
9
 
11
10
 
12
- _delvewheel_patch_1_5_2()
13
- del _delvewheel_patch_1_5_2
11
+ _delvewheel_patch_1_11_2()
12
+ del _delvewheel_patch_1_11_2
14
13
  # end delvewheel patch
15
14
 
16
15
  from ._version import __version__ # noqa: F401
17
- from .pytetwild import tetrahedralize, tetrahedralize_pv # noqa: F401
16
+ from .pytetwild import tetrahedralize, tetrahedralize_pv, tetrahedralize_csg # noqa: F401
pytetwild/_version.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Contains the pytetwild version."""
2
+
2
3
  from importlib import metadata
3
4
 
4
5
  __version__ = metadata.version("pytetwild")
pytetwild/py.typed ADDED
@@ -0,0 +1 @@
1
+ partial
pytetwild/pytetwild.py CHANGED
@@ -1,14 +1,33 @@
1
1
  """Wrapper for fTetWild."""
2
+
2
3
  import warnings
3
4
  import numpy as np
4
- from pytetwild import PyfTetWildWrapper
5
+ from pytetwild import PyfTetWildWrapper # type: ignore
5
6
  from typing import Tuple, TYPE_CHECKING
7
+ import numpy.typing as npt
6
8
 
7
9
  if TYPE_CHECKING:
8
10
  import pyvista as pv
9
11
 
10
12
 
11
- def tetrahedralize_pv(mesh: "pv.PolyData") -> "pv.UnstructuredGrid":
13
+ def _check_edge_length(edge_length_fac: float) -> None:
14
+ """Check edge length.
15
+
16
+ Parameters
17
+ ----------
18
+ edge_length_fac : float, default: 0.05
19
+ Tetrahedral edge length as a function of bounding box diagonal. The
20
+ default ideal edge length is bb/20 (bounding box divided by 20).
21
+
22
+
23
+ """
24
+ if edge_length_fac > 1.0 or edge_length_fac < 0.0 + 1e-16:
25
+ raise ValueError("Edge length factor must be between 1e-16 and 1.0")
26
+
27
+
28
+ def tetrahedralize_pv(
29
+ mesh: "pv.PolyData", edge_length_fac: float = 0.05, optimize: bool = True
30
+ ) -> "pv.UnstructuredGrid":
12
31
  """
13
32
  Convert a PyVista surface mesh to a PyVista unstructured grid.
14
33
 
@@ -16,19 +35,44 @@ def tetrahedralize_pv(mesh: "pv.PolyData") -> "pv.UnstructuredGrid":
16
35
  ----------
17
36
  mesh : pv.PolyData
18
37
  The input surface mesh.
38
+ edge_length_fac : float, default: 0.05
39
+ Tetrahedral edge length as a function of bounding box diagonal. The
40
+ default ideal edge length is bb/20 (bounding box divided by 20).
41
+ optimize : bool
42
+ Improve the minimum scaled Jacobean for each cell. This leads to higher
43
+ cell quality at the expense of computation time.
19
44
 
20
45
  Returns
21
46
  -------
22
47
  pv.UnstructuredGrid
23
- The converted unstructured grid.
48
+ The converted unstructured grid containing only tetrahedra.
49
+
50
+ Examples
51
+ --------
52
+ >>> import pyvista as pv
53
+ >>> import pytetwild
54
+ >>> surface_mesh = pv.Sphere()
55
+ >>> tetrahedral_mesh = pytetwild.tetrahedralize_pv(surface_mesh)
56
+ >>> tetrahedral_mesh
57
+ UnstructuredGrid (0x7ff568593d00)
58
+ N Cells: 7247
59
+ N Points: 1658
60
+ X Bounds: -4.993e-01, 4.993e-01
61
+ Y Bounds: -4.965e-01, 4.965e-01
62
+ Z Bounds: -5.000e-01, 4.999e-01
63
+ N Arrays: 0
64
+
24
65
  """
25
66
  try:
26
67
  import pyvista as pv
27
68
  except:
28
69
  raise ModuleNotFoundError(
29
- "Install PyVista to use this feature with:\n\n" "pip install pytetwild[all]"
70
+ "Install PyVista to use this feature with:\n\npip install pytetwild[all]"
30
71
  )
31
72
 
73
+ if not isinstance(mesh, pv.PolyData):
74
+ raise TypeError(f"`mesh` must be a pyvista.PolyData, got {type(mesh)}")
75
+
32
76
  if not mesh.is_all_triangles:
33
77
  warnings.warn(
34
78
  "Input mesh is not all triangles. Either call `.triangulate()`"
@@ -36,13 +80,14 @@ def tetrahedralize_pv(mesh: "pv.PolyData") -> "pv.UnstructuredGrid":
36
80
  )
37
81
  mesh = mesh.triangulate()
38
82
 
39
- vertices = np.array(mesh.points, dtype=np.float64)
40
- faces = np.array(mesh.faces.reshape((-1, 4))[:, 1:4], dtype=np.int32)
83
+ _check_edge_length(edge_length_fac)
84
+ vertices = mesh.points.astype(np.float64, copy=False)
85
+ faces = mesh.faces.reshape((-1, 4))[:, 1:4].astype(np.float32, copy=False)
41
86
 
42
87
  (
43
88
  tetrahedral_mesh_vertices,
44
89
  tetrahedral_mesh_tetrahedra,
45
- ) = PyfTetWildWrapper.tetrahedralize_mesh(vertices, faces)
90
+ ) = PyfTetWildWrapper.tetrahedralize_mesh(vertices, faces, optimize, edge_length_fac)
46
91
 
47
92
  cells = np.hstack(
48
93
  [
@@ -52,10 +97,15 @@ def tetrahedralize_pv(mesh: "pv.PolyData") -> "pv.UnstructuredGrid":
52
97
  )
53
98
  cell_types = np.full(tetrahedral_mesh_tetrahedra.shape[0], 10, dtype=np.uint8)
54
99
 
55
- return pv.UnstructuredGrid(cells, cell_types, tetrahedral_mesh_vertices)
100
+ return pv.UnstructuredGrid(cells, cell_types, tetrahedral_mesh_vertices).clean()
56
101
 
57
102
 
58
- def tetrahedralize(vertices: np.ndarray, faces: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
103
+ def tetrahedralize(
104
+ vertices: npt.NDArray[np.float64],
105
+ faces: npt.NDArray[np.int32],
106
+ optimize: bool = True,
107
+ edge_length_fac: float = 0.05,
108
+ ) -> Tuple[npt.NDArray[np.float64], npt.NDArray[np.int32]]:
59
109
  """
60
110
  Convert mesh vertices and faces to a tetrahedral mesh.
61
111
 
@@ -65,10 +115,84 @@ def tetrahedralize(vertices: np.ndarray, faces: np.ndarray) -> Tuple[np.ndarray,
65
115
  The vertices of the mesh.
66
116
  faces : np.ndarray
67
117
  The faces of the mesh.
118
+ optimize : bool
119
+ Improve the minimum scaled Jacobean for each cell. This leads to higher
120
+ cell quality at the expense of computation time.
121
+ edge_length_fac : float, default: 0.05
122
+ Tetrahedral edge length as a function of bounding box diagonal. The
123
+ default ideal edge length is bb/20 (bounding box divided by 20).
68
124
 
69
125
  Returns
70
126
  -------
71
127
  Tuple[np.ndarray, np.ndarray]
72
128
  A tuple containing the vertices and tetrahedra of the tetrahedral mesh.
73
129
  """
74
- return PyfTetWildWrapper.tetrahedralize_mesh(vertices, faces)
130
+ _check_edge_length(edge_length_fac)
131
+ if not isinstance(vertices, np.ndarray):
132
+ raise TypeError("`vertices` must be a numpy array")
133
+ if not isinstance(faces, np.ndarray):
134
+ raise TypeError("`faces` must be a numpy array")
135
+ vertices = vertices.astype(np.float64, copy=False)
136
+ faces = faces.astype(np.int32, copy=False)
137
+ return PyfTetWildWrapper.tetrahedralize_mesh(vertices, faces, optimize, edge_length_fac)
138
+
139
+
140
+ def tetrahedralize_csg(
141
+ csg_file: str,
142
+ epsilon: float = 1e-3,
143
+ edge_length_r: float = 0.05,
144
+ stop_energy: float = 10.0,
145
+ coarsen: bool = True,
146
+ num_threads: int = 0,
147
+ loglevel: int = 3,
148
+ ) -> "pv.UnstructuredGrid":
149
+ """
150
+ Generate a tetrahedral mesh based on a the CSG tree specified in the csf_file.
151
+
152
+ Parameters
153
+ ----------
154
+ csg_file : str
155
+ Path to the input json file.
156
+ epsilon : float, default 1e-3
157
+ Envelop size, specifying the maximum distance of the output surface from the input surface,
158
+ relative to the bounding box size.
159
+ edge_length_r : float, default: 0.05
160
+ Tetrahedral edge length as a function of bounding box diagonal. The
161
+ default ideal edge length is bb/20 (bounding box divided by 20).
162
+ stop_energy : float, default: 10.0
163
+ The mesh optimization stops when the conformal AMIPS energy reaches 'stop_energy'.
164
+ coarsen : bool, default: true
165
+ Coarsen the output as much as possible, while maintaining the mesh quality.
166
+ num_threads : int, default: 0
167
+ Set number of threads used (0 means all available cores).
168
+ loglevel : int, default: 6
169
+ Set log level (0 = most verbose, 6 = minimal output).
170
+
171
+ Returns
172
+ -------
173
+ pv.UnstructuredGrid
174
+ The converted unstructured grid containing only tetrahedra,
175
+ with a cell attribute 'marker' indicating which of the input surfaces the cell belongs to.
176
+ """
177
+ try:
178
+ import pyvista as pv
179
+ except:
180
+ raise ModuleNotFoundError(
181
+ "Install PyVista to use this feature with:\n\npip install pytetwild[all]"
182
+ )
183
+ (tetrahedral_mesh_vertices, tetrahedral_mesh_tetrahedra, tetrahedral_marker) = (
184
+ PyfTetWildWrapper.tetrahedralize_csg(
185
+ csg_file, epsilon, edge_length_r, stop_energy, coarsen, num_threads, loglevel
186
+ )
187
+ )
188
+ cells = np.hstack(
189
+ [
190
+ np.full((tetrahedral_mesh_tetrahedra.shape[0], 1), 4, dtype=np.int32),
191
+ tetrahedral_mesh_tetrahedra,
192
+ ]
193
+ )
194
+ cell_types = np.full(tetrahedral_mesh_tetrahedra.shape[0], 10, dtype=np.uint8)
195
+
196
+ grid = pv.UnstructuredGrid(cells, cell_types, tetrahedral_mesh_vertices).clean()
197
+ grid["marker"] = tetrahedral_marker
198
+ return grid
@@ -0,0 +1,2 @@
1
+ Version: 1.11.2
2
+ Arguments: ['C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-aufwxr3e\\cp312-win_amd64\\build\\venv\\Scripts\\delvewheel', 'repair', '-w', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-aufwxr3e\\cp312-win_amd64\\repaired_wheel', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-aufwxr3e\\cp312-win_amd64\\built_wheel\\pytetwild-0.1.1-cp312-cp312-win_amd64.whl', '--add-path', '.']
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pytetwild
3
- Version: 0.1.dev0
3
+ Version: 0.1.1
4
4
  Summary: Python wrapper of fTetWild
5
5
  Author-Email: Alex Kaszynski <akascap@gmail.com>
6
6
  Classifier: Development Status :: 3 - Alpha
@@ -10,22 +10,20 @@ Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
10
10
  Classifier: Operating System :: Microsoft :: Windows
11
11
  Classifier: Operating System :: POSIX
12
12
  Classifier: Operating System :: MacOS
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
13
  Classifier: Programming Language :: Python :: 3.10
16
14
  Classifier: Programming Language :: Python :: 3.11
17
15
  Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
18
17
  Requires-Dist: numpy
18
+ Provides-Extra: all
19
19
  Requires-Dist: pyvista; extra == "all"
20
+ Provides-Extra: dev
20
21
  Requires-Dist: pytest; extra == "dev"
21
22
  Requires-Dist: pre-commit; extra == "dev"
22
23
  Requires-Dist: pyvista; extra == "dev"
23
24
  Requires-Dist: scipy; extra == "dev"
24
25
  Requires-Dist: meshio; extra == "dev"
25
- Provides-Extra: all
26
- Provides-Extra: dev
27
26
  Description-Content-Type: text/x-rst
28
- License-File: LICENSE
29
27
 
30
28
  pytetwild
31
29
  #########
@@ -62,28 +60,72 @@ more details.
62
60
  Usage
63
61
  *****
64
62
 
65
- To tetrahedralize a surface mesh:
63
+ To tetrahedralize a surface mesh from `PyVista <https://docs.pyvista.org>`_:
64
+
65
+ .. code:: py
66
+
67
+ import pyvista as pv
68
+ import pytetwild
69
+
70
+ # Load or create a PyVista PolyData surface mesh
71
+ # Here, we'll create a simple sphere mesh as an example
72
+ surface_mesh = pv.Icosphere(nsub=2)
73
+
74
+ # Convert the surface mesh to a tetrahedral mesh. For this example let's
75
+ # use a coarse mesh
76
+ tetrahedral_mesh = pytetwild.tetrahedralize_pv(surface_mesh, edge_length_fac=1)
77
+
78
+ # Visualize the tetrahedral mesh in an "exploded" view
79
+ tetrahedral_mesh.explode(1).plot(show_edges=True)
80
+
81
+ .. image:: https://github.com/pyvista/pytetwild/raw/main/exploded-sphere.png
82
+
83
+ You can also work with raw arrays. Here's a simple cube that we turn into tetrahedra.
84
+
85
+ .. code:: py
86
+
87
+ import numpy as np
66
88
 
67
- .. code:: pycon
89
+ # Define vertices of the cube
90
+ vertices = np.array([
91
+ [0, 0, 0], # Vertex 0
92
+ [1, 0, 0], # Vertex 1
93
+ [1, 1, 0], # Vertex 2
94
+ [0, 1, 0], # Vertex 3
95
+ [0, 0, 1], # Vertex 4
96
+ [1, 0, 1], # Vertex 5
97
+ [1, 1, 1], # Vertex 6
98
+ [0, 1, 1] # Vertex 7
99
+ ])
68
100
 
69
- >>> import pytetwild
70
- >>> mesh = pytetwild.tetrahedralize("input_mesh.ply")
71
- >>> mesh.vertices
72
- array([[x1, y1, z1],
73
- [x2, y2, z2],
74
- ...], dtype=float32)
75
- >>> mesh.tetrahedra
76
- array([[i1, j1, k1, l1],
77
- [i2, j2, k2, l2],
78
- ...], dtype=int32)
101
+ # Define faces using vertex indices
102
+ # Each face is a rectangle (also accepts triangles)
103
+ faces = np.array([
104
+ [0, 1, 2, 3], # Front face
105
+ [1, 5, 6, 2], # Right face
106
+ [5, 4, 7, 6], # Back face
107
+ [4, 0, 3, 7], # Left face
108
+ [4, 5, 1, 0], # Bottom face
109
+ [3, 2, 6, 7] # Top face
110
+ ])
111
+ v_out, tetra = pytetwild.tetrahedralize(vertices, faces, optimize=False)
79
112
 
80
- You can also load a mesh, perform tetrahedralization, and export the tetrahedral mesh:
81
113
 
82
- .. code:: pycon
114
+ Usage - Options
115
+ ---------------
116
+ We've surfaced a handful of parameters to each of our interfaces
117
+ ``tetrahedralize`` and ``tetrahedralize_pv``. Here are the optional parameters.
83
118
 
84
- >>> import pytetwild
85
- >>> pytetwild.tetrahedralize("input_mesh.ply", "output_mesh.ply")
119
+ .. code::
86
120
 
121
+ Additional Parameters
122
+ ---------------------
123
+ edge_length_fac : float, default: 0.05
124
+ Tetrahedral edge length as a function of bounding box diagonal. The
125
+ default ideal edge length is bb/20 (bounding box divided by 20).
126
+ optimize : bool
127
+ Improve the minimum scaled Jacobean for each cell. This leads to higher
128
+ cell quality at the expense of computation time.
87
129
 
88
130
 
89
131
  License and Acknowledgments
@@ -0,0 +1,13 @@
1
+ pytetwild/py.typed,sha256=mDShSrm8qg9qjacQc2F-rI8ATllqP6EdgHuEYxuCXZ0,7
2
+ pytetwild/PyfTetWildWrapper.pyd,sha256=ol9Knvqr5Kf4MHq22-X3yRVJUgKYYswgHV0x8bdjqAk,5940736
3
+ pytetwild/pytetwild.py,sha256=JZNJzIsoC9fOLqb4xDJ7oREJarEYkdvCgbIgRCvp52Q,6977
4
+ pytetwild/_version.py,sha256=A4_1DWpVQi-Rp5-lH3Itz0MNxg-VoQh0v0s0Wub4PQ4,120
5
+ pytetwild/__init__.py,sha256=l0Dwm58loQqSSrYqdxUx8lRHxeEBYyxr9gBvmvo-QIA,498
6
+ pytetwild-0.1.1.dist-info/DELVEWHEEL,sha256=c7PLQUz98MRU1_k7pfUBO60FuE1AfgWCkxr52fi2ayU,421
7
+ pytetwild-0.1.1.dist-info/METADATA,sha256=4NA0MlyTgECJengiMK3QHzM89oMFU_IPMCscS8Mg4u0,4508
8
+ pytetwild-0.1.1.dist-info/RECORD,,
9
+ pytetwild-0.1.1.dist-info/WHEEL,sha256=chqeLhPBtPdrOoreR34YMcofSk3yWDQhkrsDJ2n48LU,106
10
+ pytetwild-0.1.1.dist-info/licenses/LICENSE,sha256=k0P1sbYupRWlxoESvbYq2UzoMW6MXA84LltqR-4mEo4,17096
11
+ pytetwild.libs/concrt140-63a42d2def1023b22584817146cee33d.dll,sha256=tWTNrcqIbCkALGnMNEoKRuaSbXscOIw0F5gWYZzfmDY,304128
12
+ pytetwild.libs/mpir-68915c4420c2a122a0aba56cd715bd26.dll,sha256=96pOmyi8-b4gAyXakkz7w0arxMoDHxmlAU33OZXMKAY,612352
13
+ pytetwild.libs/msvcp140-8f141b4454fa78db34bc1f28c571b4da.dll,sha256=jxQbRFT6eNs0vB8oxXG02g4AzSxD960OKC8xMDaCaq4,557648
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: scikit-build-core 0.8.2
2
+ Generator: scikit-build-core 0.11.6
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp312-cp312-win_amd64
5
5
 
@@ -1,2 +0,0 @@
1
- Version: 1.5.2
2
- Arguments: ['C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-a87uf2fd\\cp312-win_amd64\\build\\venv\\Scripts\\delvewheel', 'repair', '-w', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-a87uf2fd\\cp312-win_amd64\\repaired_wheel', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-a87uf2fd\\cp312-win_amd64\\built_wheel\\pytetwild-0.1.dev0-cp312-cp312-win_amd64.whl', '--add-path', '.']
@@ -1,13 +0,0 @@
1
- pytetwild/PyfTetWildWrapper.pyd,sha256=YPKOtIzkZ0Xb03svtxo6Sy7QqAn6hoQ8sk2NUaVcW00,4992000
2
- pytetwild/pytetwild.py,sha256=fA0lXIqIf97TONhpX2vME7_3vS_9kVh8ianOVIC44EU,2169
3
- pytetwild/_version.py,sha256=hbg9UkagWDGV6Zg23kEpex_otuUYHUzMCHXYTnFnHmE,118
4
- pytetwild/__init__.py,sha256=01OqAVF8WQmKyJjKPOTwgJCDAqYmP-KwbCF9VhN--xo,486
5
- pytetwild-0.1.dev0.dist-info/DELVEWHEEL,sha256=DIwy-gDi9myKYwjvZ8kcJOz4oKS6TGfwFn6Vk9_6g6E,423
6
- pytetwild-0.1.dev0.dist-info/entry_points.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- pytetwild-0.1.dev0.dist-info/METADATA,sha256=tAozjdbNnB40sjP1A_7R-maND-a9aNqKpNibMwI0k3c,3038
8
- pytetwild-0.1.dev0.dist-info/RECORD,,
9
- pytetwild-0.1.dev0.dist-info/WHEEL,sha256=I4fjUu5CKXtMlETsB-F4Q7DROW-oHB8rNWT-iDmQHok,105
10
- pytetwild-0.1.dev0.dist-info/licenses/LICENSE,sha256=k0P1sbYupRWlxoESvbYq2UzoMW6MXA84LltqR-4mEo4,17096
11
- pytetwild.libs/concrt140-ddbfd8b75976783430ced289c6b989c3.dll,sha256=BZPGv1uz0YBgBOgTWBBL0elt7C3clmR348_2Zlqh47Q,302080
12
- pytetwild.libs/mpir-0f58ffaa159ebf7efb9359a55c2d7f23.dll,sha256=qd6vEIL0JPtRZ39EzelGE9rApfJ6duoMgV8jT8UHGns,612352
13
- pytetwild.libs/msvcp140-3499a3a8427eec4915749ee9a8991ddd.dll,sha256=oDDcLf0uyiipN1ySmJrfTa8WH5iNteFrnhBnjrDf9Mc,573008
File without changes