Created by: zeffii
this shader util is required for 2d shape drawing into nodeview
example
import bgl
import blf
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
from bpy.types import SpaceNodeEditor
import sverchok
from sverchok.settings import get_params
from sverchok.utils.modules.shader_utils import ShaderLib2D
handler_remove = SpaceNodeEditor.draw_handler_remove
handler_add = SpaceNodeEditor.draw_handler_add
# remove previous handler if it exists.
if hasattr(bpy, 'test_handler'): handler_remove(bpy.test_handler, 'WINDOW')
if hasattr(bpy, 'test_handler_overlay'): handler_remove(bpy.test_handler_overlay, 'WINDOW')
def string_from_duration(duration):
original_duration = duration
postfix = "ms"
duration *= 1000
return f"{duration:.3f} {postfix}" # ({original_duration:6f} sec)"
def get_preferences():
props = get_params({'render_location_xy_multiplier': 1.0})
return props.render_location_xy_multiplier
def write_time_graph():
m = sverchok.core.update_system.graphs
if len(m) == 1:
return {idx: event for idx, event in enumerate(m[0])}
else:
cumulative_dict = {}
counter = 0
for graph in m:
for event in graph:
cumulative_dict[counter] = event
counter += 1
return cumulative_dict
def get_sv_times(named_group):
ng = bpy.data.node_groups
upd = bpy.ops.node.sverchok_update_current
for g in ng:
if g.bl_idname == 'SverchCustomTreeType':
if g.name == named_group:
upd(node_group=named_group)
return write_time_graph()
def draw_text(font_id, location, text, color):
# txt_width, txt_height = blf.dimensions(font_id, text)
x, y = location
r, g, b = color
blf.position(font_id, x, y, 0)
level = 5 # 3, 5 or 0
blf.color(font_id, r, g, b, 1.0)
blf.enable(font_id, blf.SHADOW)
blf.shadow(font_id, level, 0, 0, 0, 1)
blf.shadow_offset(font_id, 1, -1)
# blf.position(0, x - (txt_width / 2), y - (txt_height / 2), 0)
blf.draw(font_id, text)
blf.disable(font_id, blf.SHADOW)
def draw(*data):
data_tree = write_time_graph() # data[0]
location_theta = data[1]
node_tree = bpy.data.node_groups.get(data[2])
r, g, b = (0.9, 0.9, 0.9)
font_id = 0
text_height = 20
def get_xy_for_bgl_drawing(node):
_x, _y = node.absolute_location
_x, _y = _x, _y + (text_height - 9)
return _x * location_theta, _y * location_theta
blf.size(font_id, int(text_height), 72)
blf.color(font_id, r, g, b, 1.0)
for idx, node_data in data_tree.items():
node = node_tree.nodes.get(node_data['name'])
if not node: continue
x, y = get_xy_for_bgl_drawing(node)
x, y = int(x), int(y)
show_str = string_from_duration(node_data['duration'])
draw_text(font_id, (x, y), show_str, (r, g, b))
def draw_overlay(*data):
area_width = bpy.context.area.width
# bpy.context.area.height
data_tree = write_time_graph() # data[0]
node_tree = bpy.data.node_groups.get(data[1])
shader = data[2]
left_offset = 200
white = (1.0, 1.0, 1.0, 1.0)
canvas = ShaderLib2D()
canvas.add_rect(30, 140, 20, 60, white)
canvas.add_rect(130, 40, 20, 60, white)
canvas.add_rect(left_offset, 40, area_width - left_offset - 20, 1, white)
geom = canvas.compile()
batch = batch_for_shader(shader, 'TRIS',
{"pos": geom.vectors,
"color": geom.vertex_colors},
indices=geom.indices
)
# bgl.glEnable(bgl.GL_DEPTH_TEST)
batch.draw(shader)
# bgl.glDisable(bgl.GL_DEPTH_TEST)
r, g, b = (0.9, 0.9, 0.95)
font_id = 0
text_height = 10
stripe = "________________________"
blf.size(font_id, int(text_height), 72)
blf.color(font_id, r, g, b, 1.0)
x, y = 20, 50
cumsum = 0.0
# for idx, node_data in data_tree.items():
for idx in sorted(data_tree, reverse=True, key=lambda value: data_tree.get(value).get("duration")):
node_data = data_tree.get(idx)
node = node_tree.nodes.get(node_data['name'])
if not node: continue
node_name = node_data['name']
cumsum += node_data['duration']
duration_as_str = string_from_duration(node_data['duration'])
show_str = f"{node_name} : {duration_as_str}"
draw_text(font_id, (x, y), show_str, (r, g, b))
y += (text_height + 3)
y = 29
cum_duration = string_from_duration(cumsum)
draw_text(font_id, (x, y), f"total: {cum_duration}", (r, g, b))
y += (text_height + 4)
draw_text(font_id, (x, y), stripe, (r, g, b))
shader = gpu.shader.from_builtin('2D_SMOOTH_COLOR')
named_tree = "NodeTree"
data = (get_sv_times(named_tree), get_preferences(), named_tree)
data_overlay = (get_sv_times(named_tree), named_tree, shader)
bpy.test_handler = handler_add(draw, data, 'WINDOW', 'POST_VIEW')
bpy.test_handler_overlay = handler_add(draw_overlay, data_overlay, 'WINDOW', 'POST_PIXEL')