cytriangle 1.0.4__cp313-cp313-manylinux_2_35_x86_64.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.

@@ -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")