-
Notifications
You must be signed in to change notification settings - Fork 31
/
VisPyTesselators.py
90 lines (68 loc) · 2.62 KB
/
VisPyTesselators.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from OpenGL import GLU
class GLUTess:
def __init__(self):
"""
OpenGL GLU triangulation class
"""
self.tris = []
self.pts = []
self.vertex_index = 0
def _on_begin_primitive(self, type):
pass
def _on_new_vertex(self, vertex):
self.tris.append(vertex)
# Force GLU to return separate triangles (GLU_TRIANGLES)
def _on_edge_flag(self, flag):
pass
def _on_combine(self, coords, data, weight):
return (coords[0], coords[1], coords[2])
def _on_error(self, errno):
print "GLUTess error:", errno
def _on_end_primitive(self):
pass
def triangulate(self, polygon):
"""
Triangulates polygon
:param polygon: shapely.geometry.polygon
Polygon to tessellate
:return: list, list
Array of triangle vertex indices [t0i0, t0i1, t0i2, t1i0, t1i1, ... ]
Array of polygon points [(x0, y0), (x1, y1), ... ]
"""
# Create tessellation object
tess = GLU.gluNewTess()
# Setup callbacks
GLU.gluTessCallback(tess, GLU.GLU_TESS_BEGIN, self._on_begin_primitive)
GLU.gluTessCallback(tess, GLU.GLU_TESS_VERTEX, self._on_new_vertex)
GLU.gluTessCallback(tess, GLU.GLU_TESS_EDGE_FLAG, self._on_edge_flag)
GLU.gluTessCallback(tess, GLU.GLU_TESS_COMBINE, self._on_combine)
GLU.gluTessCallback(tess, GLU.GLU_TESS_ERROR, self._on_error)
GLU.gluTessCallback(tess, GLU.GLU_TESS_END, self._on_end_primitive)
# Reset data
del self.tris[:]
del self.pts[:]
self.vertex_index = 0
# Define polygon
GLU.gluTessBeginPolygon(tess, None)
def define_contour(contour):
vertices = list(contour.coords) # Get vertices coordinates
if vertices[0] == vertices[-1]: # Open ring
vertices = vertices[:-1]
self.pts += vertices
GLU.gluTessBeginContour(tess) # Start contour
# Set vertices
for vertex in vertices:
point = (vertex[0], vertex[1], 0)
GLU.gluTessVertex(tess, point, self.vertex_index)
self.vertex_index += 1
GLU.gluTessEndContour(tess) # End contour
# Polygon exterior
define_contour(polygon.exterior)
# Interiors
for interior in polygon.interiors:
define_contour(interior)
# Start tessellation
GLU.gluTessEndPolygon(tess)
# Free resources
GLU.gluDeleteTess(tess)
return self.tris, self.pts