cytriangle 1.0.4__cp313-cp313-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.
Potentially problematic release.
This version of cytriangle might be problematic. Click here for more details.
- cytriangle/__init__.py +4 -0
- cytriangle/ctriangle.pxd +39 -0
- cytriangle/cytriangle.c +13653 -0
- cytriangle/cytriangle.cp313-win_amd64.pyd +0 -0
- cytriangle/cytriangle.pyx +239 -0
- cytriangle/cytriangleio.c +21095 -0
- cytriangle/cytriangleio.cp313-win_amd64.pyd +0 -0
- cytriangle/cytriangleio.pxd +4 -0
- cytriangle/cytriangleio.pyx +561 -0
- cytriangle-1.0.4.dist-info/LICENSE +165 -0
- cytriangle-1.0.4.dist-info/METADATA +40 -0
- cytriangle-1.0.4.dist-info/RECORD +20 -0
- cytriangle-1.0.4.dist-info/WHEEL +4 -0
- src/c/A.poly +62 -0
- src/c/README +198 -0
- src/c/makefile +116 -0
- src/c/showme.c +3375 -0
- src/c/triangle.c +14913 -0
- src/c/triangle.h +296 -0
- src/c/tricall.c +273 -0
|
Binary file
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
from cytriangle.ctriangle cimport triangulate as ctriangulate
|
|
2
|
+
from cytriangle.cytriangleio cimport TriangleIO
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
cdef class CyTriangle:
|
|
6
|
+
"""
|
|
7
|
+
A class to represent the input, output, and voronoi output (optional) of a
|
|
8
|
+
triangulation action
|
|
9
|
+
|
|
10
|
+
Attributes
|
|
11
|
+
----------
|
|
12
|
+
in_ : TriangleIO
|
|
13
|
+
input object to be triangulated
|
|
14
|
+
out : TriangleIO
|
|
15
|
+
output object of the triangulation (null initially, and if no triangulation
|
|
16
|
+
is run)
|
|
17
|
+
vorout: TriangleIO
|
|
18
|
+
voronoi output object of triangulation (null initially, and if no triangulation
|
|
19
|
+
is run, and if -v switch is not included in triangulate options)
|
|
20
|
+
|
|
21
|
+
Methods
|
|
22
|
+
-------
|
|
23
|
+
input_dict(opt=""):
|
|
24
|
+
Returns a dictionary representation of the triangulation input.
|
|
25
|
+
output_dict(opt=""):
|
|
26
|
+
Returns a dictionary representation of the triangulation output.
|
|
27
|
+
voronoi_dict(opt=""):
|
|
28
|
+
Returns a dictionary representation of the triangulation voronoi output.
|
|
29
|
+
validate_input_flags(opts=""):
|
|
30
|
+
Checks validity of flag options to avoid obvious incompatibilities between
|
|
31
|
+
flags provided.
|
|
32
|
+
triangulate(triflags=""):
|
|
33
|
+
Computes the triangulation on the input object with -Qz and user input flags.
|
|
34
|
+
delaunay():
|
|
35
|
+
Runs the triangulate method on the input object with -Qz flags.
|
|
36
|
+
convex_hull():
|
|
37
|
+
Runs the triangulate method on the input object with the -Qzc flags.
|
|
38
|
+
voronoi():
|
|
39
|
+
Runs the triangulate method on the input object with the -Qzc flags.
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
cdef TriangleIO _in
|
|
43
|
+
cdef TriangleIO _out
|
|
44
|
+
cdef TriangleIO _vorout
|
|
45
|
+
|
|
46
|
+
def __init__(self, input_dict=None):
|
|
47
|
+
if input_dict is not None:
|
|
48
|
+
self._in = TriangleIO(input_dict)
|
|
49
|
+
else:
|
|
50
|
+
self._in = TriangleIO()
|
|
51
|
+
self._out = TriangleIO()
|
|
52
|
+
self._vorout = TriangleIO()
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def in_(self):
|
|
56
|
+
return self._in
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def out(self):
|
|
60
|
+
return self._out
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def vorout(self):
|
|
64
|
+
return self._vorout
|
|
65
|
+
|
|
66
|
+
def input_dict(self, opt=''):
|
|
67
|
+
return self._in.to_dict(opt)
|
|
68
|
+
|
|
69
|
+
def output_dict(self, opt=''):
|
|
70
|
+
return self._out.to_dict(opt)
|
|
71
|
+
|
|
72
|
+
def voronoi_dict(self, opt=''):
|
|
73
|
+
return self._vorout.to_dict(opt)
|
|
74
|
+
|
|
75
|
+
def validate_input_flags(self, opts):
|
|
76
|
+
if "r" in opts:
|
|
77
|
+
if 'triangles' not in self._in.to_dict():
|
|
78
|
+
raise ValueError("Triangle list must be provided when using 'r' flag")
|
|
79
|
+
if "p" in opts:
|
|
80
|
+
if 'segments' not in self._in.to_dict():
|
|
81
|
+
raise ValueError("Segment list must be provided when using 'p' flag")
|
|
82
|
+
if "a" in opts:
|
|
83
|
+
if not ('triangle_max_area' in self._in.to_dict() or 'A'
|
|
84
|
+
in opts or bool(re.search(r'a[\d.*.]+\d.*', opts))):
|
|
85
|
+
raise ValueError("""When using 'a' flag for area constraints, a global
|
|
86
|
+
area flag (e.g. a0.2), 'A' flag, or local triangle area
|
|
87
|
+
constraint list (e.g. [3.0, 1.0]) must be provided""")
|
|
88
|
+
if "q" in opts:
|
|
89
|
+
if not bool(re.search(r'q[\d.*.]+\d.*', opts)):
|
|
90
|
+
raise ValueError("""When using 'q' flag for minimum angles, an angle
|
|
91
|
+
must be provided""")
|
|
92
|
+
|
|
93
|
+
# generic triangulation that accepts any switch
|
|
94
|
+
cpdef triangulate(self, triflags='', verbose=False):
|
|
95
|
+
"""
|
|
96
|
+
Runs the main triangulation method on the in_ object with any additional
|
|
97
|
+
user flags input as triflags.
|
|
98
|
+
|
|
99
|
+
The following flags are included by default:
|
|
100
|
+
|
|
101
|
+
- Q Quiet: suppresses all output messages from Triangle library
|
|
102
|
+
|
|
103
|
+
- z Numbers all items starting from zero (zero-indexed) rather than one.
|
|
104
|
+
|
|
105
|
+
Adapted from Shewchuk's documentation:
|
|
106
|
+
|
|
107
|
+
The sequence is roughly as follows. Many of these steps can be skipped,
|
|
108
|
+
depending on the command line switches.
|
|
109
|
+
|
|
110
|
+
- Read the vertices from a file and triangulate them (no -r)
|
|
111
|
+
- Insert the PSLG segments (-p), and possibly segments on the convex
|
|
112
|
+
hull (-c).
|
|
113
|
+
- Read the holes (-p), regional attributes (-pA), and regional area
|
|
114
|
+
constraints (-pa). Carve the holes and concavities, and spread the
|
|
115
|
+
regional attributes and area constraints.
|
|
116
|
+
- Enforce the constraints on minimum angle (-q) and maximum area (-a).
|
|
117
|
+
Also enforce the conforming Delaunay property (-q and -a).
|
|
118
|
+
- Compute the number of edges in the resulting mesh.
|
|
119
|
+
- Promote the mesh's linear triangles to higher order elements (-o).
|
|
120
|
+
- Write the output files.
|
|
121
|
+
- Check the consistency and Delaunay property of the mesh (-C).
|
|
122
|
+
|
|
123
|
+
"""
|
|
124
|
+
if triflags:
|
|
125
|
+
self.validate_input_flags(triflags)
|
|
126
|
+
opts = f"{'Q' if not verbose else 'V'}z{triflags}".encode('utf-8')
|
|
127
|
+
if ctriangulate(opts, self._in._io, self._out._io, self._vorout._io) \
|
|
128
|
+
is not None:
|
|
129
|
+
raise RuntimeError('Triangulation failed')
|
|
130
|
+
return self.out
|
|
131
|
+
|
|
132
|
+
cpdef delaunay(self, verbose=False):
|
|
133
|
+
"""
|
|
134
|
+
Run the main triangulation method on the in_ object with *only* -Qz
|
|
135
|
+
flags enabled.
|
|
136
|
+
|
|
137
|
+
- Q Quiet: suppresses all output messages from Triangle library
|
|
138
|
+
|
|
139
|
+
- z Numbers all items starting from zero (zero-indexed) rather than one.
|
|
140
|
+
|
|
141
|
+
"""
|
|
142
|
+
opts = f"{'Q' if not verbose else 'V'}z".encode('utf-8')
|
|
143
|
+
if ctriangulate(opts, self._in._io, self._out._io, self._vorout._io) \
|
|
144
|
+
is not None:
|
|
145
|
+
raise RuntimeError('Delaunay triangulation failed')
|
|
146
|
+
return self.out
|
|
147
|
+
|
|
148
|
+
cpdef convex_hull(self, verbose=False):
|
|
149
|
+
"""
|
|
150
|
+
Run the main triangulation method on the in_ object with -Qzc flags enabled.
|
|
151
|
+
|
|
152
|
+
- Q Quiet: suppresses all output messages from Triangle library.
|
|
153
|
+
|
|
154
|
+
- z Numbers all items starting from zero (zero-indexed) rather than one.
|
|
155
|
+
|
|
156
|
+
- c Encloses the convex hull with segments
|
|
157
|
+
|
|
158
|
+
"""
|
|
159
|
+
opts = f"{'Q' if not verbose else 'V'}zc".encode('utf-8')
|
|
160
|
+
if ctriangulate(opts, self._in._io, self._out._io, self._vorout._io) \
|
|
161
|
+
is not None:
|
|
162
|
+
raise RuntimeError("""Delaunay triangulation and convex hull
|
|
163
|
+
construction failed""")
|
|
164
|
+
return self.out
|
|
165
|
+
|
|
166
|
+
cpdef voronoi(self, verbose=False):
|
|
167
|
+
"""
|
|
168
|
+
Run the main triangulation method on the in_ object with -Qzv flags enabled.
|
|
169
|
+
|
|
170
|
+
- Q Quiet: suppresses all output messages from Triangle library.
|
|
171
|
+
|
|
172
|
+
- z Numbers all items starting from zero (zero-indexed) rather than one.
|
|
173
|
+
|
|
174
|
+
- v Generates a Voronoi diagram.
|
|
175
|
+
|
|
176
|
+
"""
|
|
177
|
+
opts = f"{'Q' if not verbose else 'V'}zv".encode('utf-8')
|
|
178
|
+
if ctriangulate(opts, self._in._io, self._out._io, self._vorout._io) \
|
|
179
|
+
is not None:
|
|
180
|
+
raise RuntimeError("""Delaunay triangulation and generation of
|
|
181
|
+
voronoi diagram failed""")
|
|
182
|
+
return self.out
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def triangulate(input_dict, flags):
|
|
186
|
+
"""
|
|
187
|
+
Triangulates an input dict with the following properties:
|
|
188
|
+
|
|
189
|
+
Required entries:
|
|
190
|
+
- vertices: A list of pairs [x, y] that are vertex coordinates.
|
|
191
|
+
|
|
192
|
+
Optional entries:
|
|
193
|
+
- vertex_attributes: An list of lists of vertex attributes (floats).
|
|
194
|
+
Each vertex must have the same number of attributes, and
|
|
195
|
+
len(vertex_attributes) must match the number of points.
|
|
196
|
+
|
|
197
|
+
- vertex_markers: A list of vertex markers; one int per point.
|
|
198
|
+
|
|
199
|
+
- triangles: A list of lists of triangle corners (not necessarily 3).
|
|
200
|
+
Corners are designated in a counterclockwise order, followed by any
|
|
201
|
+
other nodes if the triangle represents a nonlinear element (e.g. num_corners > 3).
|
|
202
|
+
|
|
203
|
+
- triangle_attributes: A list of triangle attributes. Each triangle must have
|
|
204
|
+
the same number of attributes.
|
|
205
|
+
|
|
206
|
+
- triangle_max_area: A list of triangle area constraints; one per triangle,
|
|
207
|
+
0 if not set.
|
|
208
|
+
|
|
209
|
+
- segments: A list of segment endpoints, where each list contains vertex
|
|
210
|
+
indices.
|
|
211
|
+
|
|
212
|
+
- segment_markers: A list of segment markers; one int per segment.
|
|
213
|
+
|
|
214
|
+
- holes: A list of [x, y] hole coordinates.
|
|
215
|
+
|
|
216
|
+
- regions: A list of regional attributes and area constraints. Note that
|
|
217
|
+
each regional attribute is used only if you select the `A` switch, and each area
|
|
218
|
+
constraint is used only if you select the `a` switch (with no number following).
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
- A dictionary containing the successful triangulation data.
|
|
222
|
+
|
|
223
|
+
"""
|
|
224
|
+
# parse regions
|
|
225
|
+
if "regions" in input_dict:
|
|
226
|
+
raw_regions = input_dict["regions"]
|
|
227
|
+
parsed_regions = []
|
|
228
|
+
for region in raw_regions:
|
|
229
|
+
parsed_regions.append(
|
|
230
|
+
{
|
|
231
|
+
"vertex": [region[0], region[1]],
|
|
232
|
+
"marker": int(region[2]),
|
|
233
|
+
"max_area": region[3],
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
input_dict["regions"] = parsed_regions
|
|
237
|
+
triangle_obj = CyTriangle(input_dict)
|
|
238
|
+
triangle_obj.triangulate(flags)
|
|
239
|
+
return triangle_obj.out.to_dict(opt="np")
|