From 0fe32c0c75ac1b9cafcbdb12e30165491763ada1 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 25 Apr 2022 09:53:49 +1000 Subject: [PATCH] #1153 Add support for radius annotations --- .../blenderbim/bim/data/styles/default.css | 1 + .../blenderbim/bim/data/templates/markers.svg | 5 + .../bim/module/drawing/decoration.py | 95 ++++++++++++++++++- .../blenderbim/bim/module/drawing/prop.py | 13 --- .../bim/module/drawing/svgwriter.py | 41 ++++++++ .../blenderbim/bim/module/drawing/ui.py | 20 ++-- src/blenderbim/blenderbim/tool/drawing.py | 1 + 7 files changed, 153 insertions(+), 23 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/data/styles/default.css b/src/blenderbim/blenderbim/bim/data/styles/default.css index 888e167c27..b89ee77859 100644 --- a/src/blenderbim/blenderbim/bim/data/styles/default.css +++ b/src/blenderbim/blenderbim/bim/data/styles/default.css @@ -31,6 +31,7 @@ text { fill: black; stroke: none; } .PredefinedType-SECTIONLEVEL { marker-start: url(#section-level-marker); stroke-dasharray: 12.5, 3, 3, 3; } .PredefinedType-PLANLEVEL { marker-end: url(#plan-level-marker); } .PredefinedType-DIMENSION { marker-start: url(#dimension-marker-start); marker-end: url(#dimension-marker-end); } +.PredefinedType-RADIUS { marker-end: url(#radius-marker-end); } .PredefinedType-HIDDENLINE { stroke-dasharray: 3, 2; } .PredefinedType-STAIR { marker-start: url(#stair-marker-start); marker-end: url(#stair-marker-end); } .PredefinedType-BOUNDARY { fill: none; stroke: red; stroke-width: 1; stroke-dasharray: 12, 4, 3, 4, 3, 4; } diff --git a/src/blenderbim/blenderbim/bim/data/templates/markers.svg b/src/blenderbim/blenderbim/bim/data/templates/markers.svg index a2bfacc79f..ed34d6687a 100644 --- a/src/blenderbim/blenderbim/bim/data/templates/markers.svg +++ b/src/blenderbim/blenderbim/bim/data/templates/markers.svg @@ -16,6 +16,11 @@ + + + + + diff --git a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py index 7f9af997a5..f177bfe493 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py @@ -590,6 +590,98 @@ class LeaderDecorator(BaseDecorator): self.draw_label(context, obj.BIMTextProperties.value, pos, dir, gap=0, center=False, vcenter=False) +class RadiusDecorator(BaseDecorator): + """Decorating text with arrows + - head point with arrow + """ + + objecttype = "RADIUS" + + DEF_GLSL = ( + BaseDecorator.DEF_GLSL + + """ + #define ARROW_ANGLE PI / 12.0 + #define ARROW_SIZE 16.0 + """ + ) + + GEOM_GLSL = """ + uniform vec2 winsize; + uniform float viewportDrawingScale; + + layout(lines) in; + layout(line_strip, max_vertices=MAX_POINTS) out; + in uint type[]; + + void main() { + vec4 clip2win = matCLIP2WIN(); + vec4 win2clip = matWIN2CLIP(); + + vec4 p0 = gl_in[0].gl_Position, p1 = gl_in[1].gl_Position; + uint t0 = type[0], t1 = type[1]; + + vec4 p0w = CLIP2WIN(p0), p1w = CLIP2WIN(p1); + vec4 edge = p1w - p0w, dir = normalize(edge); + vec4 gap1 = vec4(0); + + vec4 p; + + // end edge arrow for last segment + if (t1 == 2u) { + vec4 head[3]; + arrow_head(dir, viewportDrawingScale * ARROW_SIZE, ARROW_ANGLE, head); + + gl_Position = p1; + EmitVertex(); + p = p1w - head[1]; + gl_Position = WIN2CLIP(p); + EmitVertex(); + p = p1w - head[2]; + gl_Position = WIN2CLIP(p); + EmitVertex(); + gl_Position = p1; + EmitVertex(); + EndPrimitive(); + + gap1 = dir * viewportDrawingScale * ARROW_SIZE; + } + + // stem, adjusted for and arrow + gl_Position = p0; + EmitVertex(); + p = p1w - gap1; + gl_Position = WIN2CLIP(p); + EmitVertex(); + EndPrimitive(); + } + """ + + def get_spline_end(self, obj): + spline = obj.data.splines[0] + spline_points = spline.bezier_points if spline.bezier_points else spline.points + if not spline_points: + return Vector((0, 0, 0)) + return obj.matrix_world @ spline_points[0].co + + def decorate(self, context, obj): + verts, idxs, topo = self.get_path_geom(obj) + self.draw_lines(context, obj, verts, idxs, topo) + self.draw_labels(context, obj) + + def draw_labels(self, context, obj): + region = context.region + region3d = context.region_data + dir = Vector((1, 0)) + pos = location_3d_to_region_2d(region, region3d, self.get_spline_end(obj)) + + spline = obj.data.splines[0] + spline_points = spline.bezier_points if spline.bezier_points else spline.points + if spline_points: + length = (spline_points[-1].co - spline_points[-2].co).length + text = self.format_value(context, length) + self.draw_label(context, text, pos, dir, gap=0, center=False, vcenter=False) + + class StairDecorator(BaseDecorator): """Decorating stairs - head point with arrow @@ -997,7 +1089,7 @@ class SectionLevelDecorator(LevelDecorator): class BreakDecorator(BaseDecorator): - """Decorator for dimension objects + """Decorator for breakline objects - first edge of a mesh with zigzag thingy in the middle Uses first two vertices in verts list. @@ -1517,6 +1609,7 @@ class DecorationsHandler: GridDecorator, HiddenDecorator, LeaderDecorator, + RadiusDecorator, MiscDecorator, PlanLevelDecorator, SectionLevelDecorator, diff --git a/src/blenderbim/blenderbim/bim/module/drawing/prop.py b/src/blenderbim/blenderbim/bim/module/drawing/prop.py index 3502bd5808..13716fce9b 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/prop.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/prop.py @@ -351,19 +351,6 @@ class BIMCameraProperties(PropertyGroup): raster_x: IntProperty(name="Raster X", default=1000) raster_y: IntProperty(name="Raster Y", default=1000) is_nts: BoolProperty(name="Is NTS") - cut_objects: EnumProperty( - items=[ - ( - ".IfcWall|.IfcSlab|.IfcCurtainWall|.IfcStair|.IfcStairFlight|.IfcColumn|.IfcBeam|.IfcMember|.IfcCovering|.IfcSpace", - "Overall Plan / Section", - "", - ), - (".IfcElement", "Detail Drawing", ""), - ("CUSTOM", "Custom", ""), - ], - name="Cut Objects", - ) - cut_objects_custom: StringProperty(name="Custom Cut") active_drawing_style_index: IntProperty(name="Active Drawing Style Index") # For now, this JSON dump are all the parameters that determine a camera's "Block representation" diff --git a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py index 9b345fad62..7411fd9ab9 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py @@ -155,6 +155,8 @@ class SvgWriter: self.draw_dimension_annotations(obj, text_override="EQ") elif element.ObjectType == "DIMENSION": self.draw_dimension_annotations(obj) + elif element.ObjectType == "RADIUS": + self.draw_radius_annotations(obj) elif element.ObjectType == "ELEVATION": self.draw_elevation_annotation(obj) elif element.ObjectType == "SECTION": @@ -622,6 +624,45 @@ class SvgWriter: ) ) + def draw_radius_annotations(self, obj): + x_offset = self.raw_width / 2 + y_offset = self.raw_height / 2 + classes = self.get_attribute_classes(obj) + element = tool.Ifc.get_entity(obj) + matrix_world = obj.matrix_world + for spline in obj.data.splines: + points = self.get_spline_points(spline) + projected_points = [self.project_point_onto_camera(matrix_world @ p.co.xyz) for p in points] + d = " ".join( + [ + "L {} {}".format((x_offset + p.x) * self.scale, (y_offset - p.y) * self.scale) + for p in projected_points + ] + ) + d = "M{}".format(d[1:]) + path = self.svg.add(self.svg.path(d=d, class_=" ".join(classes))) + + p0 = Vector(((x_offset + projected_points[0].x) * self.scale, (y_offset - projected_points[0].y) * self.scale)) + p1 = Vector(((x_offset + projected_points[1].x) * self.scale, (y_offset - projected_points[1].y) * self.scale)) + text_offset = (p0 - p1).xy.normalized() * 5 + text_position = projected_points[0] + text_position = Vector(((x_offset + text_position.x) * self.scale, (y_offset - text_position.y) * self.scale)) + text_position += text_offset + + text_style = { + "font-size": annotation.Annotator.get_svg_text_size(2.5), + "font-family": "OpenGost Type B TT", + "text-anchor": "middle", + "alignment-baseline": "middle", + "dominant-baseline": "middle", + } + + radius = ((matrix_world @ points[-1].co) - (matrix_world @ points[-2].co)).length + radius = helper.format_distance(radius) + tag = element.Description or f"R{radius}" + + self.svg.add(self.svg.text(tag, insert=tuple(text_position), **text_style)) + def draw_dimension_annotations(self, dimension_obj, text_override=None): classes = self.get_attribute_classes(dimension_obj) matrix_world = dimension_obj.matrix_world diff --git a/src/blenderbim/blenderbim/bim/module/drawing/ui.py b/src/blenderbim/blenderbim/bim/module/drawing/ui.py index 0f586766bc..30a5e77234 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/ui.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/ui.py @@ -65,12 +65,6 @@ class BIM_PT_camera(Panel): row = layout.row() row.operator("bim.resize_text") - row = layout.row() - row.prop(props, "cut_objects") - if props.cut_objects == "CUSTOM": - row = layout.row() - row.prop(props, "cut_objects_custom") - row = layout.row() row.prop(props, "raster_x") row = layout.row() @@ -326,11 +320,19 @@ class BIM_PT_annotation_utilities(Panel): self.props = context.scene.DocProperties row = layout.row(align=True) - op = row.operator("bim.add_annotation", text="Dim", icon="ARROW_LEFTRIGHT") + op = row.operator("bim.add_annotation", text="Dim", icon="FIXED_SIZE") op.object_type = "DIMENSION" op.data_type = "curve" - op = row.operator("bim.add_annotation", text="Dim (Eq)", icon="ARROW_LEFTRIGHT") - op.object_type = "EQUAL_DIMENSION" + op = row.operator("bim.add_annotation", text="Angle", icon="DRIVER_ROTATIONAL_DIFFERENCE") + op.object_type = "ANGLE" + op.data_type = "mesh" + + row = layout.row(align=True) + op = row.operator("bim.add_annotation", text="Radius", icon="FORWARD") + op.object_type = "RADIUS" + op.data_type = "curve" + op = row.operator("bim.add_annotation", text="Diameter", icon="ARROW_LEFTRIGHT") + op.object_type = "DIAMETER" op.data_type = "curve" row = layout.row(align=True) diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index 591ed2b766..5f5ac885c4 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -39,6 +39,7 @@ class Drawing(blenderbim.core.tool.Drawing): data_type = { "DIMENSION": "curve", "EQUAL_DIMENSION": "curve", + "RADIUS": "curve", "TEXT": "empty", "TEXT_LEADER": "curve", "STAIR_ARROW": "curve",