diff --git a/src/bonsai/bonsai/bim/data/pset/Psets_BBIM_Annotation.ifc b/src/bonsai/bonsai/bim/data/pset/Psets_BBIM_Annotation.ifc index ee149d83c6..062579edb2 100644 --- a/src/bonsai/bonsai/bim/data/pset/Psets_BBIM_Annotation.ifc +++ b/src/bonsai/bonsai/bim/data/pset/Psets_BBIM_Annotation.ifc @@ -28,7 +28,7 @@ DATA; #21=IFCSIMPLEPROPERTYTEMPLATE('1UDakJ5_f7kBhggNSW4$h5',$,'SymbolsPath','Default symbols SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.); #22=IFCSIMPLEPROPERTYTEMPLATE('0d53LEtgLDQxnv__NfgH7i',$,'PatternsPath','Default patterns SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.); #23=IFCSIMPLEPROPERTYTEMPLATE('26qFNMv7nCHgU6Jd7Anga5',$,'ShadingStylesPath','Default shading styles',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.); -#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation/DIMENSION,IfcAnnotation/RADIUS,IfcAnnotation/DIAMETER,IfcTypeProduct',(#25,#26,#35,#27,#28,#30,#34)); +#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation/DIMENSION,IfcAnnotation/RADIUS,IfcAnnotation/DIAMETER,IfcTypeProduct',(#25,#26,#35,#36,#27,#28,#30,#34)); #25=IFCSIMPLEPROPERTYTEMPLATE('1rL2AbQsXD8RbpoWH5pYOV',$,'ShowDescriptionOnly','Hide the measurement values and show only annotation description',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); #26=IFCSIMPLEPROPERTYTEMPLATE('0SVyOfB0rC2xNfdRYf3XvY',$,'SuppressZeroInches','Suppress 0 inch values in dimension annotation text (for example: 12'' - 0" -> 12'')',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); #27=IFCSIMPLEPROPERTYTEMPLATE('2bUmj458PBqPAtUoI3MXsb',$,'TextPrefix','Text to add before annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.); @@ -39,6 +39,7 @@ DATA; #32=IFCSIMPLEPROPERTYTEMPLATE('0gjJzDYBX8P85qn1xcAOOo',$,'Reverse_List','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); #34=IFCSIMPLEPROPERTYTEMPLATE('1Kx4Pm9nR8vBwZqTs2uYeL',$,'Separator','Characters placed between multiple dimension values when CustomUnit has more than one unit selected (default: '' / '')',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.); #35=IFCSIMPLEPROPERTYTEMPLATE('3Nf6Qs1mT0pWxBuCvDyEzA',$,'SuppressZeroFeet','Suppress 0 feet in dimension annotation text (for example: 0'' - 3 1/2" -> 3 1/2")',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); +#36=IFCSIMPLEPROPERTYTEMPLATE('2Rg7Hn5jK4mLpNqOsVwXtY',$,'IsOrdinate','Show accumulated distance from the first vertex instead of individual segment lengths',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); #33=IFCSIMPLEPROPERTYTEMPLATE('22TrcxF8jFNB4buSmzjGEF',$,'List_Separator','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); ENDSEC; END-ISO-10303-21; diff --git a/src/bonsai/bonsai/bim/module/drawing/data.py b/src/bonsai/bonsai/bim/module/drawing/data.py index d32adafe94..f47527dd8a 100644 --- a/src/bonsai/bonsai/bim/module/drawing/data.py +++ b/src/bonsai/bonsai/bim/module/drawing/data.py @@ -800,6 +800,7 @@ class DecoratorData: show_description_only = pset_data.get("ShowDescriptionOnly", False) suppress_zero_inches = pset_data.get("SuppressZeroInches", False) suppress_zero_feet = pset_data.get("SuppressZeroFeet", False) + is_ordinate = pset_data.get("IsOrdinate", False) text_prefix = pset_data.get("TextPrefix", None) or "" text_suffix = pset_data.get("TextSuffix", None) or "" custom_units = list(pset_data.get("CustomUnit", None) or []) @@ -810,6 +811,7 @@ class DecoratorData: "show_description_only": show_description_only, "suppress_zero_inches": suppress_zero_inches, "suppress_zero_feet": suppress_zero_feet, + "is_ordinate": is_ordinate, "text_prefix": text_prefix, "text_suffix": text_suffix, "fill_bg": fill_bg, diff --git a/src/bonsai/bonsai/bim/module/drawing/decoration.py b/src/bonsai/bonsai/bim/module/drawing/decoration.py index 74b04198c0..2e69fb8023 100644 --- a/src/bonsai/bonsai/bim/module/drawing/decoration.py +++ b/src/bonsai/bonsai/bim/module/drawing/decoration.py @@ -723,11 +723,13 @@ class DimensionDecorator(BaseDecorator): if not dimension_data: return show_description_only = dimension_data["show_description_only"] + is_ordinate = dimension_data["is_ordinate"] text_prefix = dimension_data["text_prefix"] text_suffix = dimension_data["text_suffix"] viewportDrawingScale = self.get_viewport_drawing_scale(context) text_offset_value = viewportDrawingScale * 3 + ordinate_total = 0.0 for i0, i1 in indices: v0 = Vector(vertices[i0]) v1 = Vector(vertices[i1]) @@ -746,10 +748,13 @@ class DimensionDecorator(BaseDecorator): "multiline": True, "text_dir": text_dir, } - base_pos = p0 + text_dir * 0.5 + base_pos = p1 if is_ordinate else p0 + text_dir * 0.5 if not show_description_only: - length = (v1 - v0).length + segment_length = (v1 - v0).length + if is_ordinate: + ordinate_total += segment_length + length = ordinate_total if is_ordinate else segment_length units_to_format = dimension_data["custom_units"] if dimension_data["custom_units"] else [None] parts = [ self.format_value( @@ -772,15 +777,18 @@ class DimensionDecorator(BaseDecorator): self.draw_label( text=text, - pos=base_pos + text_offset, - box_alignment="bottom-middle", + pos=base_pos + text_offset + (Vector((0, text_offset_value)) if is_ordinate else Vector((0, 0))), + box_alignment="bottom-right" if is_ordinate else "bottom-middle", multiline_to_bottom=False, **common_label_attrs, ) if not show_description_only and description: self.draw_label( - text=description, pos=base_pos - text_offset, box_alignment="top-middle", **common_label_attrs + text=description, + pos=base_pos - text_offset + (Vector((0, text_offset_value)) if is_ordinate else Vector((0, 0))), + box_alignment="top-right" if is_ordinate else "top-middle", + **common_label_attrs, ) diff --git a/src/bonsai/bonsai/bim/module/drawing/svgwriter.py b/src/bonsai/bonsai/bim/module/drawing/svgwriter.py index 2145039410..1e1ac6f51a 100644 --- a/src/bonsai/bonsai/bim/module/drawing/svgwriter.py +++ b/src/bonsai/bonsai/bim/module/drawing/svgwriter.py @@ -1521,11 +1521,15 @@ class SvgWriter: dimension_data = DecoratorData.get_dimension_data(obj) assert isinstance(obj.data, bpy.types.Curve) + is_ordinate = dimension_data["is_ordinate"] for spline in obj.data.splines: points = self.get_spline_points(spline) + ordinate_total = 0.0 for i in range(len(points) - 1): v0_global = matrix_world @ points[i].co.xyz v1_global = matrix_world @ points[i + 1].co.xyz + if is_ordinate: + ordinate_total += (v1_global - v0_global).length self.draw_dimension_annotation( v0_global, v1_global, @@ -1539,6 +1543,7 @@ class SvgWriter: fill_bg=dimension_data["fill_bg"], custom_units=dimension_data["custom_units"], separator=dimension_data["separator"], + distance_override=ordinate_total if is_ordinate else None, ) def draw_measureit_arch_dimension_annotations(self) -> None: @@ -1568,6 +1573,7 @@ class SvgWriter: fill_bg=False, custom_units=None, separator=" / ", + distance_override=None, ) -> None: offset = Vector([self.raw_width, self.raw_height]) / 2 v0 = self.project_point_onto_camera(v0_global) @@ -1580,7 +1586,10 @@ class SvgWriter: sheet_dimension = (end - start).length # if annotation can't fit offset text to the right of marker - text_position = mid if sheet_dimension > 5 else (end + (3 * vector.normalized())) + if distance_override is not None: + text_position = end + else: + text_position = mid if sheet_dimension > 5 else (end + (3 * vector.normalized())) angle = math.degrees(vector.angle_signed(Vector((1, 0)))) line = self.svg.line(start=start, end=end, class_=" ".join(classes)) @@ -1595,7 +1604,7 @@ class SvgWriter: } if not show_description_only: - dimension = (v1_global - v0_global).length + dimension = distance_override if distance_override is not None else (v1_global - v0_global).length units_to_format = custom_units if custom_units else [None] parts = [ helper.format_distance( @@ -1616,8 +1625,8 @@ class SvgWriter: text_tags += self.create_text_tag( text, - text_position + perpendicular, - box_alignment="bottom-middle", + text_position + perpendicular + (Vector((0, 1.5)) if distance_override is not None else Vector((0, 0))), + box_alignment="bottom-right" if distance_override is not None else "bottom-middle", multiline_to_bottom=False, **text_tag_kwargs, ) @@ -1625,8 +1634,8 @@ class SvgWriter: if not show_description_only and dimension_text: text_tags += self.create_text_tag( dimension_text, - text_position - perpendicular, - box_alignment="top-middle", + text_position - perpendicular + (Vector((0, 1.5)) if distance_override is not None else Vector((0, 0))), + box_alignment="top-right" if distance_override is not None else "top-middle", multiline_to_bottom=True, **text_tag_kwargs, )