Благодаря Rabbid76 и OpenGL от Atilla Toth из серии Python Youtube я создал работоспособный пример программируемого конвейера. Я еще не реализовал матричные преобразования GLM, но сейчас pyrr работает нормально. В примере создается me sh из координат и отображаются разные цвета в зависимости от высоты. Вы также сможете летать, используя клавиши мыши, w, sa, d, q, e.
import numpy
import pandas
import glfw
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader
import pyrr
import glm
from pyrr import matrix44
from math import sin, cos, radians
class threeD_viewer():
def __init__(self, indi, tria, z_scale, x_st, y_st):
self.cam = Camera(x_st, y_st)
self.WIDTH, self.HEIGHT = 1280, 720
self.lastX, self.LastY = self.WIDTH / 2, self.HEIGHT / 2
self.first_mouse = True
self.forward, self.backward, self.right, self.left, self.up, self.down = False, False, False, False, False, False
self.x_start, self.y_start = x_st, y_st
vertices = indi
triangles = tria
z_values = []
for i in range(0, len(vertices)):
if vertices[i][2] < 0:
vertices[i][2] = 0
z_values.append(vertices[i][2])
else:
vertices[i][2] = vertices[i][2] * z_scale
z_values.append(vertices[i][2])
temp_z = vertices[i][2]
vertices[i][2] = vertices[i][1]
vertices[i][1] = temp_z
# Create a colour scheme to be based on height of the z axis
self.color_theme_1 = [[0.000, 0.000, 0.804], [0.678, 1.000, 0.184], [0.000, 1.000, 0.000],
[0.196, 0.804, 0.196], [1.000, 0.843, 0.000], [0.000, 0.392, 0.000]
, [0.804, 0.361, 0.361], [0.333, 0.420, 0.184]]
# Create heigth groups based on height quantiles
z_df = pandas.DataFrame(z_values, columns=["z_value"])
z_quant = z_df[z_df.z_value != 0].z_value.quantile([0.1, 0.3, 0.5, 0.75, 0.85, 0.9, 0.95, 0.98])
z_quant = z_quant.tolist()
# Add colour and texture to vertices
vert = []
for ver in vertices:
if ver[1] == 0:
color_in = self.color_theme_1[0] + [1.0, 0.0]
elif ver[1] < z_quant[0]:
color_in = self.color_theme_1[1] + [1.0, 0.0]
elif ver[1] < z_quant[1]:
color_in = self.color_theme_1[2] + [1.0, 0.0]
elif ver[1] < z_quant[2]:
color_in = self.color_theme_1[3] + [1.0, 0.0]
elif ver[1] < z_quant[3]:
color_in = self.color_theme_1[4] + [1.0, 0.0]
elif ver[1] < z_quant[4]:
color_in = self.color_theme_1[5] + [1.0, 0.0]
elif ver[1] < z_quant[5]:
color_in = self.color_theme_1[6] + [1.0, 0.0]
elif ver[1] < z_quant[6]:
color_in = self.color_theme_1[7] + [1.0, 0.0]
else:
vertices[i][1] = z_quant[6]
color_in = [0.502, 0.000, 0.000, 0.0, 0.1]
vert.append(ver + color_in)
# print(vert)
vertices = vert
self.vertices = numpy.array(vertices, dtype='f')
self.indices = numpy.array(triangles, dtype=numpy.int32)
self.vertex_src = """
# version 330
in vec3 a_position;
in vec3 a_color;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
out vec3 v_color;
void main()
{
gl_Position = projection* view* vec4(a_position, 1.0);
v_color = a_color;
}
"""
self.fragment_src = """
# version 330
in vec3 v_color;
out vec4 out_color;
void main()
{
out_color = vec4(v_color, 1.0);
}
"""
self.main()
# the keyboard input callback
def key_input_clb(self, window, key, scancode, action, mode):
if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
glfw.set_window_should_close(window, True)
if key == glfw.KEY_W and action == glfw.PRESS:
self.forward = True
elif key == glfw.KEY_W and action == glfw.RELEASE:
self.forward = False
if key == glfw.KEY_S and action == glfw.PRESS:
self.backward = True
elif key == glfw.KEY_S and action == glfw.RELEASE:
self.backward = False
if key == glfw.KEY_A and action == glfw.PRESS:
self.left = True
elif key == glfw.KEY_A and action == glfw.RELEASE:
self.left = False
if key == glfw.KEY_D and action == glfw.PRESS:
self.right = True
elif key == glfw.KEY_D and action == glfw.RELEASE:
self.right = False
if key == glfw.KEY_Q and action == glfw.PRESS:
self.up = True
elif key == glfw.KEY_Q and action == glfw.RELEASE:
self.up = False
if key == glfw.KEY_E and action == glfw.PRESS:
self.down = True
elif key == glfw.KEY_E and action == glfw.RELEASE:
self.down = False
def do_movement(self):
if self.forward:
self.cam.process_keyboard("FORWARD", 0.000008)
if self.backward:
self.cam.process_keyboard("BACKWARD", 0.000008)
if self.right:
self.cam.process_keyboard("RIGHT", 0.000008)
if self.left:
self.cam.process_keyboard("LEFT", 0.000008)
if self.up:
self.cam.process_keyboard("UP", 0.000008)
if self.down:
self.cam.process_keyboard("DOWN", 0.000008)
def mmouse_look_clb(self, window, xpos, ypos):
if self.first_mouse:
self.lastX = xpos
self.lastY = ypos
self.first_mouse = False
xoffset = xpos - self.lastX
yoffset = self.lastY - ypos
self.lastX = xpos
self.lastY = ypos
self.cam.process_mouse_movement(xoffset, yoffset)
def window_resize(self, window, width, height):
glViewport(0, 0, width, height)
projection = pyrr.matrix44.create_perspective_projection_matrix(45, width / height, 0.0001, 100)
proj_loc = glGetUniformLocation(self.shader, "projection")
glUniformMatrix4fv(proj_loc, 1, GL_FALSE, projection)
def main(self):
# initializing glfw library
if not glfw.init():
raise Exception("glfw can not be initialized!")
# creating the window
window = glfw.create_window(self.WIDTH, self.HEIGHT, "My OpenGL window", None, None)
# check if window was created
if not window:
glfw.terminate()
raise Exception("glfw window can not be created!")
# set window's position
glfw.set_window_pos(window, 400, 200)
# set the callback function for window resize
glfw.set_window_size_callback(window, self.window_resize)
glfw.set_cursor_pos_callback(window, self.mmouse_look_clb)
glfw.set_input_mode(window, glfw.CURSOR, glfw.CURSOR_DISABLED)
glfw.set_key_callback(window, self.key_input_clb)
#glfw.set_cursor_enter_callback(window, self.mouse_enter_clb)
# make the context current
glfw.make_context_current(window)
self.shader = compileProgram(compileShader(self.vertex_src, GL_VERTEX_SHADER),
compileShader(self.fragment_src, GL_FRAGMENT_SHADER))
VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)
# Vertex Buffer Object
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, GL_STATIC_DRAW)
# Element Buffer Object
EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.indices.nbytes, self.indices, GL_STATIC_DRAW)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(0))
glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(12))
glEnableVertexAttribArray(2)
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(24))
glBindVertexArray(0)
glClearColor(0, 0.1, 0.1, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
projection_2 = glm.perspective(45, self.WIDTH / self.HEIGHT, 0.001, 3000)
projection = pyrr.matrix44.create_perspective_projection_matrix(45, self.WIDTH / self.HEIGHT, 0.0001, 100)
# print(projection_2)
# print(projection)
glUseProgram(self.shader)
model_loc = glGetUniformLocation(self.shader, "model")
proj_loc = glGetUniformLocation(self.shader, "projection")
view_loc = glGetUniformLocation(self.shader, "view")
glUniformMatrix4fv(proj_loc, 1, GL_FALSE, projection)
# the main application loop
while not glfw.window_should_close(window):
glfw.poll_events()
self.do_movement()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
view = self.cam.get_view_matrix()
glUniformMatrix4fv(view_loc, 1, GL_FALSE, view)
glBindVertexArray(VAO)
glDrawElements(GL_TRIANGLES, len(self.indices) * 3, GL_UNSIGNED_INT, None)
glBindVertexArray(0)
glfw.swap_buffers(window)
# terminate glfw, free up allocated resources
glfw.terminate()
class Camera:
def __init__(self, xstart, ystart):
self.camera_pos = glm.vec3(xstart+0.005, 0.002, ystart+0.01)
self.camera_front = glm.vec3(0.0, 0.0, -200.0)
self.camera_up = glm.vec3(0.0, 1.0, 0.0)
self.camera_right = glm.vec3(1.0, 0.0, 0.0)
self.mouse_sensitivity = 0.25
self.jaw = -90.0
self.pitch = 0.0
def get_view_matrix(self):
return matrix44.create_look_at(self.camera_pos, self.camera_pos + self.camera_front, self.camera_up)
def process_mouse_movement(self, xoffset, yoffset, constrain_pitch=True):
xoffset *= self.mouse_sensitivity
yoffset *= self.mouse_sensitivity
self.jaw += xoffset
self.pitch += yoffset
if constrain_pitch:
if self.pitch > 45:
self.pitch = 45
if self.pitch < -45:
self.pitch = -45
self.update_camera_vectors()
def update_camera_vectors(self):
front = glm.vec3(0.0, 0.0, 0.0)
front.x = cos(radians(self.jaw)) * cos(radians(self.pitch))
front.y = sin(radians(self.pitch))
front.z = sin(radians(self.jaw)) * cos(radians(self.pitch))
self.camera_front = glm.normalize(front)
self.camera_right = glm.normalize(glm.cross(self.camera_front, glm.vec3(0.0, 1.0, 0.0)))
#self.camera_up = glm.normalize(glm.cross(self.camera_right, self.camera_front))
# Camera method for the WASD movement
def process_keyboard(self, direction, velocity):
if direction == "FORWARD":
self.camera_pos += self.camera_front * velocity
if direction == "BACKWARD":
self.camera_pos -= self.camera_front * velocity
if direction == "LEFT":
self.camera_pos -= self.camera_right * velocity
if direction == "RIGHT":
self.camera_pos += self.camera_right * velocity
if direction == "UP":
self.camera_pos += self.camera_up * velocity
if direction == "DOWN":
self.camera_pos -= self.camera_up * velocity
vertices = [[18.427083, -34.104583, 14.097592], [18.427917, -34.104583, 13.813885],
[18.42875, -34.104583, 11.798318], [18.429583, -34.104583, 12.170123],
[18.430417, -34.104583, 13.23494], [18.43125, -34.104583, 12.263627],
[18.432083, -34.104583, 10.543183], [18.432917, -34.104583, 9.150859],
[18.43375, -34.104583, 7.531989], [18.434583, -34.104583, 5.370541],
[18.435417, -34.104583, 4.947286],
[18.43625, -34.104583, 4.369431], [18.437083, -34.104583, 9.29184],
[18.437917, -34.104583, 11.300546], [18.43875, -34.104583, 9.590596],
[18.439583, -34.104583, 7.006906], [18.427083, -34.105417, 17.277378],
[18.427917, -34.105417, 12.070671], [18.42875, -34.105417, 9.0447],
[18.429583, -34.105417, 7.853086], [18.430417, -34.105417, 7.927739],
[18.43125, -34.105417, 8.325415],
[18.432083, -34.105417, 8.505657], [18.432917, -34.105417, 7.904904],
[18.43375, -34.105417, 7.7015], [18.434583, -34.105417, 7.362363], [18.435417, -34.105417, 7.08594],
[18.43625, -34.105417, 6.692467], [18.437083, -34.105417, 1.177889],
[18.437917, -34.105417, 6.393278], [18.43875, -34.105417, 8.610809],
[18.439583, -34.105417, 9.748986], [18.427083, -34.10625, 29.354589],
[18.427917, -34.10625, 24.616703], [18.42875, -34.10625, 18.529903],
[18.429583, -34.10625, 13.677365], [18.430417, -34.10625, 10.466432],
[18.43125, -34.10625, 9.469019], [18.432083, -34.10625, 7.960031], [18.432917, -34.10625, 7.115651],
[18.43375, -34.10625, 6.465553], [18.434583, -34.10625, 5.50102], [18.435417, -34.10625, 5.712739],
[18.43625, -34.10625, 6.946383],
[18.437083, -34.10625, 4.263526], [18.437917, -34.10625, 2.732419], [18.43875, -34.10625, 5.488115],
[18.439583, -34.10625, 6.902328], [18.427083, -34.107083, 30.979712],
[18.427917, -34.107083, 30.684374], [18.42875, -34.107083, 26.90592],
[18.429583, -34.107083, 22.378777], [18.430417, -34.107083, 19.191908],
[18.43125, -34.107083, 16.608807], [18.432083, -34.107083, 13.171669],
[18.432917, -34.107083, 10.77886], [18.43375, -34.107083, 11.478356],
[18.434583, -34.107083, 11.300546], [18.435417, -34.107083, 9.737173],
[18.43625, -34.107083, 6.484625], [18.437083, -34.107083, 5.185645],
[18.437917, -34.107083, 3.770918], [18.43875, -34.107083, 4.11032],
[18.439583, -34.107083, 4.947286], [18.427083, -34.107917, 30.013678],
[18.427917, -34.107917, 32.894321],
[18.42875, -34.107917, 31.857147], [18.429583, -34.107917, 26.9683],
[18.430417, -34.107917, 21.895006], [18.43125, -34.107917, 16.907623],
[18.432083, -34.107917, 12.721774], [18.432917, -34.107917, 11.510896],
[18.43375, -34.107917, 14.044291], [18.434583, -34.107917, 13.438006],
[18.435417, -34.107917, 12.538547], [18.43625, -34.107917, 11.562454],
[18.437083, -34.107917, 9.263826],
[18.437917, -34.107917, 6.071107], [18.43875, -34.107917, 4.289905],
[18.439583, -34.107917, 4.057948], [18.427083, -34.10875, 25.226519],
[18.427917, -34.10875, 26.609413], [18.42875, -34.10875, 29.121534],
[18.429583, -34.10875, 27.900227], [18.430417, -34.10875, 24.414494],
[18.43125, -34.10875, 20.20229], [18.432083, -34.10875, 14.686948],
[18.432917, -34.10875, 10.620943],
[18.43375, -34.10875, 11.136961], [18.434583, -34.10875, 9.067697],
[18.435417, -34.10875, 9.031256], [18.43625, -34.10875, 11.842289],
[18.437083, -34.10875, 14.412585], [18.437917, -34.10875, 14.026602],
[18.43875, -34.10875, 10.77886], [18.439583, -34.10875, 7.479022],
[18.427083, -34.109583, 24.316551], [18.427917, -34.109583, 4.027079],
[18.42875, -34.109583, 13.726677],
[18.429583, -34.109583, 23.883642], [18.430417, -34.109583, 28.826719],
[18.43125, -34.109583, 29.248907], [18.432083, -34.109583, 24.62047],
[18.432917, -34.109583, 14.576126], [18.43375, -34.109583, 10.270979],
[18.434583, -34.109583, 9.1116], [18.435417, -34.109583, 8.978557],
[18.43625, -34.109583, 10.877857], [18.437083, -34.109583, 13.952817],
[18.437917, -34.109583, 17.318939],
[18.43875, -34.109583, 18.3776], [18.439583, -34.109583, 16.823097],
[18.427083, -34.110417, 31.066404], [18.427917, -34.110417, 27.124994],
[18.42875, -34.110417, 14.584773], [18.429583, -34.110417, 6.256494],
[18.430417, -34.110417, 14.902382], [18.43125, -34.110417, 23.147758],
[18.432083, -34.110417, 26.993055], [18.432917, -34.110417, 22.765322],
[18.43375, -34.110417, 17.905703],
[18.434583, -34.110417, 13.544991], [18.435417, -34.110417, 11.899844],
[18.43625, -34.110417, 14.348012], [18.437083, -34.110417, 16.262051],
[18.437917, -34.110417, 17.542927], [18.43875, -34.110417, 21.157032],
[18.439583, -34.110417, 23.491091], [18.427083, -34.11125, 12.909849],
[18.427917, -34.11125, 20.651325], [18.42875, -34.11125, 24.733046],
[18.429583, -34.11125, 22.71829],
[18.430417, -34.11125, 12.409415], [18.43125, -34.11125, 4.794024],
[18.432083, -34.11125, 14.560322], [18.432917, -34.11125, 19.986332],
[18.43375, -34.11125, 21.261787], [18.434583, -34.11125, 18.94504],
[18.435417, -34.11125, 17.467054], [18.43625, -34.11125, 17.029078],
[18.437083, -34.11125, 15.266393], [18.437917, -34.11125, 14.918492],
[18.43875, -34.11125, 16.444849],
[18.439583, -34.11125, 18.332243], [18.427083, -34.112083, 14.870467],
[18.427917, -34.112083, 10.946778], [18.42875, -34.112083, 9.536969],
[18.429583, -34.112083, 17.428055], [18.430417, -34.112083, 20.116079],
[18.43125, -34.112083, 14.013614], [18.432083, -34.112083, 4.487359],
[18.432917, -34.112083, 4.302343], [18.43375, -34.112083, 9.771387],
[18.434583, -34.112083, 11.65025],
[18.435417, -34.112083, 11.8523], [18.43625, -34.112083, 10.677254],
[18.437083, -34.112083, 8.148099], [18.437917, -34.112083, 7.58765],
[18.43875, -34.112083, 5.033905], [18.439583, -34.112083, 3.151809],
[18.427083, -34.112917, 4.697855], [18.427917, -34.112917, 5.462211],
[18.42875, -34.112917, 6.136745], [18.429583, -34.112917, 6.001783],
[18.430417, -34.112917, 9.035099],
[18.43125, -34.112917, 13.059889], [18.432083, -34.112917, 13.085486],
[18.432917, -34.112917, 11.08321], [18.43375, -34.112917, 6.319217],
[18.434583, -34.112917, 4.270484], [18.435417, -34.112917, 4.372147],
[18.43625, -34.112917, 4.910031], [18.437083, -34.112917, 4.54907],
[18.437917, -34.112917, 3.606416], [18.43875, -34.112917, 6.188358],
[18.439583, -34.112917, 10.144054],
[18.427083, -34.11375, 8.589212], [18.427917, -34.11375, 8.18161], [18.42875, -34.11375, 7.444539],
[18.429583, -34.11375, 6.263077], [18.430417, -34.11375, 5.025665], [18.43125, -34.11375, 4.281593],
[18.432083, -34.11375, 4.90037], [18.432917, -34.11375, 9.216936], [18.43375, -34.11375, 10.723666],
[18.434583, -34.11375, 11.447696], [18.435417, -34.11375, 11.056483],
[18.43625, -34.11375, 10.136135], [18.437083, -34.11375, 6.79003], [18.437917, -34.11375, 2.968766],
[18.43875, -34.11375, 1.72892], [18.439583, -34.11375, 6.459183]]
triangles = [[0, 16, 17], [0, 17, 1], [1, 17, 18], [1, 18, 2], [2, 18, 19], [2, 19, 3], [3, 19, 20], [3, 20, 4],
[4, 20, 21], [4, 21, 5], [5, 21, 22],
[5, 22, 6], [6, 22, 23], [6, 23, 7], [7, 23, 24], [7, 24, 8], [8, 24, 25], [8, 25, 9], [9, 25, 26],
[9, 26, 10], [10, 26, 27], [10, 27, 11],
[11, 27, 28], [11, 28, 12], [12, 28, 29], [12, 29, 13], [13, 29, 30], [13, 30, 14], [14, 30, 31],
[14, 31, 15], [16, 32, 33], [16, 33, 17], [17, 33, 34],
[17, 34, 18], [18, 34, 35], [18, 35, 19], [19, 35, 36], [19, 36, 20], [20, 36, 37], [20, 37, 21],
[21, 37, 38], [21, 38, 22], [22, 38, 39], [22, 39, 23],
[23, 39, 40], [23, 40, 24], [24, 40, 41], [24, 41, 25], [25, 41, 42], [25, 42, 26], [26, 42, 43],
[26, 43, 27], [27, 43, 44], [27, 44, 28], [28, 44, 45],
[28, 45, 29], [29, 45, 46], [29, 46, 30], [30, 46, 47], [30, 47, 31], [32, 48, 49], [32, 49, 33],
[33, 49, 50], [33, 50, 34], [34, 50, 51], [34, 51, 35],
[35, 51, 52], [35, 52, 36], [36, 52, 53], [36, 53, 37], [37, 53, 54], [37, 54, 38], [38, 54, 55],
[38, 55, 39], [39, 55, 56], [39, 56, 40], [40, 56, 57],
[40, 57, 41], [41, 57, 58], [41, 58, 42], [42, 58, 59], [42, 59, 43], [43, 59, 60], [43, 60, 44],
[44, 60, 61], [44, 61, 45], [45, 61, 62], [45, 62, 46],
[46, 62, 63], [46, 63, 47], [48, 64, 65], [48, 65, 49], [49, 65, 66], [49, 66, 50], [50, 66, 67],
[50, 67, 51], [51, 67, 68], [51, 68, 52], [52, 68, 69],
[52, 69, 53], [53, 69, 70], [53, 70, 54], [54, 70, 71], [54, 71, 55], [55, 71, 72], [55, 72, 56],
[56, 72, 73], [56, 73, 57], [57, 73, 74], [57, 74, 58],
[58, 74, 75], [58, 75, 59], [59, 75, 76], [59, 76, 60], [60, 76, 77], [60, 77, 61], [61, 77, 78],
[61, 78, 62], [62, 78, 79], [62, 79, 63], [64, 80, 81],
[64, 81, 65], [65, 81, 82], [65, 82, 66], [66, 82, 83], [66, 83, 67], [67, 83, 84], [67, 84, 68],
[68, 84, 85], [68, 85, 69], [69, 85, 86], [69, 86, 70],
[70, 86, 87], [70, 87, 71], [71, 87, 88], [71, 88, 72], [72, 88, 89], [72, 89, 73], [73, 89, 90],
[73, 90, 74], [74, 90, 91], [74, 91, 75], [75, 91, 92],
[75, 92, 76], [76, 92, 93], [76, 93, 77], [77, 93, 94], [77, 94, 78], [78, 94, 95], [78, 95, 79],
[80, 96, 97], [80, 97, 81], [81, 97, 98], [81, 98, 82],
[82, 98, 99], [82, 99, 83], [83, 99, 100], [83, 100, 84], [84, 100, 101], [84, 101, 85],
[85, 101, 102], [85, 102, 86], [86, 102, 103], [86, 103, 87], [87, 103, 104],
[87, 104, 88], [88, 104, 105], [88, 105, 89], [89, 105, 106], [89, 106, 90], [90, 106, 107],
[90, 107, 91], [91, 107, 108], [91, 108, 92], [92, 108, 109], [92, 109, 93],
[93, 109, 110], [93, 110, 94], [94, 110, 111], [94, 111, 95], [96, 112, 113], [96, 113, 97],
[97, 113, 114], [97, 114, 98], [98, 114, 115], [98, 115, 99], [99, 115, 116],
[99, 116, 100], [100, 116, 117], [100, 117, 101], [101, 117, 118], [101, 118, 102], [102, 118, 119],
[102, 119, 103], [103, 119, 120], [103, 120, 104], [104, 120, 121], [104, 121, 105],
[105, 121, 122], [105, 122, 106], [106, 122, 123], [106, 123, 107], [107, 123, 124], [107, 124, 108],
[108, 124, 125], [108, 125, 109], [109, 125, 126], [109, 126, 110], [110, 126, 127],
[110, 127, 111], [112, 128, 129], [112, 129, 113], [113, 129, 130], [113, 130, 114], [114, 130, 131],
[114, 131, 115], [115, 131, 132], [115, 132, 116], [116, 132, 133], [116, 133, 117],
[117, 133, 134], [117, 134, 118], [118, 134, 135], [118, 135, 119], [119, 135, 136], [119, 136, 120],
[120, 136, 137], [120, 137, 121], [121, 137, 138], [121, 138, 122], [122, 138, 139],
[122, 139, 123], [123, 139, 140], [123, 140, 124], [124, 140, 141], [124, 141, 125], [125, 141, 142],
[125, 142, 126], [126, 142, 143], [126, 143, 127], [128, 144, 145], [128, 145, 129],
[129, 145, 146], [129, 146, 130], [130, 146, 147], [130, 147, 131], [131, 147, 148], [131, 148, 132],
[132, 148, 149], [132, 149, 133], [133, 149, 150], [133, 150, 134], [134, 150, 151],
[134, 151, 135], [135, 151, 152], [135, 152, 136], [136, 152, 153], [136, 153, 137], [137, 153, 154],
[137, 154, 138], [138, 154, 155], [138, 155, 139], [139, 155, 156], [139, 156, 140],
[140, 156, 157], [140, 157, 141], [141, 157, 158], [141, 158, 142], [142, 158, 159], [142, 159, 143],
[144, 160, 161], [144, 161, 145], [145, 161, 162], [145, 162, 146], [146, 162, 163],
[146, 163, 147], [147, 163, 164], [147, 164, 148], [148, 164, 165], [148, 165, 149], [149, 165, 166],
[149, 166, 150], [150, 166, 167], [150, 167, 151], [151, 167, 168], [151, 168, 152],
[152, 168, 169], [152, 169, 153], [153, 169, 170], [153, 170, 154], [154, 170, 171], [154, 171, 155],
[155, 171, 172], [155, 172, 156], [156, 172, 173], [156, 173, 157], [157, 173, 174],
[157, 174, 158], [158, 174, 175], [158, 175, 159], [160, 176, 177], [160, 177, 161], [161, 177, 178],
[161, 178, 162], [162, 178, 179], [162, 179, 163], [163, 179, 180], [163, 180, 164],
[164, 180, 181], [164, 181, 165], [165, 181, 182], [165, 182, 166], [166, 182, 183], [166, 183, 167],
[167, 183, 184], [167, 184, 168], [168, 184, 185], [168, 185, 169], [169, 185, 186],
[169, 186, 170], [170, 186, 187], [170, 187, 171], [171, 187, 188], [171, 188, 172], [172, 188, 189],
[172, 189, 173], [173, 189, 190], [173, 190, 174], [174, 190, 191], [174, 191, 175]]
Z_scale = 0.00005
xStart = vertices[0][0]
yStart = vertices[0][1]
threeD_viewer(vertices, triangles, Z_scale, xStart, yStart)