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
175
176
177
178
179
180
181
182
183
184
185
|
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
import bpy
def console_namespace():
import console_python
get_consoles = console_python.get_console
consoles = getattr(get_consoles, "consoles", None)
if consoles:
for console, stdout, stderr in get_consoles.consoles.values():
return console.locals
return {}
def is_display_list(listvar):
from mathutils import Vector
for var in listvar:
if type(var) is not 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 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 type_var in {Matrix, Vector, Quaternion, Euler} or \
type_var in {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
var_type = type(var)
if var_type is 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 var_type is Vector:
if len(var) < 3:
var = var.to_3d()
data_vector[key] = var
elif var_type is Quaternion:
data_quat[key] = var
elif var_type is Euler:
data_euler[key] = var
elif var_type 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
|