diff --git a/src/bonsai/bonsai/bim/module/drawing/sheeter.py b/src/bonsai/bonsai/bim/module/drawing/sheeter.py index df57b6efb5..b364f7f673 100644 --- a/src/bonsai/bonsai/bim/module/drawing/sheeter.py +++ b/src/bonsai/bonsai/bim/module/drawing/sheeter.py @@ -486,11 +486,29 @@ class SheetBuilder: data.update({"Sheet" + k: v for k, v in sheet.get_info().items()}) if not data["Name"]: data["Name"] = document.Name or "Unnamed" + if view.attrib.get("data-type") == "reference": + human_scale = self.get_scale_from_svg(os.path.join(self.layout_dir, path)) + if human_scale: + data["Scale"] = human_scale view.append(self.parse_embedded_svg(view_title, data)) for image in images: view.remove(image) + def get_scale_from_svg(self, svg_path: str) -> str: + try: + tree = ET.parse(svg_path) + root = tree.getroot() + for g in root.iter(f"{SVG}g"): + for cls in g.attrib.get("class", "").split(): + if cls.startswith("scale-"): + denominator = cls[6:] + if denominator.isdigit(): + return tool.Drawing.get_human_scale_from_scale_denominator(denominator) + except Exception: + pass + return "" + def get_href(self, element: ET.Element) -> str: return urllib.parse.unquote(element.attrib[f"{XLINK}href"]).replace("\\", "/") diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 86113b9c95..7cc7610e82 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -2227,6 +2227,63 @@ class Drawing(bonsai.core.tool.Drawing): pset = ifcopenshell.util.element.get_pset(drawing, "EPset_Drawing") or {} return "NTS" if pset.get("IsNTS", False) else pset.get("HumanScale", "NTS") + @classmethod + def get_human_scale_from_scale_denominator(cls, denominator: str) -> str: + """Return the human-readable scale string for a scale CSS class denominator. + + E.g. denominator '4' returns '3"=1\'-0"' (imperial) or '' if not found. + """ + IMPERIAL_SCALES = { + "1": "1'=1'-0\"", + "2": '6"=1\'-0"', + "4": '3"=1\'-0"', + "8": '1-1/2"=1\'-0"', + "12": '1"=1\'-0"', + "16": '3/4"=1\'-0"', + "24": '1/2"=1\'-0"', + "32": '3/8"=1\'-0"', + "48": '1/4"=1\'-0"', + "64": '3/16"=1\'-0"', + "96": '1/8"=1\'-0"', + "128": '3/32"=1\'-0"', + "192": '1/16"=1\'-0"', + "384": '1/32"=1\'-0"', + "768": '1/64"=1\'-0"', + "1536": '1/128"=1\'-0"', + "120": "1\"=10'", + "240": "1\"=20'", + "360": "1\"=30'", + "480": "1\"=40'", + "600": "1\"=50'", + "720": "1\"=60'", + "840": "1\"=70'", + "960": "1\"=80'", + "1080": "1\"=90'", + "1200": "1\"=100'", + "1800": "1\"=150'", + "2400": "1\"=200'", + "3600": "1\"=300'", + "4800": "1\"=400'", + "6000": "1\"=500'", + } + METRIC_SCALES = { + "5000": "1:5000", + "2000": "1:2000", + "1000": "1:1000", + "500": "1:500", + "200": "1:200", + "100": "1:100", + "50": "1:50", + "20": "1:20", + "10": "1:10", + "5": "1:5", + "2": "1:2", + "1": "1:1", + } + import bpy + is_imperial = bpy.context.scene.unit_settings.system == "IMPERIAL" + return (IMPERIAL_SCALES if is_imperial else METRIC_SCALES).get(denominator, "") + @classmethod def get_drawing_metadata(cls, drawing: ifcopenshell.entity_instance) -> list[str]: pset_data = ifcopenshell.util.element.get_pset(drawing, "EPset_Drawing")