From 02b01b2a44c9ed8432faf420edd5f1aa424d97a2 Mon Sep 17 00:00:00 2001 From: QwiglyDee Date: Wed, 6 Jan 2021 03:52:40 +0700 Subject: [PATCH] refectored decorations. fixed #1241 somehow --- .../blenderbim/bim/decoration.py | 259 +++++++++--------- src/ifcblenderexport/blenderbim/bim/prop.py | 9 +- 2 files changed, 131 insertions(+), 137 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/decoration.py b/src/ifcblenderexport/blenderbim/bim/decoration.py index 7267a5e96a..b52a3b18db 100644 --- a/src/ifcblenderexport/blenderbim/bim/decoration.py +++ b/src/ifcblenderexport/blenderbim/bim/decoration.py @@ -21,7 +21,6 @@ class BaseDecorator(): DEF_GLSL = """ #define PI 3.141592653589793 - #define COLOR vec4({color[0]}, {color[1]}, {color[2]}, {color[3]}) #define MAX_POINTS 64 #define CIRCLE_SEGS 24 """ @@ -99,63 +98,28 @@ class BaseDecorator(): """ FRAG_GLSL = """ + uniform vec4 color; out vec4 fragColor; void main() { - fragColor = COLOR; + fragColor = color; } """ - # class var for single handler - installed = None - - @classmethod - def install(cls, *args, **kwargs): - if cls.installed: - cls.uninstall() - handler = cls(*args, **kwargs) - cls.installed = SpaceView3D.draw_handler_add(handler, (), 'WINDOW', 'POST_PIXEL') - - @classmethod - def uninstall(cls): - try: - SpaceView3D.draw_handler_remove(cls.installed, 'WINDOW') - except ValueError: - pass - cls.installed = None - - def __init__(self, props, context): - self.context = context - self.props = props - self.shader = self.create_shader() - self.font_id = 0 - self.font_size = 16 - self.dpi = context.preferences.system.dpi - - def create_shader(self): - defines = self.DEF_GLSL.format(color=self.props.decorations_colour) + def __init__(self): # NB: libcode param doesn't work - return GPUShader(vertexcode=self.VERT_GLSL, - fragcode=self.FRAG_GLSL, - geocode=self.LIB_GLSL + self.GEOM_GLSL, - defines=defines) + self.shader = GPUShader(vertexcode=self.VERT_GLSL, + fragcode=self.FRAG_GLSL, + geocode=self.LIB_GLSL + self.GEOM_GLSL, + defines=self.DEF_GLSL) - def __call__(self): - if self.props.active_drawing_index is None or len(self.props.drawings) == 0: - return - - for obj in self.get_objects(): - self.decorate(obj) - - def get_objects(self): + def get_objects(self, collection): """find relevant objects using class.basename returns: iterable of blender objects """ - drawing = self.props.drawings[self.props.active_drawing_index] - collection = bpy.data.collections.get("IfcGroup/" + drawing.name) - return filter(lambda o: self.basename in o.name, collection.objects) + return filter(lambda o: self.basename in o.name, collection.all_objects) def get_path_geom(self, obj, topo=True): """Parses path geometry into line segments @@ -223,13 +187,14 @@ class BaseDecorator(): return vertices, indices - def decorate(self, object): + def decorate(self, context, object): """perform actuall drawing stuff""" raise NotImplementedError() - def draw_lines(self, obj, vertices, indices, topology=None): - region = self.context.region - region3d = self.context.region_data + def draw_lines(self, context, obj, vertices, indices, topology=None): + region = context.region + region3d = context.region_data + color = context.scene.DocProperties.decorations_colour fmt = GPUVertFormat() fmt.attr_add(id="pos", comp_type='F32', len=3, fetch_mode='FLOAT') @@ -245,18 +210,20 @@ class BaseDecorator(): batch = GPUBatch(type='LINES', buf=vbo, elem=ibo) - self.shader.bind() - self.shader.uniform_float - self.shader.uniform_float("viewMatrix", region3d.perspective_matrix) - self.shader.uniform_float("winsize", (region.width, region.height)) - bgl.glEnable(bgl.GL_LINE_SMOOTH) bgl.glHint(bgl.GL_LINE_SMOOTH_HINT, bgl.GL_NICEST) bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) + + self.shader.bind() + self.shader.uniform_float + self.shader.uniform_float("viewMatrix", region3d.perspective_matrix) + self.shader.uniform_float("winsize", (region.width, region.height)) + self.shader.uniform_float("color", color) + batch.draw(self.shader) - def draw_label(self, text, pos, dir, gap=4, center=True, vcenter=False): + def draw_label(self, context, text, pos, dir, gap=4, center=True, vcenter=False): """Draw text label Args: @@ -264,15 +231,21 @@ class BaseDecorator(): aligned and centered at segment middle """ + font_id = 0 + font_size = 16 + dpi = context.preferences.system.dpi + + color = context.scene.DocProperties.decorations_colour + ang = -Vector((1, 0)).angle_signed(dir) cos = math.cos(ang) sin = math.sin(ang) - blf.size(self.font_id, self.font_size, self.dpi) + blf.size(font_id, font_size, dpi) w, h = 0, 0 if center or vcenter: - w, h = blf.dimensions(self.font_id, text) + w, h = blf.dimensions(font_id, text) if center: # horizontal centering @@ -286,18 +259,18 @@ class BaseDecorator(): # side-shifting pos += Vector((-sin, cos)) * gap - blf.enable(self.font_id, blf.ROTATION) - blf.position(self.font_id, pos.x, pos.y, 0) + blf.enable(font_id, blf.ROTATION) + blf.position(font_id, pos.x, pos.y, 0) - blf.rotation(self.font_id, ang) - blf.color(self.font_id, *self.props.decorations_colour) - blf.draw(self.font_id, text) - blf.disable(self.font_id, blf.ROTATION) + blf.rotation(font_id, ang) + blf.color(font_id, *color) + blf.draw(font_id, text) + blf.disable(font_id, blf.ROTATION) - def format_value(self, value): - unit_system = bpy.context.scene.unit_settings.system + def format_value(self, context, value): + unit_system = context.scene.unit_settings.system if unit_system == 'IMPERIAL': - precision = bpy.context.scene.BIMProperties.imperial_precision + precision = context.scene.BIMProperties.imperial_precision if precision == "NONE": precision = 256 elif precision == "1": @@ -318,7 +291,6 @@ class DimensionDecorator(BaseDecorator): - puts metric text next to each segment """ basename = "IfcAnnotation/Dimension" - installed = None DEF_GLSL = BaseDecorator.DEF_GLSL + """ #define ARROW_ANGLE PI / 12.0 @@ -382,14 +354,14 @@ class DimensionDecorator(BaseDecorator): } """ - def decorate(self, obj): + def decorate(self, context, obj): verts, idxs, _ = self.get_path_geom(obj, topo=False) - self.draw_lines(obj, verts, idxs) - self.draw_labels(obj, verts, idxs) + self.draw_lines(context, obj, verts, idxs) + self.draw_labels(context, obj, verts, idxs) - def draw_labels(self, obj, vertices, indices): - region = self.context.region - region3d = self.context.region_data + def draw_labels(self, context, obj, vertices, indices): + region = context.region + region3d = context.region_data for i0, i1 in indices: v0 = Vector(vertices[i0]) v1 = Vector(vertices[i1]) @@ -399,8 +371,8 @@ class DimensionDecorator(BaseDecorator): if dir.length < 1: continue length = (v1 - v0).length - text = self.format_value(length) - self.draw_label(text, p0 + (dir) * .5, dir) + text = self.format_value(context, length) + self.draw_label(context, text, p0 + (dir) * .5, dir) class EqualityDecorator(DimensionDecorator): @@ -410,11 +382,10 @@ class EqualityDecorator(DimensionDecorator): - puts 'EQ' label """ basename = "IfcAnnotation/Equal" - installed = None - def draw_labels(self, obj, vertices, indices): - region = self.context.region - region3d = self.context.region_data + def draw_labels(self, context, obj, vertices, indices): + region = context.region + region3d = context.region_data for i0, i1 in indices: v0 = Vector(vertices[i0]) v1 = Vector(vertices[i1]) @@ -423,7 +394,7 @@ class EqualityDecorator(DimensionDecorator): dir = p1 - p0 if dir.length < 1: continue - self.draw_label("EQ", p0 + (dir) * .5, dir) + self.draw_label(context, "EQ", p0 + (dir) * .5, dir) class LeaderDecorator(BaseDecorator): @@ -432,7 +403,6 @@ class LeaderDecorator(BaseDecorator): - middle points w/out decorations """ basename = "IfcAnnotation/Leader" - installed = None DEF_GLSL = BaseDecorator.DEF_GLSL + """ #define ARROW_ANGLE PI / 12.0 @@ -489,9 +459,9 @@ class LeaderDecorator(BaseDecorator): } """ - def decorate(self, obj): + def decorate(self, context, obj): verts, idxs, topo = self.get_path_geom(obj) - self.draw_lines(obj, verts, idxs, topo) + self.draw_lines(context, obj, verts, idxs, topo) class StairDecorator(BaseDecorator): @@ -501,7 +471,6 @@ class StairDecorator(BaseDecorator): - middle points w/out decorations """ basename = "IfcAnnotation/Stair" - installed = None DEF_GLSL = BaseDecorator.DEF_GLSL + """ #define CIRCLE_SIZE 8.0 @@ -575,14 +544,13 @@ class StairDecorator(BaseDecorator): } """ - def decorate(self, obj): + def decorate(self, context, obj): verts, idxs, topo = self.get_path_geom(obj) - self.draw_lines(obj, verts, idxs, topo) + self.draw_lines(context, obj, verts, idxs, topo) class HiddenDecorator(BaseDecorator): basename = "IfcAnnotation/Hidden" - installed = None DEF_GLSL = BaseDecorator.DEF_GLSL + """ #define DASH_SIZE 16.0 @@ -624,6 +592,7 @@ class HiddenDecorator(BaseDecorator): """ FRAG_GLSL = """ + uniform vec4 color; in vec2 gl_FragCoord; in float dist; out vec4 fragColor; @@ -631,21 +600,20 @@ class HiddenDecorator(BaseDecorator): void main() { uint bit = uint(fract(dist / DASH_SIZE) * 32); if ((DASH_PATTERN & (1U<