From 9f6c1c0964bd38a9280d2a92d83255df166a7d9c Mon Sep 17 00:00:00 2001 From: Philipp Oeser <info@graphics-engineer.com> Date: Fri, 15 Mar 2019 16:41:36 +0100 Subject: [PATCH] Node Wrangler: update drawing code to 2.8 Reviewers: JacquesLucke Differential Revision: https://developer.blender.org/D4517 --- node_wrangler.py | 217 +++++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 110 deletions(-) diff --git a/node_wrangler.py b/node_wrangler.py index f4d06f762..c2c267ed6 100644 --- a/node_wrangler.py +++ b/node_wrangler.py @@ -30,6 +30,7 @@ bl_info = { } import bpy, blf, bgl +import gpu from bpy.types import Operator, Panel, Menu from bpy.props import ( FloatProperty, @@ -41,6 +42,7 @@ from bpy.props import ( CollectionProperty, ) from bpy_extras.io_utils import ImportHelper, ExportHelper +from gpu_extras.batch import batch_for_shader from mathutils import Vector from math import cos, sin, pi, hypot from os import path @@ -747,53 +749,40 @@ def store_mouse_cursor(context, event): else: space.cursor_location = tree.view_center +def draw_line(x1, y1, x2, y2, size, colour=(1.0, 1.0, 1.0, 0.7)): + shader = gpu.shader.from_builtin('2D_SMOOTH_COLOR') -def draw_line(x1, y1, x2, y2, size, colour=[1.0, 1.0, 1.0, 0.7]): - shademodel_state = bgl.Buffer(bgl.GL_INT, 1) - bgl.glGetIntegerv(bgl.GL_SHADE_MODEL, shademodel_state) + vertices = ((x1, y1), (x2, y2)) + vertex_colors = ((colour[0]+(1.0-colour[0])/4, + colour[1]+(1.0-colour[1])/4, + colour[2]+(1.0-colour[2])/4, + colour[3]+(1.0-colour[3])/4), + colour) - bgl.glEnable(bgl.GL_BLEND) + batch = batch_for_shader(shader, 'LINE_STRIP', {"pos": vertices, "color": vertex_colors}) bgl.glLineWidth(size * dpifac()) - bgl.glShadeModel(bgl.GL_SMOOTH) - bgl.glEnable(bgl.GL_LINE_SMOOTH) - - bgl.glBegin(bgl.GL_LINE_STRIP) - try: - bgl.glColor4f(colour[0]+(1.0-colour[0])/4, colour[1]+(1.0-colour[1])/4, colour[2]+(1.0-colour[2])/4, colour[3]+(1.0-colour[3])/4) - bgl.glVertex2f(x1, y1) - bgl.glColor4f(colour[0], colour[1], colour[2], colour[3]) - bgl.glVertex2f(x2, y2) - except: - pass - bgl.glEnd() - - bgl.glShadeModel(shademodel_state[0]) - bgl.glDisable(bgl.GL_LINE_SMOOTH) - - -def draw_circle(mx, my, radius, colour=[1.0, 1.0, 1.0, 0.7]): - bgl.glEnable(bgl.GL_LINE_SMOOTH) - bgl.glBegin(bgl.GL_TRIANGLE_FAN) - bgl.glColor4f(colour[0], colour[1], colour[2], colour[3]) + + shader.bind() + batch.draw(shader) + + +def draw_circle_2d_filled(shader, mx, my, radius, colour=(1.0, 1.0, 1.0, 0.7)): radius = radius * dpifac() sides = 12 - for i in range(sides + 1): - cosine = radius * cos(i * 2 * pi / sides) + mx - sine = radius * sin(i * 2 * pi / sides) + my - bgl.glVertex2f(cosine, sine) - bgl.glEnd() - bgl.glDisable(bgl.GL_LINE_SMOOTH) + vertices = [(radius * cos(i * 2 * pi / sides) + mx, + radius * sin(i * 2 * pi / sides) + my) + for i in range(sides + 1)] + batch = batch_for_shader(shader, 'TRI_FAN', {"pos": vertices}) + shader.bind() + shader.uniform_float("color", colour) + batch.draw(shader) -def draw_rounded_node_border(node, radius=8, colour=[1.0, 1.0, 1.0, 0.7]): - bgl.glEnable(bgl.GL_BLEND) - bgl.glEnable(bgl.GL_LINE_SMOOTH) - +def draw_rounded_node_border(shader, node, radius=8, colour=(1.0, 1.0, 1.0, 0.7)): area_width = bpy.context.area.width - (16*dpifac()) - 1 bottom_bar = (16*dpifac()) + 1 sides = 16 radius = radius*dpifac() - bgl.glColor4f(colour[0], colour[1], colour[2], colour[3]) nlocx = (node.location.x+1)*dpifac() nlocy = (node.location.y+1)*dpifac() @@ -821,129 +810,142 @@ def draw_rounded_node_border(node, radius=8, colour=[1.0, 1.0, 1.0, 0.7]): radius += 6 # Top left corner - bgl.glBegin(bgl.GL_TRIANGLE_FAN) mx, my = bpy.context.region.view2d.view_to_region(nlocx, nlocy, clip=False) - bgl.glVertex2f(mx,my) + vertices = [(mx,my)] for i in range(sides+1): if (4<=i<=8): if my > bottom_bar and mx < area_width: cosine = radius * cos(i * 2 * pi / sides) + mx sine = radius * sin(i * 2 * pi / sides) + my - bgl.glVertex2f(cosine, sine) - bgl.glEnd() + vertices.append((cosine,sine)) + batch = batch_for_shader(shader, 'TRI_FAN', {"pos": vertices}) + shader.bind() + shader.uniform_float("color", colour) + batch.draw(shader) # Top right corner - bgl.glBegin(bgl.GL_TRIANGLE_FAN) mx, my = bpy.context.region.view2d.view_to_region(nlocx + ndimx, nlocy, clip=False) - bgl.glVertex2f(mx,my) + vertices = [(mx,my)] for i in range(sides+1): if (0<=i<=4): if my > bottom_bar and mx < area_width: cosine = radius * cos(i * 2 * pi / sides) + mx sine = radius * sin(i * 2 * pi / sides) + my - bgl.glVertex2f(cosine, sine) - bgl.glEnd() + vertices.append((cosine,sine)) + batch = batch_for_shader(shader, 'TRI_FAN', {"pos": vertices}) + shader.bind() + shader.uniform_float("color", colour) + batch.draw(shader) # Bottom left corner - bgl.glBegin(bgl.GL_TRIANGLE_FAN) mx, my = bpy.context.region.view2d.view_to_region(nlocx, nlocy - ndimy, clip=False) - bgl.glVertex2f(mx,my) + vertices = [(mx,my)] for i in range(sides+1): if (8<=i<=12): if my > bottom_bar and mx < area_width: cosine = radius * cos(i * 2 * pi / sides) + mx sine = radius * sin(i * 2 * pi / sides) + my - bgl.glVertex2f(cosine, sine) - bgl.glEnd() + vertices.append((cosine,sine)) + batch = batch_for_shader(shader, 'TRI_FAN', {"pos": vertices}) + shader.bind() + shader.uniform_float("color", colour) + batch.draw(shader) # Bottom right corner - bgl.glBegin(bgl.GL_TRIANGLE_FAN) mx, my = bpy.context.region.view2d.view_to_region(nlocx + ndimx, nlocy - ndimy, clip=False) - bgl.glVertex2f(mx,my) + vertices = [(mx,my)] for i in range(sides+1): if (12<=i<=16): if my > bottom_bar and mx < area_width: cosine = radius * cos(i * 2 * pi / sides) + mx sine = radius * sin(i * 2 * pi / sides) + my - bgl.glVertex2f(cosine, sine) - bgl.glEnd() + vertices.append((cosine,sine)) + batch = batch_for_shader(shader, 'TRI_FAN', {"pos": vertices}) + shader.bind() + shader.uniform_float("color", colour) + batch.draw(shader) + # prepare drawing all edges in one batch + vertices = [] + indices = [] + id_last = 0 # Left edge - bgl.glBegin(bgl.GL_QUADS) m1x, m1y = bpy.context.region.view2d.view_to_region(nlocx, nlocy, clip=False) m2x, m2y = bpy.context.region.view2d.view_to_region(nlocx, nlocy - ndimy, clip=False) - m1y = max(m1y, bottom_bar) - m2y = max(m2y, bottom_bar) if m1x < area_width and m2x < area_width: - bgl.glVertex2f(m2x-radius,m2y) # draw order is important, start with bottom left and go anti-clockwise - bgl.glVertex2f(m2x,m2y) - bgl.glVertex2f(m1x,m1y) - bgl.glVertex2f(m1x-radius,m1y) - bgl.glEnd() + vertices.extend([(m2x-radius,m2y), (m2x,m2y), + (m1x,m1y), (m1x-radius,m1y)]) + indices.extend([(id_last, id_last+1, id_last+3), + (id_last+3, id_last+1, id_last+2)]) + id_last += 4 # Top edge - bgl.glBegin(bgl.GL_QUADS) m1x, m1y = bpy.context.region.view2d.view_to_region(nlocx, nlocy, clip=False) m2x, m2y = bpy.context.region.view2d.view_to_region(nlocx + ndimx, nlocy, clip=False) m1x = min(m1x, area_width) m2x = min(m2x, area_width) if m1y > bottom_bar and m2y > bottom_bar: - bgl.glVertex2f(m1x,m2y) # draw order is important, start with bottom left and go anti-clockwise - bgl.glVertex2f(m2x,m2y) - bgl.glVertex2f(m2x,m1y+radius) - bgl.glVertex2f(m1x,m1y+radius) - bgl.glEnd() + vertices.extend([(m1x,m1y), (m2x,m1y), + (m2x,m1y+radius), (m1x,m1y+radius)]) + indices.extend([(id_last, id_last+1, id_last+3), + (id_last+3, id_last+1, id_last+2)]) + id_last += 4 # Right edge - bgl.glBegin(bgl.GL_QUADS) m1x, m1y = bpy.context.region.view2d.view_to_region(nlocx + ndimx, nlocy, clip=False) m2x, m2y = bpy.context.region.view2d.view_to_region(nlocx + ndimx, nlocy - ndimy, clip=False) m1y = max(m1y, bottom_bar) m2y = max(m2y, bottom_bar) if m1x < area_width and m2x < area_width: - bgl.glVertex2f(m2x,m2y) # draw order is important, start with bottom left and go anti-clockwise - bgl.glVertex2f(m2x+radius,m2y) - bgl.glVertex2f(m1x+radius,m1y) - bgl.glVertex2f(m1x,m1y) - bgl.glEnd() + vertices.extend([(m1x,m2y), (m1x+radius,m2y), + (m1x+radius,m1y), (m1x,m1y)]) + indices.extend([(id_last, id_last+1, id_last+3), + (id_last+3, id_last+1, id_last+2)]) + id_last += 4 # Bottom edge - bgl.glBegin(bgl.GL_QUADS) m1x, m1y = bpy.context.region.view2d.view_to_region(nlocx, nlocy-ndimy, clip=False) m2x, m2y = bpy.context.region.view2d.view_to_region(nlocx + ndimx, nlocy-ndimy, clip=False) m1x = min(m1x, area_width) m2x = min(m2x, area_width) if m1y > bottom_bar and m2y > bottom_bar: - bgl.glVertex2f(m1x,m2y) # draw order is important, start with bottom left and go anti-clockwise - bgl.glVertex2f(m2x,m2y) - bgl.glVertex2f(m2x,m1y-radius) - bgl.glVertex2f(m1x,m1y-radius) - bgl.glEnd() - - - # Restore defaults - bgl.glDisable(bgl.GL_BLEND) - bgl.glDisable(bgl.GL_LINE_SMOOTH) - + vertices.extend([(m1x,m2y), (m2x,m2y), + (m2x,m1y-radius), (m1x,m1y-radius)]) + indices.extend([(id_last, id_last+1, id_last+3), + (id_last+3, id_last+1, id_last+2)]) + + # now draw all edges in one batch + if len(vertices) != 0: + batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices) + shader.bind() + shader.uniform_float("color", colour) + batch.draw(shader) def draw_callback_nodeoutline(self, context, mode): if self.mouse_path: - nodes, links = get_nodes_links(context) + + bgl.glLineWidth(1) + bgl.glEnable(bgl.GL_BLEND) bgl.glEnable(bgl.GL_LINE_SMOOTH) + bgl.glHint(bgl.GL_LINE_SMOOTH_HINT, bgl.GL_NICEST) + + nodes, links = get_nodes_links(context) + + shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') if mode == "LINK": - col_outer = [1.0, 0.2, 0.2, 0.4] - col_inner = [0.0, 0.0, 0.0, 0.5] - col_circle_inner = [0.3, 0.05, 0.05, 1.0] + col_outer = (1.0, 0.2, 0.2, 0.4) + col_inner = (0.0, 0.0, 0.0, 0.5) + col_circle_inner = (0.3, 0.05, 0.05, 1.0) elif mode == "LINKMENU": - col_outer = [0.4, 0.6, 1.0, 0.4] - col_inner = [0.0, 0.0, 0.0, 0.5] - col_circle_inner = [0.08, 0.15, .3, 1.0] + col_outer = (0.4, 0.6, 1.0, 0.4) + col_inner = (0.0, 0.0, 0.0, 0.5) + col_circle_inner = (0.08, 0.15, .3, 1.0) elif mode == "MIX": - col_outer = [0.2, 1.0, 0.2, 0.4] - col_inner = [0.0, 0.0, 0.0, 0.5] - col_circle_inner = [0.05, 0.3, 0.05, 1.0] + col_outer = (0.2, 1.0, 0.2, 0.4) + col_inner = (0.0, 0.0, 0.0, 0.5) + col_circle_inner = (0.05, 0.3, 0.05, 1.0) m1x = self.mouse_path[0][0] m1y = self.mouse_path[0][1] @@ -954,34 +956,29 @@ def draw_callback_nodeoutline(self, context, mode): n2 = nodes[context.scene.NWLazyTarget] if n1 == n2: - col_outer = [0.4, 0.4, 0.4, 0.4] - col_inner = [0.0, 0.0, 0.0, 0.5] - col_circle_inner = [0.2, 0.2, 0.2, 1.0] + col_outer = (0.4, 0.4, 0.4, 0.4) + col_inner = (0.0, 0.0, 0.0, 0.5) + col_circle_inner = (0.2, 0.2, 0.2, 1.0) - draw_rounded_node_border(n1, radius=6, colour=col_outer) # outline - draw_rounded_node_border(n1, radius=5, colour=col_inner) # inner - draw_rounded_node_border(n2, radius=6, colour=col_outer) # outline - draw_rounded_node_border(n2, radius=5, colour=col_inner) # inner + draw_rounded_node_border(shader, n1, radius=6, colour=col_outer) # outline + draw_rounded_node_border(shader, n1, radius=5, colour=col_inner) # inner + draw_rounded_node_border(shader, n2, radius=6, colour=col_outer) # outline + draw_rounded_node_border(shader, n2, radius=5, colour=col_inner) # inner draw_line(m1x, m1y, m2x, m2y, 5, col_outer) # line outline draw_line(m1x, m1y, m2x, m2y, 2, col_inner) # line inner # circle outline - draw_circle(m1x, m1y, 7, col_outer) - draw_circle(m2x, m2y, 7, col_outer) + draw_circle_2d_filled(shader, m1x, m1y, 7, col_outer) + draw_circle_2d_filled(shader, m2x, m2y, 7, col_outer) # circle inner - draw_circle(m1x, m1y, 5, col_circle_inner) - draw_circle(m2x, m2y, 5, col_circle_inner) + draw_circle_2d_filled(shader, m1x, m1y, 5, col_circle_inner) + draw_circle_2d_filled(shader, m2x, m2y, 5, col_circle_inner) - # restore opengl defaults - bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) - bgl.glColor4f(0.0, 0.0, 0.0, 1.0) - bgl.glDisable(bgl.GL_LINE_SMOOTH) - def get_nodes_links(context): tree = context.space_data.node_tree -- GitLab