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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
def console_namespace():
import console_python
for window in bpy.context.window_manager.windows:
for area in window.screen.areas:
if area.type == 'CONSOLE':
for region in area.regions:
if region.type == 'WINDOW':
console = console_python.get_console(hash(region))
if console:
return console[0].locals
return {}
def is_display_list(listvar):
from mathutils import Vector
for var in listvar:
if not isinstance(var, Vector):
return False
return True
class VarStates:
@staticmethod
def store_states():
# Store the display states, called upon unregister the Add-on
# This is useful when you press F8 to reload the Addons.
# Then this function preserves the display states of the
# console variables.
state_props = bpy.context.window_manager.MathVisStatePropList
variables = get_math_data()
for index, state_prop in reversed(list(enumerate(state_props))):
if state_prop.name not in variables:
# Variable has been removed from console
state_props.remove(index)
for key, ktype in variables.items():
if key and key not in state_props:
prop = state_props.add()
prop.name = key
prop.ktype = ktype.__name__
prop.state = [True, False]
@staticmethod
def get_index(key):
index = bpy.context.window_manager.MathVisStatePropList.find(key)
return index
@staticmethod
def delete(key):
state_props = bpy.context.window_manager.MathVisStatePropList
index = state_props.find(key)
if index != -1:
state_props.remove(index)
@staticmethod
def toggle_display_state(key):
state_props = bpy.context.window_manager.MathVisStatePropList
if key in state_props:
state_props[key].state[0] = not state_props[key].state[0]
else:
print("Odd: Can not find key %s in MathVisStateProps" % (key))
@staticmethod
def toggle_lock_state(key):
state_props = bpy.context.window_manager.MathVisStatePropList
if key in state_props:
state_props[key].state[1] = not state_props[key].state[1]
else:
print("Odd: Can not find key %s in MathVisStateProps" % (key))
def get_math_data():
from mathutils import Matrix, Vector, Quaternion, Euler
locals = console_namespace()
if not locals:
return {}
variables = {}
for key, var in locals.items():
if len(key) == 0 or key[0] == "_":
continue
type_var = type(var)
# Rules out sets/dicts.
# It's also possible the length check below is slow
# for data with underlying linked-list structure.
if not hasattr(type_var, "__getitem__"):
continue
# Don't do a truth test on the data because this causes an error with some
# array types, see T66107.
len_fn = getattr(type_var, "__len__", None)
if len_fn is None:
continue
if len_fn(var) == 0:
continue
if isinstance(var, (Matrix, Vector, Quaternion, Euler)) or \
isinstance(var, (tuple, list)) and is_display_list(var):
variables[key] = type_var
return variables
def cleanup_math_data():
locals = console_namespace()
if not locals:
return
variables = get_math_data()
for key in variables.keys():
index = VarStates.get_index(key)
if index == -1:
continue
state_prop = bpy.context.window_manager.MathVisStatePropList.get(key)
if state_prop.state[1]:
continue
del locals[key]
bpy.context.window_manager.MathVisStatePropList.remove(index)
def console_math_data():
from mathutils import Matrix, Vector, Quaternion, Euler
data_matrix = {}
data_quat = {}
data_euler = {}
data_vector = {}
data_vector_array = {}
for key, var in console_namespace().items():
if key[0] == "_":
continue
state_prop = bpy.context.window_manager.MathVisStatePropList.get(key)
if state_prop:
disp, lock = state_prop.state
if not disp:
continue
if isinstance(var, Matrix):
if len(var.col) != 4 or len(var.row) != 4:
if len(var.col) == len(var.row):
var = var.to_4x4()
else: # todo, support 4x3 matrix
continue
data_matrix[key] = var
elif isinstance(var, Vector):
if len(var) < 3:
var = var.to_3d()
data_vector[key] = var
elif isinstance(var, Quaternion):
data_quat[key] = var
elif isinstance(var, Euler):
data_euler[key] = var
elif type(var) in {list, tuple} and is_display_list(var):
data_vector_array[key] = var
return data_matrix, data_quat, data_euler, data_vector, data_vector_array
|