halfedge 0.8.1__py3-none-any.whl → 0.12.0__py3-none-any.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.
- halfedge/__init__.py +5 -1
- halfedge/half_edge_constructors.py +3 -5
- halfedge/half_edge_elements.py +6 -5
- halfedge/py.typed +5 -1
- halfedge/type_attrib.py +58 -59
- halfedge/validations.py +2 -2
- {halfedge-0.8.1.dist-info → halfedge-0.12.0.dist-info}/METADATA +5 -11
- halfedge-0.12.0.dist-info/RECORD +11 -0
- {halfedge-0.8.1.dist-info → halfedge-0.12.0.dist-info}/WHEEL +1 -2
- halfedge-0.8.1.dist-info/RECORD +0 -12
- halfedge-0.8.1.dist-info/top_level.txt +0 -1
halfedge/__init__.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Import functions into the package namespace.
|
|
2
|
+
|
|
3
|
+
:author: Shay Hill
|
|
4
|
+
:created: 2026-01-25
|
|
5
|
+
"""
|
|
2
6
|
|
|
3
7
|
from halfedge.half_edge_constructors import BlindHalfEdges
|
|
4
8
|
from halfedge.half_edge_elements import Edge, Face, MeshElementBase, Vert
|
|
@@ -23,7 +23,7 @@ then passing that raw data to mesh_from_vr would create a mesh with 6 faces and
|
|
|
23
23
|
from __future__ import annotations
|
|
24
24
|
|
|
25
25
|
from contextlib import suppress
|
|
26
|
-
from typing import TYPE_CHECKING, Any, TypeVar
|
|
26
|
+
from typing import TYPE_CHECKING, Any, Self, TypeVar
|
|
27
27
|
|
|
28
28
|
from paragraphs import par
|
|
29
29
|
|
|
@@ -37,8 +37,6 @@ if TYPE_CHECKING:
|
|
|
37
37
|
|
|
38
38
|
_T = TypeVar("_T")
|
|
39
39
|
|
|
40
|
-
_TBlindHalfEdges = TypeVar("_TBlindHalfEdges", bound="BlindHalfEdges")
|
|
41
|
-
|
|
42
40
|
|
|
43
41
|
class BlindHalfEdges:
|
|
44
42
|
"""Half-edge structure with no lookups."""
|
|
@@ -191,11 +189,11 @@ class BlindHalfEdges:
|
|
|
191
189
|
|
|
192
190
|
@classmethod
|
|
193
191
|
def from_vlfi(
|
|
194
|
-
cls
|
|
192
|
+
cls,
|
|
195
193
|
vl: Sequence[Vert],
|
|
196
194
|
fi: Iterable[tuple[int, ...]],
|
|
197
195
|
hi: Iterable[tuple[int, ...]] | None = None,
|
|
198
|
-
) ->
|
|
196
|
+
) -> Self:
|
|
199
197
|
"""Create a set of half edges from a vertex list and face index.
|
|
200
198
|
|
|
201
199
|
:param vl: (vertex list) a seq of vertices
|
halfedge/half_edge_elements.py
CHANGED
|
@@ -38,14 +38,15 @@ from __future__ import annotations
|
|
|
38
38
|
|
|
39
39
|
from contextlib import suppress
|
|
40
40
|
from itertools import count
|
|
41
|
-
from typing import TYPE_CHECKING, Any,
|
|
41
|
+
from typing import TYPE_CHECKING, Any, Self, TypeVar
|
|
42
42
|
|
|
43
43
|
from halfedge.type_attrib import Attrib, ContagionAttrib
|
|
44
44
|
|
|
45
45
|
if TYPE_CHECKING:
|
|
46
|
+
from collections.abc import Callable
|
|
47
|
+
|
|
46
48
|
from halfedge.half_edge_constructors import BlindHalfEdges
|
|
47
49
|
|
|
48
|
-
_TMeshElem = TypeVar("_TMeshElem", bound="MeshElementBase")
|
|
49
50
|
|
|
50
51
|
_T = TypeVar("_T")
|
|
51
52
|
|
|
@@ -141,7 +142,7 @@ class MeshElementBase:
|
|
|
141
142
|
except AttributeError:
|
|
142
143
|
return None
|
|
143
144
|
|
|
144
|
-
def merge_from(self
|
|
145
|
+
def merge_from(self, *elements: Self) -> Self:
|
|
145
146
|
"""Fill in missing references from other elements.
|
|
146
147
|
|
|
147
148
|
:param elements: elements to merge from
|
|
@@ -165,7 +166,7 @@ class MeshElementBase:
|
|
|
165
166
|
self.set_attrib(merged_attrib)
|
|
166
167
|
return self
|
|
167
168
|
|
|
168
|
-
def split_from(self
|
|
169
|
+
def split_from(self, element: Self) -> Self:
|
|
169
170
|
"""Pass attributes when dividing or altering elements.
|
|
170
171
|
|
|
171
172
|
:param element: element to split from
|
|
@@ -182,7 +183,7 @@ class MeshElementBase:
|
|
|
182
183
|
self.set_attrib(splitted)
|
|
183
184
|
return self
|
|
184
185
|
|
|
185
|
-
def __lt__(self
|
|
186
|
+
def __lt__(self, other: Self) -> bool:
|
|
186
187
|
"""Sort by sn.
|
|
187
188
|
|
|
188
189
|
You'll want to be able to sort Verts at least to make a vlvi (vertex list,
|
halfedge/py.typed
CHANGED
halfedge/type_attrib.py
CHANGED
|
@@ -61,7 +61,7 @@ When assigned to a Vert instance, these will be stored in the Vert instance's
|
|
|
61
61
|
from __future__ import annotations
|
|
62
62
|
|
|
63
63
|
from contextlib import suppress
|
|
64
|
-
from typing import TYPE_CHECKING, Any, Generic, Literal, TypeVar
|
|
64
|
+
from typing import TYPE_CHECKING, Any, Generic, Literal, Self, TypeVar
|
|
65
65
|
|
|
66
66
|
from paragraphs import par
|
|
67
67
|
|
|
@@ -79,13 +79,13 @@ class StaticAttrib(Generic[_T]):
|
|
|
79
79
|
merged or split.
|
|
80
80
|
"""
|
|
81
81
|
|
|
82
|
-
__slots__ = ("_mesh", "
|
|
82
|
+
__slots__ = ("_mesh", "cached_value")
|
|
83
83
|
|
|
84
84
|
def __new__(
|
|
85
|
-
cls
|
|
85
|
+
cls,
|
|
86
86
|
value: _T | None = None,
|
|
87
87
|
mesh: BlindHalfEdges | None = None,
|
|
88
|
-
) ->
|
|
88
|
+
) -> Self:
|
|
89
89
|
"""Raise an exception if the attribute is not subclassed."""
|
|
90
90
|
del value
|
|
91
91
|
del mesh
|
|
@@ -98,7 +98,7 @@ class StaticAttrib(Generic[_T]):
|
|
|
98
98
|
self, value: _T | None = None, mesh: BlindHalfEdges | None = None
|
|
99
99
|
) -> None:
|
|
100
100
|
"""Set value and mesh."""
|
|
101
|
-
self.
|
|
101
|
+
self.cached_value = value
|
|
102
102
|
self._mesh = mesh
|
|
103
103
|
|
|
104
104
|
def copy_to_element(
|
|
@@ -109,7 +109,7 @@ class StaticAttrib(Generic[_T]):
|
|
|
109
109
|
:param mesh: BlindHalfEdges instance to which attrib will be assigned.
|
|
110
110
|
:return: Attrib instance
|
|
111
111
|
"""
|
|
112
|
-
return type(self)(self.
|
|
112
|
+
return type(self)(self.cached_value, mesh)
|
|
113
113
|
|
|
114
114
|
@property
|
|
115
115
|
def value(self) -> _T:
|
|
@@ -118,12 +118,12 @@ class StaticAttrib(Generic[_T]):
|
|
|
118
118
|
:return: Value of the attribute
|
|
119
119
|
:raises AttributeError: If no value is set and _infer_value fails
|
|
120
120
|
"""
|
|
121
|
-
if self.
|
|
122
|
-
return self.
|
|
121
|
+
if self.cached_value is not None:
|
|
122
|
+
return self.cached_value
|
|
123
123
|
with suppress(NotImplementedError, ValueError):
|
|
124
124
|
value = self._infer_value()
|
|
125
|
-
self.
|
|
126
|
-
return self.
|
|
125
|
+
self.cached_value = value
|
|
126
|
+
return self.cached_value
|
|
127
127
|
msg = "no value set and failed to infer from 'self.mesh'"
|
|
128
128
|
raise AttributeError(msg)
|
|
129
129
|
|
|
@@ -157,16 +157,16 @@ class StaticAttrib(Generic[_T]):
|
|
|
157
157
|
implication here is that calculation *cannot* be deferred till after a
|
|
158
158
|
merge.
|
|
159
159
|
* The merged method sums areas of the merged triangles at the first and
|
|
160
|
-
subsequent mergers, so further triangle area calculations (which
|
|
161
|
-
|
|
160
|
+
subsequent mergers, so further triangle area calculations (which wouldn't
|
|
161
|
+
work on the merged shapes anyway) are not required.
|
|
162
162
|
|
|
163
163
|
If you infer a value, cache it by setting self._value.
|
|
164
164
|
|
|
165
|
-
If you do not intend to infer values, raise an exception. This exception
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
If you do not intend to infer values, raise an exception. This exception should
|
|
166
|
+
occur *before* an AttributeError is raised for a potentially missing mesh
|
|
167
|
+
attribute. It should be clear that _infer_value failed because there is no
|
|
168
|
+
provision for inferring this Attrib.value, *not* because the user failed to set
|
|
169
|
+
the Attrib property attribute.
|
|
170
170
|
"""
|
|
171
171
|
msg = par(
|
|
172
172
|
f"""'{type(self).__name__}' has no provision for inferring a value from
|
|
@@ -175,31 +175,26 @@ class StaticAttrib(Generic[_T]):
|
|
|
175
175
|
raise AttributeError(msg)
|
|
176
176
|
|
|
177
177
|
|
|
178
|
-
_TStaticAttrib = TypeVar("_TStaticAttrib", bound=StaticAttrib[Any])
|
|
179
|
-
|
|
180
|
-
|
|
181
178
|
class Attrib(Generic[_T]):
|
|
182
179
|
"""Base class for element attributes.
|
|
183
180
|
|
|
184
181
|
MeshElementBase has methods set_attrib and get_attrib that will store Attrib
|
|
185
182
|
instances in the MeshElemenBase.attrib dict. The Attrib class defines how these
|
|
186
|
-
attributes behave when mesh elements are merged and optionally allows a value
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
Do not overload `__init__` or `value`.
|
|
191
|
-
|
|
192
|
-
are marginally useful and instructive, so you will not need to overload both in
|
|
193
|
-
every case.
|
|
183
|
+
attributes behave when mesh elements are merged and optionally allows a value (e.g.,
|
|
184
|
+
edge length) to be inferred from the Attrib.element property when and if needed,
|
|
185
|
+
allowing us to cache (and potentially never access) slow attributes.
|
|
186
|
+
|
|
187
|
+
Do not overload `__init__` or `value`. Subclasses can override `merge`, `split`,
|
|
188
|
+
and `_infer_value` to customize behavior while inheriting all other functionality.
|
|
194
189
|
"""
|
|
195
190
|
|
|
196
|
-
__slots__ = ("_element", "
|
|
191
|
+
__slots__ = ("_element", "cached_value")
|
|
197
192
|
|
|
198
193
|
def __new__(
|
|
199
|
-
cls
|
|
194
|
+
cls,
|
|
200
195
|
value: _T | None = None,
|
|
201
196
|
element: MeshElementBase | None = None,
|
|
202
|
-
) ->
|
|
197
|
+
) -> Self:
|
|
203
198
|
"""Raise an exception if the attribute is not subclassed."""
|
|
204
199
|
del value
|
|
205
200
|
del element
|
|
@@ -212,7 +207,7 @@ class Attrib(Generic[_T]):
|
|
|
212
207
|
self, value: _T | None = None, element: MeshElementBase | None = None
|
|
213
208
|
) -> None:
|
|
214
209
|
"""Set value and element."""
|
|
215
|
-
self.
|
|
210
|
+
self.cached_value = value
|
|
216
211
|
self._element = element
|
|
217
212
|
|
|
218
213
|
@property
|
|
@@ -222,12 +217,12 @@ class Attrib(Generic[_T]):
|
|
|
222
217
|
:return: Value of the attribute
|
|
223
218
|
:raises AttributeError: If no value is set and _infer_value fails
|
|
224
219
|
"""
|
|
225
|
-
if self.
|
|
226
|
-
return self.
|
|
220
|
+
if self.cached_value is not None:
|
|
221
|
+
return self.cached_value
|
|
227
222
|
with suppress(NotImplementedError, ValueError):
|
|
228
223
|
value = self._infer_value()
|
|
229
|
-
self.
|
|
230
|
-
return self.
|
|
224
|
+
self.cached_value = value
|
|
225
|
+
return self.cached_value
|
|
231
226
|
msg = "no value set and failed to infer from 'self.element'"
|
|
232
227
|
raise AttributeError(msg)
|
|
233
228
|
|
|
@@ -249,7 +244,7 @@ class Attrib(Generic[_T]):
|
|
|
249
244
|
:param element: New element
|
|
250
245
|
:return: Attrib instance
|
|
251
246
|
"""
|
|
252
|
-
return type(self)(self.
|
|
247
|
+
return type(self)(self.cached_value, element)
|
|
253
248
|
|
|
254
249
|
@classmethod
|
|
255
250
|
def merge(cls, *merge_from: _TAttrib | None) -> _TAttrib | None:
|
|
@@ -268,14 +263,15 @@ class Attrib(Generic[_T]):
|
|
|
268
263
|
Attrib attributes are assumed None if not defined and are never defined
|
|
269
264
|
if their value is None.
|
|
270
265
|
|
|
271
|
-
|
|
266
|
+
Override this method in subclasses to customize merge behavior. Default
|
|
267
|
+
implementation returns None (no merge), which is desirable in some cases.
|
|
272
268
|
For example, a triangle circumcenter that will be meaningless when the
|
|
273
269
|
triangle is merged.
|
|
274
270
|
"""
|
|
275
271
|
_ = merge_from
|
|
276
272
|
return None
|
|
277
273
|
|
|
278
|
-
def split(self
|
|
274
|
+
def split(self) -> Self | None:
|
|
279
275
|
"""Define how attribute will be passed when dividing self.element.
|
|
280
276
|
|
|
281
277
|
:return: Attrib instance or None
|
|
@@ -293,7 +289,9 @@ class Attrib(Generic[_T]):
|
|
|
293
289
|
attribute is lazy (e.g., edge norm), you might want to unset _value for each
|
|
294
290
|
piece of a split edge.
|
|
295
291
|
|
|
296
|
-
|
|
292
|
+
Override this method in subclasses to customize split behavior. Default
|
|
293
|
+
implementation returns None (no split), meaning the attribute will not be
|
|
294
|
+
passed when dividing or altering elements.
|
|
297
295
|
"""
|
|
298
296
|
return None
|
|
299
297
|
|
|
@@ -320,11 +318,12 @@ class Attrib(Generic[_T]):
|
|
|
320
318
|
|
|
321
319
|
If you infer a value, cache it by setting self._value.
|
|
322
320
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
321
|
+
Override this method in subclasses to customize value inference. If you do
|
|
322
|
+
not intend to infer values, raise an exception. This exception should occur
|
|
323
|
+
*before* an AttributeError is raised for a potentially missing element
|
|
324
|
+
attribute. It should be clear that _infer_value failed because there is no
|
|
325
|
+
provision for inferring this Attrib.value, *not* because the user failed to
|
|
326
|
+
set the Attrib property attribute.
|
|
328
327
|
"""
|
|
329
328
|
msg = par(
|
|
330
329
|
f"""'{type(self).__name__}' has no provision for inferring a value from
|
|
@@ -348,10 +347,10 @@ class ContagionAttrib(Attrib[Literal[True]]):
|
|
|
348
347
|
"""
|
|
349
348
|
|
|
350
349
|
def __new__(
|
|
351
|
-
cls
|
|
350
|
+
cls,
|
|
352
351
|
value: Literal[True] | None = None,
|
|
353
352
|
element: MeshElementBase | None = None,
|
|
354
|
-
) ->
|
|
353
|
+
) -> Self:
|
|
355
354
|
"""Raise an exception if the attribute is not subclassed."""
|
|
356
355
|
del value
|
|
357
356
|
del element
|
|
@@ -381,7 +380,7 @@ class ContagionAttrib(Attrib[Literal[True]]):
|
|
|
381
380
|
return attribs[0]
|
|
382
381
|
return None
|
|
383
382
|
|
|
384
|
-
def split(self
|
|
383
|
+
def split(self) -> Self | None:
|
|
385
384
|
"""Copy attribute to splits.
|
|
386
385
|
|
|
387
386
|
:return: self
|
|
@@ -400,10 +399,10 @@ class IncompatibleAttrib(Attrib[_T]):
|
|
|
400
399
|
"""
|
|
401
400
|
|
|
402
401
|
def __new__(
|
|
403
|
-
cls
|
|
402
|
+
cls,
|
|
404
403
|
value: _T | None = None,
|
|
405
404
|
element: MeshElementBase | None = None,
|
|
406
|
-
) ->
|
|
405
|
+
) -> Self:
|
|
407
406
|
"""Raise an exception if the attribute is not subclassed."""
|
|
408
407
|
del value
|
|
409
408
|
del element
|
|
@@ -431,7 +430,7 @@ class IncompatibleAttrib(Attrib[_T]):
|
|
|
431
430
|
return None
|
|
432
431
|
return merge_from[0]
|
|
433
432
|
|
|
434
|
-
def split(self
|
|
433
|
+
def split(self) -> Self | None:
|
|
435
434
|
"""Pass the value on.
|
|
436
435
|
|
|
437
436
|
:return: self
|
|
@@ -443,10 +442,10 @@ class NumericAttrib(Attrib[_T]):
|
|
|
443
442
|
"""Average merge_from values."""
|
|
444
443
|
|
|
445
444
|
def __new__(
|
|
446
|
-
cls
|
|
445
|
+
cls,
|
|
447
446
|
value: _T | None = None,
|
|
448
447
|
element: MeshElementBase | None = None,
|
|
449
|
-
) ->
|
|
448
|
+
) -> Self:
|
|
450
449
|
"""Raise an exception if the attribute is not subclassed."""
|
|
451
450
|
del value
|
|
452
451
|
del element
|
|
@@ -473,10 +472,10 @@ class Vector2Attrib(Attrib[tuple[float, float]]):
|
|
|
473
472
|
"""Average merge_from values as xy tuples."""
|
|
474
473
|
|
|
475
474
|
def __new__(
|
|
476
|
-
cls
|
|
475
|
+
cls,
|
|
477
476
|
value: tuple[float, float] | None = None,
|
|
478
477
|
element: MeshElementBase | None = None,
|
|
479
|
-
) ->
|
|
478
|
+
) -> Self:
|
|
480
479
|
"""Raise an exception if the attribute is not subclassed."""
|
|
481
480
|
del value
|
|
482
481
|
del element
|
|
@@ -496,7 +495,7 @@ class Vector2Attrib(Attrib[tuple[float, float]]):
|
|
|
496
495
|
if not have_values:
|
|
497
496
|
return None
|
|
498
497
|
values = [x.value for x in have_values]
|
|
499
|
-
sum_x, sum_y = (sum(xs) for xs in zip(*values))
|
|
498
|
+
sum_x, sum_y = (sum(xs) for xs in zip(*values, strict=True))
|
|
500
499
|
num = len(values)
|
|
501
500
|
return type(have_values[0])((sum_x / num, sum_y / num))
|
|
502
501
|
|
|
@@ -505,10 +504,10 @@ class Vector3Attrib(Attrib[tuple[float, float, float]]):
|
|
|
505
504
|
"""Average merge_from values as xyz tuples."""
|
|
506
505
|
|
|
507
506
|
def __new__(
|
|
508
|
-
cls
|
|
507
|
+
cls,
|
|
509
508
|
value: tuple[float, float, float] | None = None,
|
|
510
509
|
element: MeshElementBase | None = None,
|
|
511
|
-
) ->
|
|
510
|
+
) -> Self:
|
|
512
511
|
"""Raise an exception if the attribute is not subclassed."""
|
|
513
512
|
del value
|
|
514
513
|
del element
|
|
@@ -528,6 +527,6 @@ class Vector3Attrib(Attrib[tuple[float, float, float]]):
|
|
|
528
527
|
if not have_values:
|
|
529
528
|
return None
|
|
530
529
|
values = [x.value for x in have_values]
|
|
531
|
-
sum_x, sum_y, sum_z = (sum(xs) for xs in zip(*values))
|
|
530
|
+
sum_x, sum_y, sum_z = (sum(xs) for xs in zip(*values, strict=True))
|
|
532
531
|
num = len(values)
|
|
533
532
|
return type(have_values[0])((sum_x / num, sum_y / num, sum_z / num))
|
halfedge/validations.py
CHANGED
|
@@ -10,12 +10,12 @@ created: 181127
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
12
|
from itertools import chain
|
|
13
|
-
from typing import TYPE_CHECKING, Any,
|
|
13
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
14
14
|
|
|
15
15
|
from halfedge.half_edge_elements import Edge, Face, ManifoldMeshError
|
|
16
16
|
|
|
17
17
|
if TYPE_CHECKING:
|
|
18
|
-
from collections.abc import Iterator
|
|
18
|
+
from collections.abc import Callable, Iterator
|
|
19
19
|
|
|
20
20
|
from halfedge.half_edge_querries import StaticHalfEdges
|
|
21
21
|
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: halfedge
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: A typical half-edge data structure with some padding
|
|
5
|
+
Author: Shay Hill
|
|
5
6
|
Author-email: Shay Hill <shay_public@hotmail.com>
|
|
6
|
-
License: MIT
|
|
7
|
-
Requires-
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Requires-Dist: paragraphs>=1.0.1
|
|
9
|
+
Requires-Python: >=3.11
|
|
8
10
|
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: paragraphs
|
|
10
|
-
Provides-Extra: dev
|
|
11
|
-
Requires-Dist: commitizen; extra == "dev"
|
|
12
|
-
Requires-Dist: coverage; extra == "dev"
|
|
13
|
-
Requires-Dist: pre-commit; extra == "dev"
|
|
14
|
-
Requires-Dist: pylint; extra == "dev"
|
|
15
|
-
Requires-Dist: pytest; extra == "dev"
|
|
16
|
-
Requires-Dist: tox; extra == "dev"
|
|
17
11
|
|
|
18
12
|
# A typical halfedges data structure with some padding
|
|
19
13
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
halfedge/__init__.py,sha256=1-q2fVFdMh3NWMh9ujuuyAnxNgPW8jIs_XpJ2oU8eFc,703
|
|
2
|
+
halfedge/half_edge_constructors.py,sha256=mozSdN3fBh1EbjKnhR1g9tqePj2LwM6GL1OrUaBocos,8584
|
|
3
|
+
halfedge/half_edge_elements.py,sha256=z5rjlZCVJJOpWUf8oVNvZXgr1x4xhz5033lmsm4UBLk,18466
|
|
4
|
+
halfedge/half_edge_object.py,sha256=A70CVmV44zDi46gbtGHj8dw4Ltshqs56MRn5-78eM20,28771
|
|
5
|
+
halfedge/half_edge_querries.py,sha256=q5xVOFdpw7t6fhs-Z8yF5j3RlG4DOrOgoLbBsAfkm4A,5179
|
|
6
|
+
halfedge/py.typed,sha256=cnjZxaS4F-N8wLWhQK9YvZ-PaN5T1TK94E9VhPT_LGg,155
|
|
7
|
+
halfedge/type_attrib.py,sha256=Giu4ck7shuq2xZoRrDjOMcOGty5v69Q49lo1kz7BJlU,20452
|
|
8
|
+
halfedge/validations.py,sha256=G3YmJnxX5Q_C3Jhbd7740oTngvsOIllfSwLa81jY3d0,4544
|
|
9
|
+
halfedge-0.12.0.dist-info/WHEEL,sha256=e_m4S054HL0hyR3CpOk-b7Q7fDX6BuFkgL5OjAExXas,80
|
|
10
|
+
halfedge-0.12.0.dist-info/METADATA,sha256=T_3wiZ5N5tYrZy3v36L0sjyEVVDmGv8jWpnA4RdsUT4,6779
|
|
11
|
+
halfedge-0.12.0.dist-info/RECORD,,
|
halfedge-0.8.1.dist-info/RECORD
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
halfedge/__init__.py,sha256=O5tfw3JIBJH83JlpwdYoTNHFsmcg959rAJd6RU51E4s,661
|
|
2
|
-
halfedge/half_edge_constructors.py,sha256=0V9xsjPgoA0zKuqUSSLJI1WKhLDJAXHzVWwH2AHZcq4,8686
|
|
3
|
-
halfedge/half_edge_elements.py,sha256=oX4ti6f6L1gcYsoP-KGNwdF4-cRpTJeBoMGMTJuIN14,18554
|
|
4
|
-
halfedge/half_edge_object.py,sha256=A70CVmV44zDi46gbtGHj8dw4Ltshqs56MRn5-78eM20,28771
|
|
5
|
-
halfedge/half_edge_querries.py,sha256=q5xVOFdpw7t6fhs-Z8yF5j3RlG4DOrOgoLbBsAfkm4A,5179
|
|
6
|
-
halfedge/py.typed,sha256=MsSFjiLMLJZ7QhUPpVBWKiyDnCzryquRyr329NoCACI,2
|
|
7
|
-
halfedge/type_attrib.py,sha256=NP8h5DmkSeq_v-wfueUumFeUKY94XqDoTQR9Lu8n094,20413
|
|
8
|
-
halfedge/validations.py,sha256=8dDUf76t1_63_e0V5tRETHJDoYUUmjnSFgsULwSSKP4,4544
|
|
9
|
-
halfedge-0.8.1.dist-info/METADATA,sha256=HITY6W4YbbBLTaGm68Iizy9tDtaMxmDyXj5gyYp4PKo,6996
|
|
10
|
-
halfedge-0.8.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
-
halfedge-0.8.1.dist-info/top_level.txt,sha256=iqphKHiIR4DfFMs14-gkFOWTXVkRWfGmDZmCYHhuoFM,9
|
|
12
|
-
halfedge-0.8.1.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
halfedge
|