1 # SPDX-License-Identifier: GPL-2.0-or-later
9 from gpu_extras
.batch
import batch_for_shader
12 from mathutils
import Vector
14 SpaceView3D
= bpy
.types
.SpaceView3D
17 if not bpy
.app
.background
:
18 single_color_shader
= gpu
.shader
.from_builtin('3D_UNIFORM_COLOR')
19 smooth_color_shader
= gpu
.shader
.from_builtin('3D_SMOOTH_COLOR')
21 single_color_shader
= None
22 smooth_color_shader
= None
24 COLOR_POINT
= (1.0, 0.0, 1.0, 1)
25 COLOR_LINE
= (0.5, 0.5, 1, 1)
26 COLOR_LINE_ACTIVE
= (1.0, 1.0, 0.5, 1)
27 COLOR_BOUNDING_BOX
= (1.0, 1.0, 1.0, 1.0)
28 COLOR_BOUNDING_BOX_ACTIVE
= (1.0, 0.5, 0.0, 1.0)
31 def tag_redraw_areas():
34 # Py cant access notifers
35 for window
in context
.window_manager
.windows
:
36 for area
in window
.screen
.areas
:
37 if area
.type in ['VIEW_3D', 'PROPERTIES']:
41 def callback_enable():
45 handle_pixel
= SpaceView3D
.draw_handler_add(draw_callback_px
, (), 'WINDOW', 'POST_PIXEL')
46 handle_view
= SpaceView3D
.draw_handler_add(draw_callback_view
, (), 'WINDOW', 'POST_VIEW')
47 callback_handle
[:] = handle_pixel
, handle_view
52 def callback_disable():
53 if not callback_handle
:
56 handle_pixel
, handle_view
= callback_handle
57 SpaceView3D
.draw_handler_remove(handle_pixel
, 'WINDOW')
58 SpaceView3D
.draw_handler_remove(handle_view
, 'WINDOW')
59 callback_handle
[:] = []
64 def draw_callback_px():
67 if context
.window_manager
.MathVisProp
.name_hide
:
71 ui_scale
= context
.preferences
.system
.ui_scale
72 blf
.size(font_id
, round(12 * ui_scale
), 72)
74 data_matrix
, data_quat
, data_euler
, data_vector
, data_vector_array
= utils
.console_math_data()
75 if not data_matrix
and not data_quat
and not data_euler
and not data_vector
and not data_vector_array
:
78 region
= context
.region
79 region3d
= context
.space_data
.region_3d
81 region_mid_width
= region
.width
/ 2.0
82 region_mid_height
= region
.height
/ 2.0
84 perspective_matrix
= region3d
.perspective_matrix
.copy()
86 def draw_text(text
, vec
, dx
=3.0, dy
=-4.0):
87 vec_4d
= perspective_matrix
@ vec
.to_4d()
89 x
= region_mid_width
+ region_mid_width
* (vec_4d
.x
/ vec_4d
.w
)
90 y
= region_mid_height
+ region_mid_height
* (vec_4d
.y
/ vec_4d
.w
)
92 blf
.position(font_id
, x
+ dx
, y
+ dy
, 0.0)
93 blf
.draw(font_id
, text
)
96 for key
, vec
in data_vector
.items():
100 for key
, vec
in data_vector_array
.items():
102 draw_text(key
, vec
[0])
105 for key
, mat
in data_matrix
.items():
106 loc
= Vector((mat
[0][3], mat
[1][3], mat
[2][3]))
107 draw_text(key
, loc
, dx
=10, dy
=-20)
111 loc
= context
.scene
.cursor
.location
.copy()
112 for key
, mat
in data_quat
.items():
113 draw_text(key
, loc
, dy
=-offset_y
)
117 loc
= context
.scene
.cursor
.location
.copy()
118 for key
, mat
in data_euler
.items():
119 draw_text(key
, loc
, dy
=-offset_y
)
123 def draw_callback_view():
124 settings
= bpy
.context
.window_manager
.MathVisProp
125 prop_states
= bpy
.context
.window_manager
.MathVisStatePropList
127 scale
= settings
.bbox_scale
128 with_bounding_box
= not settings
.bbox_hide
130 if settings
.in_front
:
131 bgl
.glDepthFunc(bgl
.GL_ALWAYS
)
133 bgl
.glDepthFunc(bgl
.GL_LESS
)
135 data_matrix
, data_quat
, data_euler
, data_vector
, data_vector_array
= utils
.console_math_data()
136 if settings
.index
in range(0,len(prop_states
)):
137 active_index
= settings
.index
138 active_key
= prop_states
[active_index
].name
144 coords
= [tuple(vec
.to_3d()) for vec
in data_vector
.values()]
147 if data_vector_array
:
148 for key
, line
in data_vector_array
.items():
149 coords
= [tuple(vec
.to_3d()) for vec
in line
]
150 if key
== active_key
:
151 draw_line(coords
, COLOR_LINE_ACTIVE
)
153 draw_line(coords
, COLOR_LINE
)
156 draw_matrices(data_matrix
, scale
, with_bounding_box
, active_key
)
158 if data_euler
or data_quat
:
159 cursor
= bpy
.context
.scene
.cursor
.location
.copy()
160 derived_matrices
= []
161 for key
, quat
in data_quat
.values():
162 matrix
= quat
.to_matrix().to_4x4()
163 matrix
.translation
= cursor
164 derived_matrices
[key
] = matrix
165 for key
, eul
in data_euler
.values():
166 matrix
= eul
.to_matrix().to_4x4()
167 matrix
.translation
= cursor
168 derived_matrices
[key
] = matrix
169 draw_matrices(derived_matrices
, scale
, with_bounding_box
, active_key
)
172 def draw_points(points
):
173 batch
= batch_from_points(points
, "POINTS")
174 single_color_shader
.bind()
175 single_color_shader
.uniform_float("color", COLOR_POINT
)
176 batch
.draw(single_color_shader
)
179 def draw_line(points
, color
):
180 batch
= batch_from_points(points
, "LINE_STRIP")
181 single_color_shader
.bind()
182 single_color_shader
.uniform_float("color", color
)
183 batch
.draw(single_color_shader
)
186 def batch_from_points(points
, type):
187 return batch_for_shader(single_color_shader
, type, {"pos": points
})
190 def draw_matrices(matrices
, scale
, with_bounding_box
, active_key
):
191 x_p
= Vector((scale
, 0.0, 0.0))
192 x_n
= Vector((-scale
, 0.0, 0.0))
193 y_p
= Vector((0.0, scale
, 0.0))
194 y_n
= Vector((0.0, -scale
, 0.0))
195 z_p
= Vector((0.0, 0.0, scale
))
196 z_n
= Vector((0.0, 0.0, -scale
))
198 red_dark
= (0.2, 0.0, 0.0, 1.0)
199 red_light
= (1.0, 0.2, 0.2, 1.0)
200 green_dark
= (0.0, 0.2, 0.0, 1.0)
201 green_light
= (0.2, 1.0, 0.2, 1.0)
202 blue_dark
= (0.0, 0.0, 0.2, 1.0)
203 blue_light
= (0.4, 0.4, 1.0, 1.0)
209 for key
, matrix
in matrices
.items():
210 coords
.append(matrix
@ x_n
)
211 coords
.append(matrix
@ x_p
)
212 colors
.extend((red_dark
, red_light
))
213 coords
.append(matrix
@ y_n
)
214 coords
.append(matrix
@ y_p
)
215 colors
.extend((green_dark
, green_light
))
216 coords
.append(matrix
@ z_n
)
217 coords
.append(matrix
@ z_p
)
218 colors
.extend((blue_dark
, blue_light
))
219 if key
== active_key
:
220 active
.append(matrix
)
222 selected
.append(matrix
)
224 batch
= batch_for_shader(smooth_color_shader
, "LINES", {
228 batch
.draw(smooth_color_shader
)
230 if with_bounding_box
:
232 draw_bounding_boxes(selected
, scale
, COLOR_BOUNDING_BOX
)
234 draw_bounding_boxes(active
, scale
, COLOR_BOUNDING_BOX_ACTIVE
)
237 def draw_bounding_boxes(matrices
, scale
, color
):
239 for x
in (-scale
, scale
):
240 for y
in (-scale
, scale
):
241 for z
in (-scale
, scale
):
242 boundbox_points
.append(Vector((x
, y
, z
)))
245 (0, 1), (1, 3), (3, 2), (2, 0), (0, 4), (4, 5),
246 (5, 7), (7, 6), (6, 4), (1, 5), (2, 6), (3, 7)
250 for matrix
in matrices
:
251 for v1
, v2
in boundbox_lines
:
252 points
.append(matrix
@ boundbox_points
[v1
])
253 points
.append(matrix
@ boundbox_points
[v2
])
255 batch
= batch_from_points(points
, "LINES")
257 single_color_shader
.bind()
258 single_color_shader
.uniform_float("color", color
)
259 batch
.draw(single_color_shader
)