diff --git a/src/blenderbim/blenderbim/bim/module/drawing/data.py b/src/blenderbim/blenderbim/bim/module/drawing/data.py index 5c707531ed..3aeebc46ce 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/data.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/data.py @@ -287,15 +287,18 @@ class DecoratorData: cls.data[obj.name] = text_data return text_data - # used by Ifc Annotations with ObjectType = "DIMENSION" / "DIAMETER" @classmethod def get_dimension_data(cls, obj): + """used by Ifc Annotations with ObjectType: + + DIMENSION / DIAMETER / SECTION_LEVEL / PLAN_LEVEL + """ result = cls.data.get(obj.name, None) if result is not None: return result element = tool.Ifc.get_entity(obj) - supported_object_types = ("DIMENSION", "DIAMETER", "SECTION_LEVEL") + supported_object_types = ("DIMENSION", "DIAMETER", "SECTION_LEVEL", "PLAN_LEVEL") if not element or not element.is_a("IfcAnnotation") or element.ObjectType not in supported_object_types: return None diff --git a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py index df562e3116..d63fedd051 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py @@ -1054,23 +1054,51 @@ class PlanLevelDecorator(BaseDecorator): unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) region = context.region region3d = context.region_data + + element = tool.Ifc.get_entity(obj) + description = element.Description + dimension_data = DecoratorData.get_dimension_data(obj) + show_description_only = dimension_data["show_description_only"] + text_prefix = dimension_data["text_prefix"] + text_suffix = dimension_data["text_suffix"] + for verts in splines: p0, p1 = [location_3d_to_region_2d(region, region3d, v) for v in verts[:2]] - dir = p1 - p0 - if dir.length < 1: + text_dir = p1 - p0 + if text_dir.length < 1: continue - if dir.x > 0: + if text_dir.x > 0: box_alignment = "bottom-left" else: box_alignment = "bottom-right" - dir *= -1 + text_dir *= -1 - z = verts[0].z / unit_scale - z = ifcopenshell.util.geolocation.auto_z2e(tool.Ifc.get(), z) - z *= unit_scale - text = "RL " + self.format_value(context, z) - self.draw_label(context, text, p0, dir, gap=8, center=False, box_alignment=box_alignment) + line_number_start = 0 + if not show_description_only: + z = verts[0].z / unit_scale + z = ifcopenshell.util.geolocation.auto_z2e(tool.Ifc.get(), z) + z *= unit_scale + text = "RL " + self.format_value(context, z) + full_prefix = ((description + "\\n") if description else "") + text_prefix + text = full_prefix + text + text_suffix + line_number_start -= full_prefix.count("\\n") + else: + if not description: + break + text = description + + self.draw_label( + context, + text=text, + pos=p0, + text_dir=text_dir, + box_alignment=box_alignment, + line_no=line_number_start, + multiline=True, + gap=8, + center=False, + ) class SectionLevelDecorator(BaseDecorator): @@ -1129,17 +1157,11 @@ class SectionLevelDecorator(BaseDecorator): text_suffix = dimension_data["text_suffix"] for verts in splines: - z = verts[0].z / unit_scale - z = ifcopenshell.util.geolocation.auto_z2e(tool.Ifc.get(), z) - z *= unit_scale - - common_label_attrs = { - "context": context, - "multiline": True, - "text_dir": text_dir, - } line_number_start = 0 if not show_description_only: + z = verts[0].z / unit_scale + z = ifcopenshell.util.geolocation.auto_z2e(tool.Ifc.get(), z) + z *= unit_scale text = "RL " + self.format_value(context, z) full_prefix = ((tag + "\\n") if tag else "") + text_prefix text = full_prefix + text + text_suffix @@ -1150,11 +1172,13 @@ class SectionLevelDecorator(BaseDecorator): text = tag self.draw_label( + context, text=text, pos=text_position, + text_dir=text_dir, box_alignment="bottom-left", line_no=line_number_start, - **common_label_attrs, + multiline=True, ) break # support only 1 label diff --git a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py index cf4b9c96f9..deda031164 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py @@ -241,6 +241,7 @@ class SvgWriter: d = "M{}".format(d[1:]) path = self.svg.add(self.svg.path(d=d, class_=" ".join(classes))) text_position = projected_points_svg[0] - Vector((0, base_offset_y)) + # TODO: allow metric to be configurable rl_value = (matrix_world @ points[0].co.xyz).z if bpy.context.scene.unit_settings.system == "IMPERIAL": @@ -873,27 +874,28 @@ class SvgWriter: path = self.svg.add(self.svg.path(d=d, class_=" ".join(classes))) def draw_plan_level_annotation(self, obj): - x_offset = self.raw_width / 2 - y_offset = self.raw_height / 2 + offset = Vector([self.raw_width, self.raw_height]) / 2 matrix_world = obj.matrix_world classes = self.get_attribute_classes(obj) + + element = tool.Ifc.get_entity(obj) + description = element.Description + + dimension_data = DecoratorData.get_dimension_data(obj) + prefix = dimension_data["text_prefix"] + suffix = dimension_data["text_suffix"] + show_description_only = dimension_data["show_description_only"] + base_offset_y = 1.0 + 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.svg_scale, (y_offset - p.y) * self.svg_scale) - for p in projected_points - ] - ) + projected_points_svg = [(offset + p.xy * Vector((1, -1))) * self.svg_scale for p in projected_points] + d = " ".join(["L {} {}".format(*p) for p in projected_points_svg]) d = "M{}".format(d[1:]) path = self.svg.add(self.svg.path(d=d, class_=" ".join(classes))) - text_position = Vector( - ( - (x_offset + projected_points[0].x) * self.svg_scale, - ((y_offset - projected_points[0].y) * self.svg_scale) - 1.0, - ) - ) + text_position = projected_points_svg[0] - Vector((0, base_offset_y)) + # TODO: allow metric to be configurable rl_value = (matrix_world @ points[0].co).z if bpy.context.scene.unit_settings.system == "IMPERIAL": @@ -905,17 +907,31 @@ class SvgWriter: rl *= unit_scale rl = "{:.3f}m".format(rl) + text_tags = [] box_alignment = "bottom-left" if projected_points[0].x <= projected_points[-1].x else "bottom-right" - text_style = SvgWriter.get_box_alignment_parameters(box_alignment) - self.svg.add( - self.svg.text( - "{}{}".format("" if rl_value < 0 else "+", rl), - insert=tuple(text_position), - class_="PLANLEVEL", - **text_style, - ) + line_number_start = 0 + + if not show_description_only: + text = "{}{}".format("" if rl_value < 0 else "+", rl) + full_prefix = ((description + "\\n") if description else "") + prefix + text = full_prefix + text + suffix + line_number_start -= full_prefix.count("\\n") + else: + if not description: + continue + text = description + + text_tags += self.create_text_tag( + text, + text_position, + class_str="PLANLEVEL", + line_number_start=line_number_start, + box_alignment=box_alignment, ) + for text in text_tags: + self.svg.add(text) + def draw_angle_annotations(self, obj): points = obj.data.splines[0].points region = bpy.context.region