mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
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:
@@ -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")
|
||||||
|
|
||||||
font_size = font_sizes[font_size_type]
|
# 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]
|
||||||
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")
|
||||||
@@ -409,6 +405,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)
|
||||||
test_prop: StringProperty(name="test_prop", default="TEXT")
|
test_prop: StringProperty(name="test_prop", default="TEXT")
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user