-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmotion_graph_widget.py
115 lines (81 loc) · 3.2 KB
/
motion_graph_widget.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
import sys
import json
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtCore import QUrl
from PyQt5.QtCore import *
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtGui import *
import qt_resources
from motion_graph import MotionGraph
class GraphVisualizePage(QWebEnginePage):
def __init__(self):
self._is_loaded = False
self._motion_graph = None
QWebEnginePage.__init__(self)
# self.on_node_select_callbacks = []
@pyqtSlot()
def on_node_selected(self, id):
# for listener in self.on_node_select_listeners:
# listener(id)
print(f'User selected node {id}')
@pyqtSlot(str)
def log(self, string):
print(string)
@pyqtSlot()
def on_channel_ready(self):
self._is_loaded = True
if self._motion_graph is not None:
self.load_motion_graph(self._motion_graph)
self._motion_graph = None
def init(self):
self.runJavaScript('init()')
def load_motion_graph(self, motion_graph):
if not self._is_loaded:
self._motion_graph = motion_graph
return
self.log('Loading Motion Graph')
nodes = []
edges = []
visited = {}
def build_rec(node):
if self._id(node) in visited:
return
visited[self._id(node)] = True
nodes.append({ 'id': self._id(node), 'name': node.label, 'weight': str(len(node.iin) + len(node.out)) })
for out_edge in node.out:
try:
motion_idx = self._motion_graph._motions.index(out_edge.motion) + 1
except ValueError:
motion_idx = 0
edges.append({ 'id': self._id(out_edge), 'motion_idx': motion_idx, 'label': out_edge.label,'source': self._id(node), 'target': self._id(out_edge.dst), 'length': str(len(out_edge.frames))})
build_rec(out_edge.dst)
for node in motion_graph.get_root_nodes():
build_rec(node)
js = f"load_motion_graph('{json.dumps(nodes)}', '{json.dumps(edges)}')"
self.runJavaScript(js)
def _id(self, obj):
return str(id(obj))
def set_active_edge(self, edge):
if self._is_loaded:
self.runJavaScript(f'set_active_edge({self._id(edge)})')
class MotionGraphVisualizerWidget(QWebEngineView):
def __init__(self, parent=None):
QWebEngineView.__init__(self, parent)
self.setAttribute(Qt.WA_TranslucentBackground);
self.setWindowFlags(Qt.FramelessWindowHint);
self._page = GraphVisualizePage()
self.setPage(self._page)
self._channel = QWebChannel(self._page)
self._channel.registerObject('page', self._page)
self._page.setWebChannel(self._channel)
self.loadFinished.connect(self._on_load_finished)
self.setUrl(QUrl('qrc:/graph_visualizer/test.html'))
def _on_load_finished(self):
self._page.init()
def load_motion_graph(self, motion_graph):
self._page.load_motion_graph(motion_graph)
@property
def visualizer(self):
return self._page