mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
UI for changing representation item's shape aspect
Example - https://imgur.com/a/tN7hCYz
This commit is contained in:
@@ -53,6 +53,9 @@ classes = (
|
|||||||
operator.EditRepresentationItemStyle,
|
operator.EditRepresentationItemStyle,
|
||||||
operator.DisableEditingRepresentationItemStyle,
|
operator.DisableEditingRepresentationItemStyle,
|
||||||
operator.UnassignRepresentationItemStyle,
|
operator.UnassignRepresentationItemStyle,
|
||||||
|
operator.EnableEditingRepresentationItemShapeAspect,
|
||||||
|
operator.EditRepresentationItemShapeAspect,
|
||||||
|
operator.DisableEditingRepresentationItemShapeAspect,
|
||||||
operator.RemoveRepresentationItemFromShapeAspect,
|
operator.RemoveRepresentationItemFromShapeAspect,
|
||||||
prop.RepresentationItem,
|
prop.RepresentationItem,
|
||||||
prop.BIMObjectGeometryProperties,
|
prop.BIMObjectGeometryProperties,
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class RepresentationsData:
|
|||||||
def load(cls):
|
def load(cls):
|
||||||
cls.data = {"representations": cls.representations()}
|
cls.data = {"representations": cls.representations()}
|
||||||
cls.data["contexts"] = cls.contexts()
|
cls.data["contexts"] = cls.contexts()
|
||||||
|
cls.data["shape_aspects"] = cls.shape_aspects()
|
||||||
cls.is_loaded = True
|
cls.is_loaded = True
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -92,6 +93,23 @@ class RepresentationsData:
|
|||||||
)
|
)
|
||||||
return results
|
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:
|
class RepresentationItemsData:
|
||||||
data = {}
|
data = {}
|
||||||
|
|||||||
@@ -1683,6 +1683,52 @@ class UnassignRepresentationItemStyle(bpy.types.Operator, Operator):
|
|||||||
bpy.ops.bim.enable_editing_representation_items()
|
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):
|
class RemoveRepresentationItemFromShapeAspect(bpy.types.Operator, Operator):
|
||||||
bl_idname = "bim.remove_representation_item_from_shape_aspect"
|
bl_idname = "bim.remove_representation_item_from_shape_aspect"
|
||||||
bl_label = "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"]
|
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):
|
class RepresentationItem(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
name: StringProperty(name="Name")
|
||||||
surface_style: StringProperty(name="Surface Style")
|
surface_style: StringProperty(name="Surface Style")
|
||||||
@@ -72,6 +78,8 @@ class BIMObjectGeometryProperties(PropertyGroup):
|
|||||||
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)
|
is_editing_item_style: BoolProperty(name="Is Editing Item's Style", default=False)
|
||||||
representation_item_style: EnumProperty(items=get_styles, name="Representation Item Style")
|
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):
|
class BIMGeometryProperties(PropertyGroup):
|
||||||
|
|||||||
@@ -213,10 +213,16 @@ class BIM_PT_representation_items(Panel):
|
|||||||
row = self.layout.row()
|
row = self.layout.row()
|
||||||
row.label(text=active_item.layer or "No Presentation Layer", icon="STICKY_UVS_LOC")
|
row.label(text=active_item.layer or "No Presentation Layer", icon="STICKY_UVS_LOC")
|
||||||
|
|
||||||
row = self.layout.row()
|
row = self.layout.row(align=True)
|
||||||
row.label(text=shape_aspect or "No Shape Aspect", icon="SHAPEKEY_DATA")
|
if props.is_editing_item_shape_aspect:
|
||||||
if shape_aspect:
|
row.prop(props, "representation_item_shape_aspect", icon="SHAPEKEY_DATA", text="")
|
||||||
row.operator("bim.remove_representation_item_from_shape_aspect", icon="X", 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):
|
class BIM_PT_connections(Panel):
|
||||||
|
|||||||
@@ -731,6 +731,18 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
apply_openings=True,
|
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
|
@classmethod
|
||||||
def remove_representation_item_from_shape_aspect(cls, representation_item, shape_aspect):
|
def remove_representation_item_from_shape_aspect(cls, representation_item, shape_aspect):
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
@@ -751,3 +763,47 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
else:
|
else:
|
||||||
items = set(representation.Items) - {representation_item}
|
items = set(representation.Items) - {representation_item}
|
||||||
representation.Items = tuple(items)
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user