UI for changing representation item's shape aspect

Example - https://imgur.com/a/tN7hCYz
This commit is contained in:
Andrej730
2024-01-26 15:51:07 +05:00
parent fda6fc6c48
commit 0da3270c7f
6 changed files with 141 additions and 4 deletions
@@ -53,6 +53,9 @@ classes = (
operator.EditRepresentationItemStyle,
operator.DisableEditingRepresentationItemStyle,
operator.UnassignRepresentationItemStyle,
operator.EnableEditingRepresentationItemShapeAspect,
operator.EditRepresentationItemShapeAspect,
operator.DisableEditingRepresentationItemShapeAspect,
operator.RemoveRepresentationItemFromShapeAspect,
prop.RepresentationItem,
prop.BIMObjectGeometryProperties,
@@ -38,6 +38,7 @@ class RepresentationsData:
def load(cls):
cls.data = {"representations": cls.representations()}
cls.data["contexts"] = cls.contexts()
cls.data["shape_aspects"] = cls.shape_aspects()
cls.is_loaded = True
@classmethod
@@ -92,6 +93,23 @@ class RepresentationsData:
)
return results
@classmethod
def shape_aspects(cls):
obj = bpy.context.active_object
element = tool.Ifc.get_entity(obj)
active_representation_id = obj.data.BIMMeshProperties.ifc_definition_id
base_representation = tool.Ifc.get().by_id(active_representation_id)
# shape aspects matching context of the active representation
matching_shape_aspects = []
for shape_aspect in tool.Geometry.get_shape_aspects(element):
matching_representation = tool.Geometry.get_shape_aspect_representation(shape_aspect, base_representation)
if matching_representation:
matching_shape_aspects.append(shape_aspect)
# blender enum items
return [(str(s.id()), s.Name or "Unnamed", "") for s in matching_shape_aspects]
class RepresentationItemsData:
data = {}
@@ -1683,6 +1683,52 @@ class UnassignRepresentationItemStyle(bpy.types.Operator, Operator):
bpy.ops.bim.enable_editing_representation_items()
class EnableEditingRepresentationItemShapeAspect(bpy.types.Operator, Operator):
bl_idname = "bim.enable_editing_representation_item_shape_aspect"
bl_label = "Enable Editing Representation Item Shape Aspect"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.active_object.BIMGeometryProperties
props.is_editing_item_shape_aspect = True
# set dropdown to currently active style
shape_aspect_id = props.items[props.active_item_index].shape_aspect_id
if shape_aspect_id != 0:
props.representation_item_shape_aspect = str(shape_aspect_id)
class EditRepresentationItemShapeAspect(bpy.types.Operator, Operator):
bl_idname = "bim.edit_representation_item_shape_aspect"
bl_label = "Edit Representation Item Shape Aspect"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
obj = context.active_object
props = obj.BIMGeometryProperties
props.is_editing_item_shape_aspect = False
ifc_file = tool.Ifc.get()
shape_aspect = ifc_file.by_id(int(props.representation_item_shape_aspect))
representation_item_id = props.items[props.active_item_index].ifc_definition_id
representation_item = ifc_file.by_id(representation_item_id)
tool.Geometry.add_representation_item_to_shape_aspect(representation_item, shape_aspect)
# reload style ui
bpy.ops.bim.disable_editing_representation_items()
bpy.ops.bim.enable_editing_representation_items()
class DisableEditingRepresentationItemShapeAspect(bpy.types.Operator, Operator):
bl_idname = "bim.disable_editing_representation_item_shape_aspect"
bl_label = "Disable Editing Representation Item Shape Aspect"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = context.active_object.BIMGeometryProperties
props.is_editing_item_shape_aspect = False
class RemoveRepresentationItemFromShapeAspect(bpy.types.Operator, Operator):
bl_idname = "bim.remove_representation_item_from_shape_aspect"
bl_label = "Remove Representation Item From Shape Aspect"
@@ -56,6 +56,12 @@ def get_styles(self, context):
return MaterialsData.data["styles"]
def get_shape_aspects(self, context):
if not RepresentationsData.is_loaded:
RepresentationsData.load()
return RepresentationsData.data["shape_aspects"]
class RepresentationItem(PropertyGroup):
name: StringProperty(name="Name")
surface_style: StringProperty(name="Surface Style")
@@ -72,6 +78,8 @@ class BIMObjectGeometryProperties(PropertyGroup):
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")
is_editing_item_shape_aspect: BoolProperty(name="Is Editing Item's Shape Aspect", default=False)
representation_item_shape_aspect: EnumProperty(items=get_shape_aspects, name="Representation Item Shape Aspect")
class BIMGeometryProperties(PropertyGroup):
@@ -213,10 +213,16 @@ class BIM_PT_representation_items(Panel):
row = self.layout.row()
row.label(text=active_item.layer or "No Presentation Layer", icon="STICKY_UVS_LOC")
row = self.layout.row()
row.label(text=shape_aspect or "No Shape Aspect", icon="SHAPEKEY_DATA")
if shape_aspect:
row.operator("bim.remove_representation_item_from_shape_aspect", icon="X", text="")
row = self.layout.row(align=True)
if props.is_editing_item_shape_aspect:
row.prop(props, "representation_item_shape_aspect", icon="SHAPEKEY_DATA", text="")
row.operator("bim.edit_representation_item_shape_aspect", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_representation_item_shape_aspect", icon="CANCEL", text="")
else:
row.label(text=shape_aspect or "No Shape Aspect", icon="SHAPEKEY_DATA")
row.operator("bim.enable_editing_representation_item_shape_aspect", icon="GREASEPENCIL", text="")
if shape_aspect:
row.operator("bim.remove_representation_item_from_shape_aspect", icon="X", text="")
class BIM_PT_connections(Panel):
@@ -731,6 +731,18 @@ class Geometry(blenderbim.core.tool.Geometry):
apply_openings=True,
)
@classmethod
def get_shape_aspects(cls, element):
# IfcProduct
if hasattr(element, "Representation"):
return element.Representation.ShapeOfProduct
# IfcTypeProduct
shape_aspects = []
for repersentation_map in element.RepresentationMaps:
shape_aspects += repersentation_map.HasShapeAspects
return shape_aspects
@classmethod
def remove_representation_item_from_shape_aspect(cls, representation_item, shape_aspect):
ifc_file = tool.Ifc.get()
@@ -751,3 +763,47 @@ class Geometry(blenderbim.core.tool.Geometry):
else:
items = set(representation.Items) - {representation_item}
representation.Items = tuple(items)
@classmethod
def add_representation_item_to_shape_aspect(cls, representation_item, shape_aspect):
ifc_file = tool.Ifc.get()
previous_shape_aspect = None
for inverse in ifc_file.get_inverse(representation_item):
if inverse.is_a("IfcShapeRepresentation"):
if inverse.OfShapeAspect:
# item is already added to the shape aspect
if inverse.OfShapeAspect[0] == shape_aspect:
return
previous_shape_aspect = inverse.OfShapeAspect[0]
else:
base_representation = inverse
# remove item from previous shape aspect
if previous_shape_aspect:
cls.remove_representation_item_from_shape_aspect(representation_item, previous_shape_aspect)
shape_aspect_representation = cls.get_shape_aspect_representation(
shape_aspect, base_representation, create_new=True
)
shape_aspect_representation.Items = shape_aspect_representation.Items + (representation_item,)
@classmethod
def get_shape_aspect_representation(cls, shape_aspect, base_representation, create_new=False):
for representation in shape_aspect.ShapeRepresentations:
if (
representation.ContextOfItems == base_representation.ContextOfItems
and representation.RepresentationIdentifier == base_representation.RepresentationIdentifier
and representation.RepresentationType == base_representation.RepresentationType
):
return representation
if not create_new:
return None
shape_aspect_representation = tool.Ifc.get().createIfcShapeRepresentation(
ContextOfItems=base_representation.ContextOfItems,
RepresentationIdentifier=base_representation.RepresentationIdentifier,
RepresentationType=base_representation.RepresentationType,
)
shape_aspect.ShapeRepresentations = shape_aspect.ShapeRepresentations + (shape_aspect_representation,)
return shape_aspect_representation