UI for changing styles for representation items

Example - https://imgur.com/a/SQh6rR2
This commit is contained in:
Andrej730
2024-01-25 15:17:44 +05:00
parent c3ddfbdae2
commit 8bbb4cb43b
7 changed files with 178 additions and 9 deletions
@@ -49,6 +49,10 @@ classes = (
operator.SwitchRepresentation, operator.SwitchRepresentation,
operator.UpdateParametricRepresentation, operator.UpdateParametricRepresentation,
operator.UpdateRepresentation, operator.UpdateRepresentation,
operator.EnableEditingRepresentationItemStyle,
operator.EditRepresentationItemStyle,
operator.DisableEditingRepresentationItemStyle,
operator.UnassignRepresentationItemStyle,
prop.RepresentationItem, prop.RepresentationItem,
prop.BIMObjectGeometryProperties, prop.BIMObjectGeometryProperties,
prop.BIMGeometryProperties, prop.BIMGeometryProperties,
@@ -1605,3 +1605,77 @@ class DisableEditingRepresentationItems(bpy.types.Operator, Operator):
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = context.active_object
obj.BIMGeometryProperties.is_editing = False obj.BIMGeometryProperties.is_editing = False
class EnableEditingRepresentationItemStyle(bpy.types.Operator, Operator):
bl_idname = "bim.enable_editing_representation_item_style"
bl_label = "Enable Editing Representation Item Style"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.active_object.BIMGeometryProperties
props.is_editing_item_style = True
ifc_file = tool.Ifc.get()
# set dropdown to currently active style
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = ifc_file.by_id(representation_item_id)
style = tool.Style.get_representation_item_style(representation_item)
if style:
props.representation_item_style = str(style.id())
class EditRepresentationItemStyle(bpy.types.Operator, Operator):
bl_idname = "bim.edit_representation_item_style"
bl_label = "Edit Representation Item Style"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
obj = context.active_object
props = obj.BIMGeometryProperties
props.is_editing_item_style = False
ifc_file = tool.Ifc.get()
surface_style = ifc_file.by_id(int(props.representation_item_style))
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = ifc_file.by_id(representation_item_id)
tool.Style.assign_style_to_representation_item(representation_item, surface_style)
tool.Geometry.reload_representation(obj)
# reload style ui
bpy.ops.bim.disable_editing_representation_items()
bpy.ops.bim.enable_editing_representation_items()
class DisableEditingRepresentationItemStyle(bpy.types.Operator, Operator):
bl_idname = "bim.disable_editing_representation_item_style"
bl_label = "Disable Editing Representation Item Style"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.active_object.BIMGeometryProperties
props.is_editing_item_style = False
class UnassignRepresentationItemStyle(bpy.types.Operator, Operator):
bl_idname = "bim.unassign_representation_item_style"
bl_label = "Unassign Representation Item Style"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
obj = context.active_object
props = obj.BIMGeometryProperties
props.is_editing_item_style = False
# get active representation item
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = tool.Ifc.get_entity_by_id(representation_item_id)
if not representation_item:
self.report({"ERROR"}, f"Couldn't find representation item by id {representation_item_id}.")
return {"CANCELLED"}
tool.Style.assign_style_to_representation_item(representation_item, None)
tool.Geometry.reload_representation(obj)
# reload style ui
bpy.ops.bim.disable_editing_representation_items()
bpy.ops.bim.enable_editing_representation_items()
@@ -47,6 +47,15 @@ def update_mode(self, context):
bpy.ops.bim.override_mode_set_edit("INVOKE_DEFAULT") bpy.ops.bim.override_mode_set_edit("INVOKE_DEFAULT")
def get_styles(self, context):
# postponed import to avoid circular import
from blenderbim.bim.module.material.data import MaterialsData
if not MaterialsData.is_loaded:
MaterialsData.load()
return MaterialsData.data["styles"]
class RepresentationItem(PropertyGroup): class RepresentationItem(PropertyGroup):
name: StringProperty(name="Name") name: StringProperty(name="Name")
surface_style: StringProperty(name="Surface Style") surface_style: StringProperty(name="Surface Style")
@@ -59,6 +68,8 @@ class BIMObjectGeometryProperties(PropertyGroup):
is_editing: BoolProperty(name="Is Editing", default=False) is_editing: BoolProperty(name="Is Editing", default=False)
items: CollectionProperty(name="Representation Items", type=RepresentationItem) items: CollectionProperty(name="Representation Items", type=RepresentationItem)
active_item_index: IntProperty(name="Active Representation Item Index") active_item_index: IntProperty(name="Active Representation Item Index")
is_editing_item_style: BoolProperty(name="Is Editing Item's Style", default=False)
representation_item_style: EnumProperty(items=get_styles, name="Representation Item Style")
class BIMGeometryProperties(PropertyGroup): class BIMGeometryProperties(PropertyGroup):
@@ -187,17 +187,27 @@ class BIM_PT_representation_items(Panel):
self.layout.template_list("BIM_UL_representation_items", "", props, "items", props, "active_item_index") self.layout.template_list("BIM_UL_representation_items", "", props, "items", props, "active_item_index")
item_is_active = props.active_item_index < len(props.items) item_is_active = props.active_item_index < len(props.items)
if item_is_active: if not item_is_active:
surface_style = props.items[props.active_item_index].surface_style return
presentation_layer = props.items[props.active_item_index].layer
else:
surface_style, presentation_layer = None, None
row = self.layout.row() surface_style = props.items[props.active_item_index].surface_style
if surface_style: presentation_layer = props.items[props.active_item_index].layer
row.label(text=surface_style, icon="SHADING_RENDERED")
row = self.layout.row(align=True)
if props.is_editing_item_style:
# NOTE: we currently support 1 item having just 1 style
# when IfcStyledItem can actually have multiple styles
row.prop(props, "representation_item_style", icon="SHADING_RENDERED", text="")
row.operator("bim.edit_representation_item_style", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_representation_item_style", icon="CANCEL", text="")
else: else:
row.label(text="No Surface Style", icon="MESH_UVSPHERE") if surface_style:
row.label(text=surface_style, icon="SHADING_RENDERED")
else:
row.label(text="No Surface Style", icon="MESH_UVSPHERE")
row.operator("bim.enable_editing_representation_item_style", icon="GREASEPENCIL", text="")
if surface_style:
row.operator("bim.unassign_representation_item_style", icon="X", text="")
row = self.layout.row() row = self.layout.row()
row.label(text=presentation_layer or "No Presentation Layer", icon="STICKY_UVS_LOC") row.label(text=presentation_layer or "No Presentation Layer", icon="STICKY_UVS_LOC")
@@ -716,3 +716,17 @@ class Geometry(blenderbim.core.tool.Geometry):
obj.matrix_world.translation += original_min_point - new_max_point obj.matrix_world.translation += original_min_point - new_max_point
bpy.context.view_layer.update() bpy.context.view_layer.update()
@classmethod
def reload_representation(cls, obj):
representation = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
blenderbim.core.geometry.switch_representation(
tool.Ifc,
tool.Geometry,
obj=obj,
representation=representation,
should_reload=True,
is_global=True,
should_sync_changes_first=False,
apply_openings=True,
)
+21
View File
@@ -549,6 +549,27 @@ class Style(blenderbim.core.tool.Style):
representation = tool.Geometry.get_active_representation(obj) representation = tool.Geometry.get_active_representation(obj)
tool.Ifc.run("style.assign_representation_styles", shape_representation=representation, styles=[style]) tool.Ifc.run("style.assign_representation_styles", shape_representation=representation, styles=[style])
@classmethod
def assign_style_to_representation_item(cls, representation_item, style=None):
ifc_file = tool.Ifc.get()
if not representation_item.StyledByItem:
if style is None:
return
ifc_file.createIfcStyledItem(representation_item, (style,))
styled_item = representation_item.StyledByItem[0]
if style is None:
ifc_file.remove(styled_item)
return
styled_item.Styles = (style,)
@classmethod
def get_representation_item_style(cls, representation_item):
for inverse in tool.Ifc.get().get_inverse(representation_item):
if inverse.is_a("IfcStyledItem"):
for style in inverse.Styles:
return style
@classmethod @classmethod
def reload_material_from_ifc(cls, blender_material): def reload_material_from_ifc(cls, blender_material):
blender_material.BIMStyleProperties.active_style_type = blender_material.BIMStyleProperties.active_style_type blender_material.BIMStyleProperties.active_style_type = blender_material.BIMStyleProperties.active_style_type
+35
View File
@@ -23,6 +23,7 @@ import blenderbim.core.tool
import blenderbim.tool as tool import blenderbim.tool as tool
from test.bim.bootstrap import NewFile from test.bim.bootstrap import NewFile
from blenderbim.tool.style import Style as subject from blenderbim.tool.style import Style as subject
from ifcopenshell.util.shape_builder import ShapeBuilder
class TestImplementsTool(NewFile): class TestImplementsTool(NewFile):
@@ -460,3 +461,37 @@ class TestIsEditingStyles(NewFile):
subject.is_editing_styles() is False subject.is_editing_styles() is False
bpy.context.scene.BIMStylesProperties.is_editing = True bpy.context.scene.BIMStylesProperties.is_editing = True
subject.is_editing_styles() is True subject.is_editing_styles() is True
class TestGetRepresentationStyleItem(NewFile):
def test_run(self):
tool.Ifc.set(ifc := ifcopenshell.file())
builder = ShapeBuilder(ifc)
rectangle = builder.rectangle()
assert subject.get_representation_item_style(rectangle) == None
style = ifc.createIfcSurfaceStyle()
subject.assign_style_to_representation_item(rectangle, style)
assert subject.get_representation_item_style(rectangle) == style
class TestAssignStyleToRepresentationItem(NewFile):
def test_run(self):
tool.Ifc.set(ifc := ifcopenshell.file())
builder = ShapeBuilder(ifc)
rectangle = builder.rectangle()
# assigning new style
style1 = ifc.createIfcSurfaceStyle()
subject.assign_style_to_representation_item(rectangle, style1)
assert subject.get_representation_item_style(rectangle) == style1
# changing style
style2 = ifc.createIfcSurfaceStyle()
subject.assign_style_to_representation_item(rectangle, style2)
assert subject.get_representation_item_style(rectangle) == style2
# unassigning styles
subject.assign_style_to_representation_item(rectangle, None)
assert subject.get_representation_item_style(rectangle) == None