cytriangle 1.0.0__cp312-cp312-macosx_13_0_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,230 @@
1
+ from cytriangle.ctriangle cimport triangulateio
2
+ from cytriangle.ctriangle cimport triangulate as ctriangulate
3
+ from cytriangle.cytriangleio cimport TriangleIO
4
+ import re
5
+
6
+ cdef class CyTriangle:
7
+ """
8
+ A class to represent the input, output, and voronoi output (optional) of a
9
+ triangulation action
10
+
11
+ Attributes
12
+ ----------
13
+ in_ : TriangleIO
14
+ input object to be triangulated
15
+ out : TriangleIO
16
+ output object of the triangulation (null initially, and if no triangulation
17
+ is run)
18
+ vorout: TriangleIO
19
+ voronoi output object of triangulation (null initially, and if no triangulation
20
+ is run, and if -v switch is not included in triangulate options)
21
+
22
+ Methods
23
+ -------
24
+ input_dict(opt=""):
25
+ Returns a dictionary representation of the triangulation input.
26
+ output_dict(opt=""):
27
+ Returns a dictionary representation of the triangulation output.
28
+ voronoi_dict(opt=""):
29
+ Returns a dictionary representation of the triangulation voronoi output.
30
+ validate_input_flags(opts=""):
31
+ Checks validity of flag options to avoid obvious incompatibilities between
32
+ flags provided.
33
+ triangulate(triflags=""):
34
+ Computes the triangulation on the input object with -Qz and user input flags.
35
+ delaunay():
36
+ Runs the triangulate method on the input object with -Qz flags.
37
+ convex_hull():
38
+ Runs the triangulate method on the input object with the -Qzc flags.
39
+ voronoi():
40
+ Runs the triangulate method on the input object with the -Qzc flags.
41
+
42
+ """
43
+ cdef TriangleIO _in
44
+ cdef TriangleIO _out
45
+ cdef TriangleIO _vorout
46
+
47
+ def __init__(self, input_dict=None):
48
+ if input_dict is not None:
49
+ self._in = TriangleIO(input_dict)
50
+ else:
51
+ self._in = TriangleIO()
52
+ self._out = TriangleIO(kind='out')
53
+ self._vorout = TriangleIO()
54
+
55
+ @property
56
+ def in_(self):
57
+ return self._in
58
+
59
+ @property
60
+ def out(self):
61
+ return self._out
62
+
63
+ @property
64
+ def vorout(self):
65
+ return self._vorout
66
+
67
+ def input_dict(self, opt=''):
68
+ return self._in.to_dict(opt)
69
+
70
+ def output_dict(self, opt=''):
71
+ return self._out.to_dict(opt)
72
+
73
+ def voronoi_dict(self, opt=''):
74
+ return self._vorout.to_dict(opt)
75
+
76
+ def validate_input_flags(self, opts):
77
+ if "r" in opts:
78
+ if not 'triangles' in self._in.to_dict():
79
+ raise ValueError("Triangle list must be provided when using 'r' flag")
80
+ if "p" in opts:
81
+ if not 'segments' in self._in.to_dict():
82
+ raise ValueError("Segment list must be provided when using 'p' flag")
83
+ if "a" in opts:
84
+ if not ('triangle_max_area' in self._in.to_dict() or 'A'
85
+ in opts or bool(re.search('a[\d.*.]+\d.*', opts))):
86
+ raise ValueError(f"""When using 'a' flag for area constraints, a global
87
+ area flag (e.g. a0.2), 'A' flag, or local triangle area
88
+ constraint list (e.g. [3.0, 1.0]) must be provided""")
89
+ if "q" in opts:
90
+ if not bool(re.search('q[\d.*.]+\d.*', opts)):
91
+ raise ValueError("When using 'q' flag for minimum angles, an angle must be provided")
92
+
93
+ # generic triangulation that accepts any switch
94
+ cpdef triangulate(self, triflags=''):
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: self.validate_input_flags(triflags)
125
+ opts = f"Qz{triflags}".encode('utf-8')
126
+ if ctriangulate(opts, self._in._io, self._out._io, self._vorout._io) is not None:
127
+ raise RuntimeError('Triangulation failed')
128
+ return self.out
129
+
130
+ cpdef delaunay(self):
131
+ """
132
+ Run the main triangulation method on the in_ object with *only* -Qz flags enabled.
133
+
134
+ - Q Quiet: suppresses all output messages from Triangle library
135
+
136
+ - z Numbers all items starting from zero (zero-indexed) rather than one.
137
+
138
+ """
139
+ opts = "Qz".encode('utf-8')
140
+ if ctriangulate(opts, self._in._io, self._out._io, self._vorout._io) is not None:
141
+ raise RuntimeError('Delaunay triangulation failed')
142
+ return self.out
143
+
144
+ cpdef convex_hull(self):
145
+ """
146
+ Run the main triangulation method on the in_ object with -Qzc flags enabled.
147
+
148
+ - Q Quiet: suppresses all output messages from Triangle library.
149
+
150
+ - z Numbers all items starting from zero (zero-indexed) rather than one.
151
+
152
+ - c Encloses the convex hull with segments
153
+
154
+ """
155
+ opts = f"Qzc".encode('utf-8')
156
+ if ctriangulate(opts, self._in._io, self._out._io, self._vorout._io) is not None:
157
+ raise RuntimeError('Delaunay triangulation and convex hull construction failed')
158
+ return self.out
159
+
160
+ cpdef voronoi(self):
161
+ """
162
+ Run the main triangulation method on the in_ object with -Qzv flags enabled.
163
+
164
+ - Q Quiet: suppresses all output messages from Triangle library.
165
+
166
+ - z Numbers all items starting from zero (zero-indexed) rather than one.
167
+
168
+ - v Generates a Voronoi diagram.
169
+
170
+ """
171
+ opts = f"Qzv".encode('utf-8')
172
+ if ctriangulate(opts, self._in._io, self._out._io, self._vorout._io) is not None:
173
+ raise RuntimeError('Delaunay triangulation and generation of voronoi diagram failed')
174
+ return self.out
175
+
176
+ def triangulate(input_dict, flags):
177
+ """
178
+ Triangulates an input dict with the following properties:
179
+
180
+ Required entries:
181
+ - vertices: A list of pairs [x, y] that are vertex coordinates.
182
+
183
+ Optional entries:
184
+ - vertex_attributes: An list of lists of vertex attributes (floats).
185
+ Each vertex must have the same number of attributes, and
186
+ len(vertex_attributes) must match the number of points.
187
+
188
+ - vertex_markers: A list of vertex markers; one int per point.
189
+
190
+ - triangles: A list of lists of triangle corners (not necessarily 3).
191
+ Corners are designated in a counterclockwise order, followed by any
192
+ other nodes if the triangle represents a nonlinear element (e.g. num_corners > 3).
193
+
194
+ - triangle_attributes: A list of triangle attributes. Each triangle must have
195
+ the same number of attributes.
196
+
197
+ - triangle_max_area: A list of triangle area constraints; one per triangle,
198
+ 0 if not set.
199
+
200
+ - segments: A list of segment endpoints, where each list contains vertex
201
+ indices.
202
+
203
+ - segment_markers: A list of segment markers; one int per segment.
204
+
205
+ - holes: A list of [x, y] hole coordinates.
206
+
207
+ - regions: A list of regional attributes and area constraints. Note that
208
+ each regional attribute is used only if you select the `A` switch, and each area
209
+ constraint is used only if you select the `a` switch (with no number following).
210
+
211
+ Returns:
212
+ - A dictionary containing the successful triangulation data.
213
+
214
+ """
215
+ # parse regions
216
+ if "regions" in input_dict:
217
+ raw_regions = input_dict["regions"]
218
+ parsed_regions = []
219
+ for region in raw_regions:
220
+ parsed_regions.append(
221
+ {
222
+ "vertex": [region[0], region[1]],
223
+ "marker": int(region[2]),
224
+ "max_area": region[3],
225
+ }
226
+ )
227
+ input_dict["regions"] = parsed_regions
228
+ triangle_obj = CyTriangle(input_dict)
229
+ triangle_obj.triangulate(flags)
230
+ return triangle_obj.out.to_dict(opt="np")