Option to scale symbol from ifc tag by scaling ifc text object #2946

Also added some text scaling in viewport if there is some symbol associated with text annotation to roughly visually indicate how big this thing is going to be in the svg.

Example - https://user-images.githubusercontent.com/9417531/235445393-447f3aba-8425-4da6-81d0-6bf9004fcf2b.mp4
This commit is contained in:
Andrej730
2023-05-01 16:24:11 +05:00
parent 166e7d52ec
commit ceb2c4075c
3 changed files with 22 additions and 8 deletions
@@ -228,9 +228,11 @@ class DecoratorData:
props = obj.BIMTextProperties
# getting font size
classes = ifcopenshell.util.element.get_pset(element, "EPset_Annotation", "Classes")
pset_data = ifcopenshell.util.element.get_pset(element, "EPset_Annotation") or {}
# use `regular` as default
if classes:
# get font size
if classes := pset_data.get("Classes", None):
classes_split = classes.split()
# prioritize smaller font sizes just like in svg
font_size_type = next(
@@ -240,6 +242,9 @@ class DecoratorData:
font_size_type = "regular"
font_size = FONT_SIZES[font_size_type]
# get symbol
symbol = pset_data.get("Symbol", None)
# other attributes
props_literals = props.literals
props_literals_n = len(props.literals)
@@ -257,7 +262,7 @@ class DecoratorData:
literals_data.append(literal_data)
text_data = {"Literals": literals_data, "FontSize": font_size}
text_data = {"Literals": literals_data, "FontSize": font_size, "Symbol": symbol}
cls.data[obj.name] = text_data
return text_data
@@ -437,12 +437,16 @@ class BaseDecorator:
props = obj.BIMTextProperties
text_data = props.get_text_edited_data() if props.is_editing else DecoratorData.get_ifc_text_data(obj)
literals_data = text_data["Literals"]
symbol = text_data["Symbol"]
text_scale = 1.0
# draw asterisk symbol to visually indicate that there are multiple literals
if len(literals_data) > 1:
# draw asterisk symbol to indicate that there is some symbol that's not shown in viewport
if symbol:
verts = [text_world_position]
idxs = [(0, 0)]
self.draw_lines(context, obj, verts, idxs)
# NOTE: for now we assume that scale is uniform
text_scale = obj.scale.x
line_i = 0
for literal_data in literals_data:
@@ -457,7 +461,7 @@ class BaseDecorator:
gap=0,
center=False,
vcenter=False,
font_size_mm=text_data["FontSize"],
font_size_mm=text_data["FontSize"] * text_scale,
line_no=line_i,
box_alignment=box_alignment,
)
@@ -686,7 +686,13 @@ class SvgWriter:
# if there is a symbol with template text fields
# then we just populate it's fields with the data from text literals
if template_text_fields:
symbol_xml.attrib["transform"] = f"translate({', '.join(map(str, text_position_svg))}) rotate({angle})"
# NOTE: for now we assume that scale is uniform
symbol_transform = (
f"translate({', '.join(map(str, text_position_svg))})"
f" rotate({angle})"
f" scale({text_obj.scale.x})"
)
symbol_xml.attrib["transform"] = symbol_transform
symbol_xml.attrib.pop("id")
# note: zip makes sure that we iterate over the shortest list
for field, text_literal in zip(template_text_fields, text_literals):
@@ -732,7 +738,6 @@ class SvgWriter:
add_text_tag(True)
add_text_tag(False)
def draw_break_annotations(self, obj):
x_offset = self.raw_width / 2
y_offset = self.raw_height / 2