Ifc Text - drop down menu to switch font size

Added drop down menu to Ifc Text section in object properties where you can change text's size and it will automatically change it in `EPset_Annotation.Classes`. You can also preview it in viewport and it will write in IFC only after you finish editing.

Still need to investigate `annotation.Annotator.resize_text(context.active_object)` in `refreshFontSize`.
This commit is contained in:
Andrej730
2023-03-15 18:58:06 +05:00
parent 3c2ef518e8
commit ee1e401719
6 changed files with 90 additions and 28 deletions
@@ -125,6 +125,14 @@ class SchedulesData:
return len([d for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "SCHEDULE"])
FONT_SIZES = {
'small': 1.8,
'regular': 2.5,
'large': 3.5,
'header': 5.0,
'title': 7.0,
}
class DecoratorData:
# stores 1 type of data per object
data = {}
@@ -194,24 +202,19 @@ class DecoratorData:
if not element:
return
classes = ifcopenshell.util.element.get_pset(element, "EPset_Annotation", "Classes")
font_sizes = {
'small': 1.8,
'regular': 2.5,
'large': 3.5,
'header': 5,
'title': 7,
}
# use `regular` as default
if classes:
tags = classes.split()
# prioritize smaller font sizes just like in svg
font_size_type = next((font_size_type for font_size_type in font_sizes if font_size_type in tags), 'regular')
if obj.BIMTextProperties.is_editing:
font_size = float(obj.BIMTextProperties.font_size)
else:
font_size_type = 'regular'
classes = ifcopenshell.util.element.get_pset(element, "EPset_Annotation", "Classes")
# use `regular` as default
if classes:
classes_split = classes.split()
# prioritize smaller font sizes just like in svg
font_size_type = next((font_size_type for font_size_type in FONT_SIZES if font_size_type in classes_split), 'regular')
else:
font_size_type = 'regular'
font_size = font_sizes[font_size_type]
font_size = FONT_SIZES[font_size_type]
cls.data[obj.name] = font_size
return font_size
@@ -39,6 +39,7 @@ import blenderbim.bim.module.drawing.annotation as annotation
import blenderbim.bim.module.drawing.sheeter as sheeter
import blenderbim.bim.module.drawing.scheduler as scheduler
import blenderbim.bim.module.drawing.helper as helper
from blenderbim.bim.module.drawing.data import DecoratorData
import blenderbim.bim.export_ifc
from lxml import etree
from mathutils import Vector
@@ -1362,6 +1363,14 @@ class DisableEditingText(bpy.types.Operator, Operator):
def _execute(self, context):
core.disable_editing_text(tool.Drawing, obj=context.active_object)
# force update this object's font size for viewport display
DecoratorData.data.pop(context.object.name, None)
# TODO: just needed some way to trigger UI update
# probably there is more proper way to do it
props = context.object.BIMTextProperties
props.font_size = props.font_size
class EditAssignedProduct(bpy.types.Operator, Operator):
bl_idname = "bim.edit_assigned_product"
@@ -25,7 +25,7 @@ import blenderbim.tool as tool
import blenderbim.core.drawing as core
import blenderbim.bim.module.drawing.annotation as annotation
import blenderbim.bim.module.drawing.decoration as decoration
from blenderbim.bim.module.drawing.data import DrawingsData
from blenderbim.bim.module.drawing.data import DrawingsData, DecoratorData
from pathlib import Path
from blenderbim.bim.prop import Attribute, StrProperty
from bpy.types import PropertyGroup
@@ -228,10 +228,6 @@ def getVectorStyles(self, context):
return vector_styles_enum
def refreshFontSize(self, context):
annotation.Annotator.resize_text(context.active_object)
class Variable(PropertyGroup):
name: StringProperty(name="Name")
prop_key: StringProperty(name="Property Key")
@@ -408,6 +404,16 @@ class BIMTextProperties(PropertyGroup):
def get_box_alignment(self):
return self.get("box_alignment", DEFAULT_BOX_ALIGNMENT)
def refreshFontSize(self, context):
# force update this object's font size for viewport display
DecoratorData.data.pop(context.object.name, None)
# TODO: line seems outdated and currently is just throwing error. remove?
# File "\blenderbim\bim\module\drawing\annotation.py", line 63, in resize_text
# font_size *= float(text_obj.data.BIMTextProperties.font_size)
# AttributeError: 'NoneType' object has no attribute 'BIMTextProperties'
# annotation.Annotator.resize_text(context.active_object)
is_editing: BoolProperty(name="Is Editing", default=False)
attributes: CollectionProperty(name="Attributes", type=Attribute)
@@ -355,8 +355,7 @@ class BIM_PT_text(Panel):
row = self.layout.row(align=True)
row.prop(props, 'font_size')
# a bit hacky way to align box alignment widget
rows = [self.layout.row(align=True) for i in range(3)]
rows = []
for i in range(9):
if i % 3 == 0:
split = rows[i//3].split(factor=0.1, align=True)
@@ -33,6 +33,7 @@ def edit_text(ifc, drawing, obj=None):
attributes=drawing.export_text_literal_attributes(obj),
)
drawing.update_text_value(obj)
drawing.update_text_size_pset(obj)
drawing.disable_editing_text(obj)
+48 -4
View File
@@ -34,6 +34,8 @@ import blenderbim.bim.module.drawing.sheeter as sheeter
import blenderbim.bim.module.drawing.scheduler as scheduler
import blenderbim.bim.module.drawing.annotation as annotation
import blenderbim.bim.module.drawing.helper as helper
from blenderbim.bim.module.drawing.data import FONT_SIZES, DecoratorData
from blenderbim.bim.module.drawing.prop import get_diagram_scales, BOX_ALIGNMENT_POSITIONS
@@ -463,6 +465,9 @@ class Drawing(blenderbim.core.tool.Drawing):
box_alignment_mask[BOX_ALIGNMENT_POSITIONS.index(position_string)] = True
props.box_alignment = box_alignment_mask
font_size = DecoratorData.get_ifc_text_font_size(obj)
props.font_size = str(font_size)
@classmethod
def import_assigned_product(cls, obj):
element = tool.Ifc.get_entity(obj)
@@ -525,16 +530,55 @@ class Drawing(blenderbim.core.tool.Drawing):
@classmethod
def update_text_value(cls, obj):
element = cls.get_text_literal(obj)
if not element:
props = obj.BIMTextProperties
ifc_literal = cls.get_text_literal(obj)
if not ifc_literal:
return
value = element.Literal
value = ifc_literal.Literal
product = cls.get_assigned_product(tool.Ifc.get_entity(obj))
if product:
variables = {}
for variable in re.findall("{{.*?}}", value):
value = value.replace(variable, str(ifcopenshell.util.selector.get_element_value(product, variable[2:-2]) or ""))
obj.BIMTextProperties.value = value
props.value = value
@classmethod
def update_text_size_pset(cls, obj):
""" updates pset `EPset_Annotation.Classes` value
based on current font size from `obj.BIMTextProperties.font_size`
"""
props = obj.BIMTextProperties
element = tool.Ifc.get_entity(obj)
# updating text font size in EPset_Annotation.Classes
font_size = float(props.font_size)
font_size_str = next((key for key in FONT_SIZES if FONT_SIZES[key] == font_size), None)
classes = ifcopenshell.util.element.get_pset(element, "EPset_Annotation", "Classes")
classes_split = classes.split() if classes else []
different_font_sizes = [c for c in classes_split if c in FONT_SIZES and c != font_size_str]
# if there are different font sizes in classes already
# or if the current font size is not present in classes
# (except regular because it's default)
# then we do need to change pset value in ifc
if different_font_sizes \
or (font_size_str not in classes_split and font_size_str != 'regular'):
classes_split = [c for c in classes_split if c not in FONT_SIZES] + [font_size_str]
classes = ' '.join(classes_split)
ifc_file = tool.Ifc.get()
pset = tool.Pset.get_element_pset(element, "EPset_Annotation")
if not pset:
pset = ifcopenshell.api.run("pset.add_pset", ifc_file, product=element, name="EPset_Annotation")
ifcopenshell.api.run(
"pset.edit_pset",
ifc_file,
pset=pset,
properties={"Classes": classes},
)
# TODO below this point is highly experimental prototype code with no tests