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"]) 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: class DecoratorData:
# stores 1 type of data per object # stores 1 type of data per object
data = {} data = {}
@@ -194,24 +202,19 @@ class DecoratorData:
if not element: if not element:
return return
classes = ifcopenshell.util.element.get_pset(element, "EPset_Annotation", "Classes") if obj.BIMTextProperties.is_editing:
font_size = float(obj.BIMTextProperties.font_size)
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')
else: 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 cls.data[obj.name] = font_size
return 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.sheeter as sheeter
import blenderbim.bim.module.drawing.scheduler as scheduler import blenderbim.bim.module.drawing.scheduler as scheduler
import blenderbim.bim.module.drawing.helper as helper import blenderbim.bim.module.drawing.helper as helper
from blenderbim.bim.module.drawing.data import DecoratorData
import blenderbim.bim.export_ifc import blenderbim.bim.export_ifc
from lxml import etree from lxml import etree
from mathutils import Vector from mathutils import Vector
@@ -1362,6 +1363,14 @@ class DisableEditingText(bpy.types.Operator, Operator):
def _execute(self, context): def _execute(self, context):
core.disable_editing_text(tool.Drawing, obj=context.active_object) 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): class EditAssignedProduct(bpy.types.Operator, Operator):
bl_idname = "bim.edit_assigned_product" bl_idname = "bim.edit_assigned_product"
@@ -25,7 +25,7 @@ import blenderbim.tool as tool
import blenderbim.core.drawing as core import blenderbim.core.drawing as core
import blenderbim.bim.module.drawing.annotation as annotation import blenderbim.bim.module.drawing.annotation as annotation
import blenderbim.bim.module.drawing.decoration as decoration 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 pathlib import Path
from blenderbim.bim.prop import Attribute, StrProperty from blenderbim.bim.prop import Attribute, StrProperty
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
@@ -228,10 +228,6 @@ def getVectorStyles(self, context):
return vector_styles_enum return vector_styles_enum
def refreshFontSize(self, context):
annotation.Annotator.resize_text(context.active_object)
class Variable(PropertyGroup): class Variable(PropertyGroup):
name: StringProperty(name="Name") name: StringProperty(name="Name")
prop_key: StringProperty(name="Property Key") prop_key: StringProperty(name="Property Key")
@@ -408,6 +404,16 @@ class BIMTextProperties(PropertyGroup):
def get_box_alignment(self): def get_box_alignment(self):
return self.get("box_alignment", DEFAULT_BOX_ALIGNMENT) 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) is_editing: BoolProperty(name="Is Editing", default=False)
attributes: CollectionProperty(name="Attributes", type=Attribute) attributes: CollectionProperty(name="Attributes", type=Attribute)
@@ -355,8 +355,7 @@ class BIM_PT_text(Panel):
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.prop(props, 'font_size') row.prop(props, 'font_size')
# a bit hacky way to align box alignment widget rows = []
rows = [self.layout.row(align=True) for i in range(3)]
for i in range(9): for i in range(9):
if i % 3 == 0: if i % 3 == 0:
split = rows[i//3].split(factor=0.1, align=True) 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), attributes=drawing.export_text_literal_attributes(obj),
) )
drawing.update_text_value(obj) drawing.update_text_value(obj)
drawing.update_text_size_pset(obj)
drawing.disable_editing_text(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.scheduler as scheduler
import blenderbim.bim.module.drawing.annotation as annotation import blenderbim.bim.module.drawing.annotation as annotation
import blenderbim.bim.module.drawing.helper as helper 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 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 box_alignment_mask[BOX_ALIGNMENT_POSITIONS.index(position_string)] = True
props.box_alignment = box_alignment_mask props.box_alignment = box_alignment_mask
font_size = DecoratorData.get_ifc_text_font_size(obj)
props.font_size = str(font_size)
@classmethod @classmethod
def import_assigned_product(cls, obj): def import_assigned_product(cls, obj):
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
@@ -525,16 +530,55 @@ class Drawing(blenderbim.core.tool.Drawing):
@classmethod @classmethod
def update_text_value(cls, obj): def update_text_value(cls, obj):
element = cls.get_text_literal(obj) props = obj.BIMTextProperties
if not element:
ifc_literal = cls.get_text_literal(obj)
if not ifc_literal:
return return
value = element.Literal value = ifc_literal.Literal
product = cls.get_assigned_product(tool.Ifc.get_entity(obj)) product = cls.get_assigned_product(tool.Ifc.get_entity(obj))
if product: if product:
variables = {} variables = {}
for variable in re.findall("{{.*?}}", value): for variable in re.findall("{{.*?}}", value):
value = value.replace(variable, str(ifcopenshell.util.selector.get_element_value(product, variable[2:-2]) or "")) 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 # TODO below this point is highly experimental prototype code with no tests