-
Notifications
You must be signed in to change notification settings - Fork 0
/
graphics.py
151 lines (131 loc) · 4.79 KB
/
graphics.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""Generate OpenGL graphics for visualizing polyhedra."""
# Third-party imports
import moderngl
import numpy as np
from pyrr import Matrix44, matrix44
from PySide6 import QtGui, QtOpenGLWidgets
class ModernGLWidget(QtOpenGLWidgets.QOpenGLWidget):
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
fmt = QtGui.QSurfaceFormat()
fmt.setVersion(3, 3)
fmt.setProfile(QtGui.QSurfaceFormat.CoreProfile)
self.setFormat(fmt)
self.resize(512, 512)
def initializeGL(self):
pass
def resizeGL(self, width, height):
#print(self.ctx.viewport)
#self.ctx.viewport = (0, 0, width, height)
pass
def paintGL(self):
# Set up context and shaders
self.ctx = moderngl.create_context()
self.ctx.clear(0.2, 0, 0.2, 0)
self.prog = self.ctx.program(vertex_shader="""
#version 330
uniform mat4 rotation;
uniform mat4 zoom;
in vec3 color;
in vec3 in_vert;
out vec3 v_color;
void main() {
gl_Position = zoom * rotation * vec4(in_vert, 1.0);
v_color = color;
}
""",
fragment_shader="""
#version 330
in vec3 v_color;
out vec4 f_color;
void main() {
f_color = vec4(v_color, 1.0);
}"""
)
self.edges_prog = self.ctx.program(vertex_shader="""
#version 330
uniform mat4 rotation;
uniform mat4 zoom;
uniform vec3 color;
in vec3 in_vert;
out vec3 v_color;
void main() {
gl_Position = zoom * rotation * vec4(in_vert, 1.0);
v_color = color;
}
""",
fragment_shader="""
#version 330
in vec3 v_color;
out vec4 f_color;
void main() {
f_color = vec4(v_color, 1.0);
}"""
)
if self.parent.show_edges_only.isChecked():
draw_func = self.draw_edges
else:
draw_func = self.draw_polyhedron
if self.parent.show_prior_polyhedra_checkbox.isChecked():
# Draw all created polyhedra
for model in self.parent.polytope_models:
draw_func(model)
else:
# Draw last created polyhedron
try:
draw_func(self.parent.polytope_models[-1])
# For when no created polyhedron exists
except IndexError:
pass
def draw_polyhedron(self, model):
"""Draw polyhedron."""
# Create VAOs for each face
vaos = []
for idx, face in enumerate(model.polytope.faces):
positions = self.ctx.buffer(np.array([vertex.coordinates for vertex in face.vertices], dtype="f4").flatten())
color = self.ctx.buffer(np.array(np.tile(model.color[idx], len(face)).flatten(), dtype="f4"))
vao = self.ctx.vertex_array(
self.prog,
[
(positions, "3f", "in_vert"),
(color, "3f", "color")
]
)
vaos.append(vao)
# Set uniforms
x = self.parent.x_slider.value() / 20
y = self.parent.y_slider.value() / 20
z = self.parent.z_slider.value() / 20
zoom = self.parent.zoom_slider.value() / 20
self.prog["rotation"].write(Matrix44.from_eulers((x, y, z), dtype="f4"))
self.prog["zoom"].write(matrix44.create_from_scale([zoom, zoom, zoom], dtype="f4"))
# Render
self.ctx.enable(moderngl.DEPTH_TEST)
for vao in vaos:
vao.render(moderngl.TRIANGLE_FAN)
def draw_edges(self, model):
vaos = []
for face in model.polytope.faces:
positions = self.ctx.buffer(np.array([vertex.coordinates for vertex in face.vertices], dtype="f4").flatten())
vao = self.ctx.vertex_array(
self.edges_prog,
[
(positions, "3f", "in_vert"),
]
)
vaos.append(vao)
# Set uniforms
x = self.parent.x_slider.value() / 20
y = self.parent.y_slider.value() / 20
z = self.parent.z_slider.value() / 20
zoom = self.parent.zoom_slider.value() / 20
self.edges_prog["color"].value = model.color[0]
self.edges_prog["rotation"].write(Matrix44.from_eulers((x, y, z), dtype="f4"))
self.edges_prog["zoom"].write(matrix44.create_from_scale([zoom, zoom, zoom], dtype="f4"))
# Render
self.ctx.enable(moderngl.DEPTH_TEST)
for vao in vaos:
vao.render(moderngl.LINE_LOOP)
def draw_faces(self):
pass