File size: 5,098 Bytes
ba246bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import pygame
from pygame import math
from pygame.locals import *
from view import graph
from mesh_display import MeshDisplay
from environment.actions.quadrangular_actions import split_edge_ids, flip_edge_cw_ids, collapse_edge_ids
import sys

color1 = pygame.Color(30, 30, 30)  # Dark Grey
color2 = pygame.Color(255, 255, 255)  # White
color3 = pygame.Color(128, 128, 128)  # Grey
color4 = pygame.Color(255, 0, 0)  # Red
color5 = pygame.Color(0, 255, 0)  # Green

edge_color_normal = color1
node_color_normal = color4
edge_color_select = color5
node_color_select = color3


class window_data:
    def __init__(self):
        self.options = pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.RESIZABLE
        self.center = pygame.math.Vector2(250, 250)
        self.size = (1024, 1024)
        self.stretch = 10.0
        self.scene_center = pygame.math.Vector2(0, 0)
        self.scene_xmin = -250
        self.scene_xmax = 250
        self.scene_ymin = -250
        self.scene_ymax = 250
        self.node_size = 15
        self.edge_thickness = 2
        self.font_size = 25
        self.edge_picking_pixel_tolerance = 5


class Game:
    win_data = window_data()

    def __init__(self, cmap, mesh_disp: MeshDisplay):
        scores = mesh_disp.get_scores()
        self.graph = graph.Graph(mesh_disp.get_nodes_coordinates(), mesh_disp.get_edges(), scores)
        self.model = cmap
        self.mesh_disp = mesh_disp
        pygame.init()
        self.window = pygame.display.set_mode(Game.win_data.size, Game.win_data.options)
        pygame.display.set_caption('TriGame')
        self.window.fill((255, 255, 255))
        self.font = pygame.font.SysFont(None, Game.win_data.font_size)
        self.clock = pygame.time.Clock()
        self.clock.tick(60)
        Game.win_data.scene_xmin, Game.win_data.scene_ymin, Game.win_data.scene_xmax, Game.win_data.scene_ymax = self.graph.bounding_box()
        Game.win_data.scene_center = math.Vector2((Game.win_data.scene_xmax + Game.win_data.scene_xmin) / 2.0,
                                                  (Game.win_data.scene_ymax + Game.win_data.scene_ymin) / 2.0)

    def draw(self):
        for e in self.graph.edges:
            e.draw(self.window, Game.win_data)
        for n in self.graph.vertices:
            n.draw(self.window, self.font, Game.win_data)

    def control_events(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

            if event.type == VIDEORESIZE or event.type == VIDEOEXPOSE:  # handles window minimising/maximising
                x, y = self.window.get_size()
                Game.win_data.center.x = x / 2
                Game.win_data.center.y = y / 2
                ratio = float(x) / float(Game.win_data.scene_xmax - Game.win_data.scene_xmin)
                ratio_y = float(y) / float(Game.win_data.scene_ymax - Game.win_data.scene_ymin)
                if ratio_y < ratio:
                    ratio = ratio_y

                Game.win_data.node_size = max(ratio / 100, 10)
                Game.win_data.stretch = 0.75 * ratio

                self.window.fill((255, 255, 255))
                pygame.display.flip()

            if event.type == pygame.MOUSEBUTTONDOWN:
                x, y = pygame.mouse.get_pos()
                # only edges can be selected, and just one at a time
                already_selected = False
                for e in self.graph.edges:
                    if e.collide_point(x, y, self.win_data) and not already_selected:
                        if pygame.key.get_pressed()[pygame.K_f]:
                            if flip_edge_cw_ids(self.model, e.start.idx, e.end.idx):
                                self.graph.clear()
                                self.graph.update(self.mesh_disp.get_nodes_coordinates(), self.mesh_disp.get_edges(), self.mesh_disp.get_scores())
                                already_selected = True
                        elif pygame.key.get_pressed()[pygame.K_s]:
                            if split_edge_ids(self.model, e.start.idx, e.end.idx):
                                self.graph.clear()
                                self.graph.update(self.mesh_disp.get_nodes_coordinates(),self.mesh_disp.get_edges(), self.mesh_disp.get_scores())
                                already_selected = True
                        elif pygame.key.get_pressed()[pygame.K_c]:
                            if collapse_edge_ids(self.model, e.start.idx, e.end.idx):
                                self.graph.clear()
                                self.graph.update(self.mesh_disp.get_nodes_coordinates(),self.mesh_disp.get_edges(), self.mesh_disp.get_scores())
                                already_selected = True

    def run(self):
        print("TriGame is  starting!!")
        print("- Press f and the mouse button to flip an edge")
        print("- Press s and the mouse button to split an edge")
        while True:
            self.control_events()
            self.window.fill((255, 255, 255))
            self.draw()
            pygame.display.flip()