mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
Presentation layers are now assigned to meshes, and implement representation assignment. See #1109.
This commit is contained in:
@@ -974,11 +974,11 @@ class IfcParser:
|
|||||||
|
|
||||||
def load_presentation_layer_assignments(self):
|
def load_presentation_layer_assignments(self):
|
||||||
for representation in self.representations.values():
|
for representation in self.representations.values():
|
||||||
if representation["presentation_layer"]:
|
if representation["presentation_layer"] is False:
|
||||||
layer = representation["presentation_layer"]
|
continue
|
||||||
if layer.name == "":
|
self.presentation_layer_assignments.setdefault(representation["presentation_layer"], []).append(
|
||||||
continue
|
representation
|
||||||
self.presentation_layer_assignments.setdefault(layer.name, []).append(representation)
|
)
|
||||||
|
|
||||||
def load_representations(self):
|
def load_representations(self):
|
||||||
if not self.ifc_export_settings.has_representations:
|
if not self.ifc_export_settings.has_representations:
|
||||||
@@ -1110,9 +1110,9 @@ class IfcParser:
|
|||||||
"is_native": mesh.BIMMeshProperties.is_native if hasattr(mesh, "BIMMeshProperties") else False,
|
"is_native": mesh.BIMMeshProperties.is_native if hasattr(mesh, "BIMMeshProperties") else False,
|
||||||
"is_swept_solid": mesh.BIMMeshProperties.is_swept_solid if hasattr(mesh, "BIMMeshProperties") else False,
|
"is_swept_solid": mesh.BIMMeshProperties.is_swept_solid if hasattr(mesh, "BIMMeshProperties") else False,
|
||||||
"is_generated": False,
|
"is_generated": False,
|
||||||
"presentation_layer": obj.BIMObjectProperties.presentation_layer
|
"presentation_layer": mesh.BIMMeshProperties.presentation_layer_index
|
||||||
if hasattr(obj, "BIMObjectProperties")
|
if hasattr(mesh, "BIMMeshProperties") and mesh.BIMMeshProperties.presentation_layer_index != -1
|
||||||
else None,
|
else False,
|
||||||
"attributes": {"Name": mesh.name},
|
"attributes": {"Name": mesh.name},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1163,7 +1163,6 @@ class IfcParser:
|
|||||||
"raw": material,
|
"raw": material,
|
||||||
"attributes": self.get_material_attributes(material),
|
"attributes": self.get_material_attributes(material),
|
||||||
}
|
}
|
||||||
print(material.name)
|
|
||||||
self.materials[material.name] = data
|
self.materials[material.name] = data
|
||||||
self.get_material_psets(data, material)
|
self.get_material_psets(data, material)
|
||||||
|
|
||||||
@@ -1662,7 +1661,6 @@ class IfcExporter:
|
|||||||
if not properties:
|
if not properties:
|
||||||
continue
|
continue
|
||||||
pset["attributes"].update({"Properties": properties, "Material": pset["material"]["ifc"]})
|
pset["attributes"].update({"Properties": properties, "Material": pset["material"]["ifc"]})
|
||||||
print(pset["attributes"])
|
|
||||||
pset["ifc"] = self.file.create_entity("IfcMaterialProperties", **pset["attributes"])
|
pset["ifc"] = self.file.create_entity("IfcMaterialProperties", **pset["attributes"])
|
||||||
|
|
||||||
def create_qto_properties(self, qto):
|
def create_qto_properties(self, qto):
|
||||||
@@ -2034,28 +2032,22 @@ class IfcExporter:
|
|||||||
return self.file.createIfcStyledItem(representation_item, [surface_style], item["attributes"]["Name"])
|
return self.file.createIfcStyledItem(representation_item, [surface_style], item["attributes"]["Name"])
|
||||||
|
|
||||||
def create_presentation_layer_assignments(self):
|
def create_presentation_layer_assignments(self):
|
||||||
scene_props = bpy.context.scene.BIMProperties
|
for layer_index, representations in self.ifc_parser.presentation_layer_assignments.items():
|
||||||
for name, assigned_items in self.ifc_parser.presentation_layer_assignments.items():
|
layer = bpy.context.scene.BIMProperties.presentation_layers[int(layer_index)]
|
||||||
if name == "":
|
assigned_items = []
|
||||||
continue
|
for representation in representations:
|
||||||
layer = scene_props.presentation_layers[name]
|
for usage in representation["ifc"].MapUsage:
|
||||||
|
for inverse in self.file.get_inverse(usage):
|
||||||
with_style = False
|
assigned_items.append(inverse)
|
||||||
if layer.layer_on is False:
|
if layer.layer_on:
|
||||||
with_style = True
|
|
||||||
|
|
||||||
if with_style is False:
|
|
||||||
self.file.createIfcPresentationLayerAssignment(
|
self.file.createIfcPresentationLayerAssignment(
|
||||||
name,
|
layer.name, layer.description or None, assigned_items, layer.identifier or None,
|
||||||
layer.description or None,
|
|
||||||
[i["ifc"].MappedRepresentation for i in assigned_items],
|
|
||||||
layer.identifier or None,
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.file.createIfcPresentationLayerWithStyle(
|
self.file.createIfcPresentationLayerWithStyle(
|
||||||
name,
|
layer.name,
|
||||||
layer.description or None,
|
layer.description or None,
|
||||||
[i["ifc"].MappedRepresentation for i in assigned_items],
|
assigned_items,
|
||||||
layer.identifier or None,
|
layer.identifier or None,
|
||||||
layer.layer_on,
|
layer.layer_on,
|
||||||
layer.layer_frozen,
|
layer.layer_frozen,
|
||||||
|
|||||||
@@ -479,8 +479,8 @@ class IfcImporter:
|
|||||||
self.profile_code("Merging by colour")
|
self.profile_code("Merging by colour")
|
||||||
self.add_project_to_scene()
|
self.add_project_to_scene()
|
||||||
self.profile_code("Add project to scene")
|
self.profile_code("Add project to scene")
|
||||||
self.get_presentation_layers()
|
self.create_presentation_layers()
|
||||||
self.profile_code("Get presentation layers")
|
self.profile_code("Create presentation layers")
|
||||||
if self.ifc_import_settings.should_clean_mesh and len(self.file.by_type("IfcElement")) < 10000:
|
if self.ifc_import_settings.should_clean_mesh and len(self.file.by_type("IfcElement")) < 10000:
|
||||||
self.clean_mesh()
|
self.clean_mesh()
|
||||||
self.profile_code("Mesh cleaning")
|
self.profile_code("Mesh cleaning")
|
||||||
@@ -1328,9 +1328,10 @@ class IfcImporter:
|
|||||||
self.type_collection.name
|
self.type_collection.name
|
||||||
].hide_viewport = True
|
].hide_viewport = True
|
||||||
|
|
||||||
def get_presentation_layers(self):
|
def create_presentation_layers(self):
|
||||||
for assignment in self.file.by_type("IfcPresentationLayerAssignment"):
|
for assignment in self.file.by_type("IfcPresentationLayerAssignment"):
|
||||||
layer = bpy.context.scene.BIMProperties.presentation_layers.add()
|
layer = bpy.context.scene.BIMProperties.presentation_layers.add()
|
||||||
|
layer_index = len(bpy.context.scene.BIMProperties.presentation_layers) - 1
|
||||||
layer.name = assignment.Name
|
layer.name = assignment.Name
|
||||||
layer.description = assignment.Description or ""
|
layer.description = assignment.Description or ""
|
||||||
layer.identifier = assignment.Identifier or ""
|
layer.identifier = assignment.Identifier or ""
|
||||||
@@ -1340,19 +1341,18 @@ class IfcImporter:
|
|||||||
layer.layer_blocked = assignment.LayerBlocked if assignment.LayerBlocked is not None else False
|
layer.layer_blocked = assignment.LayerBlocked if assignment.LayerBlocked is not None else False
|
||||||
|
|
||||||
for item in assignment.AssignedItems:
|
for item in assignment.AssignedItems:
|
||||||
# TODO: This is a simplified and incorrect implementation of assigning presentation layers to objects
|
# TODO: This is a simplified implementation of assigning presentation layers that ignores assigned
|
||||||
# themselves, and will need to be rewritten in the future. See bug #1109. This code also does not
|
# representation items, does not consider mapped representations, and assumes a Body context. See #1109.
|
||||||
# consider mapped representations.
|
|
||||||
guids = []
|
guids = []
|
||||||
if not hasattr(item, "OfProductRepresentation"):
|
if not hasattr(item, "OfProductRepresentation") or item.RepresentationIdentifier != "Body":
|
||||||
continue # TODO: At the moment we ignore representation items
|
continue
|
||||||
for product_representation in item.OfProductRepresentation:
|
for product_representation in item.OfProductRepresentation:
|
||||||
for product in product_representation.ShapeOfProduct:
|
for product in product_representation.ShapeOfProduct:
|
||||||
guids.append(product.GlobalId)
|
guids.append(product.GlobalId)
|
||||||
for obj in bpy.context.selectable_objects:
|
for obj in bpy.context.selectable_objects:
|
||||||
global_id = obj.BIMObjectProperties.attributes.get("GlobalId")
|
global_id = obj.BIMObjectProperties.attributes.get("GlobalId")
|
||||||
if global_id and global_id.string_value in guids:
|
if global_id and global_id.string_value in guids:
|
||||||
obj.BIMObjectProperties.presentation_layer.name = layer.name
|
obj.data.BIMMeshProperties.presentation_layer_index = layer_index
|
||||||
obj.hide_set(not layer.layer_on)
|
obj.hide_set(not layer.layer_on)
|
||||||
|
|
||||||
def clean_mesh(self):
|
def clean_mesh(self):
|
||||||
|
|||||||
@@ -4328,11 +4328,12 @@ class AssignPresentationLayer(bpy.types.Operator):
|
|||||||
index: bpy.props.IntProperty()
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
presentation_layer = bpy.context.scene.BIMProperties.presentation_layers[self.index]
|
layer = bpy.context.scene.BIMProperties.presentation_layers[self.index]
|
||||||
for obj in bpy.context.selected_objects:
|
for obj in bpy.context.selected_objects:
|
||||||
# TODO: assign using a different strategy than name association
|
if not obj.data or not hasattr(obj.data, "BIMMeshProperties"):
|
||||||
obj.BIMObjectProperties.presentation_layer.name = presentation_layer.name
|
continue
|
||||||
obj.hide_set(not presentation_layer.layer_on)
|
obj.data.BIMMeshProperties.presentation_layer_index = self.index
|
||||||
|
obj.hide_set(not layer.layer_on)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -4341,9 +4342,10 @@ class UnassignPresentationLayer(bpy.types.Operator):
|
|||||||
bl_label = "Unassign Presentation Layer"
|
bl_label = "Unassign Presentation Layer"
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
for el in bpy.context.selected_objects:
|
for obj in bpy.context.selected_objects:
|
||||||
if el.BIMObjectProperties.presentation_layer.name != "":
|
if not obj.data or not hasattr(obj.data, "BIMMeshProperties"):
|
||||||
el.BIMObjectProperties.presentation_layer.name = ""
|
continue
|
||||||
|
obj.data.BIMMeshProperties.presentation_layer_index = -1
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1679,8 +1679,6 @@ class BIMObjectProperties(PropertyGroup):
|
|||||||
qto_name: EnumProperty(items=getQtoNames, name="Qto Name")
|
qto_name: EnumProperty(items=getQtoNames, name="Qto Name")
|
||||||
has_boundary_condition: BoolProperty(name="Has Boundary Condition")
|
has_boundary_condition: BoolProperty(name="Has Boundary Condition")
|
||||||
boundary_condition: PointerProperty(name="Boundary Condition", type=BoundaryCondition)
|
boundary_condition: PointerProperty(name="Boundary Condition", type=BoundaryCondition)
|
||||||
# TODO: presentation layers should belong to a mesh, not an object
|
|
||||||
presentation_layer: PointerProperty(name="Presentation Layer", type=PresentationLayer)
|
|
||||||
structural_member_connection: PointerProperty(name="Structural Member Connection", type=bpy.types.Object)
|
structural_member_connection: PointerProperty(name="Structural Member Connection", type=bpy.types.Object)
|
||||||
representation_contexts: CollectionProperty(name="Representation Contexts", type=Subcontext)
|
representation_contexts: CollectionProperty(name="Representation Contexts", type=Subcontext)
|
||||||
# Address applies to IfcSite's SiteAddress and IfcBuilding's BuildingAddress
|
# Address applies to IfcSite's SiteAddress and IfcBuilding's BuildingAddress
|
||||||
@@ -1729,3 +1727,4 @@ class BIMMeshProperties(PropertyGroup):
|
|||||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||||
ifc_parameters: CollectionProperty(name="IFC Parameters", type=IfcParameter)
|
ifc_parameters: CollectionProperty(name="IFC Parameters", type=IfcParameter)
|
||||||
active_representation_item_index: IntProperty(name="Active Representation Item Index")
|
active_representation_item_index: IntProperty(name="Active Representation Item Index")
|
||||||
|
presentation_layer_index: IntProperty(name="Presentation Layer Index", default=-1)
|
||||||
|
|||||||
@@ -815,23 +815,25 @@ class BIM_PT_presentation_layer_data(Panel):
|
|||||||
if not context.active_object.data:
|
if not context.active_object.data:
|
||||||
return
|
return
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
elem_props = context.active_object.BIMObjectProperties.presentation_layer
|
props = context.active_object.data.BIMMeshProperties
|
||||||
props = context.scene.BIMProperties
|
scene_props = context.scene.BIMProperties
|
||||||
|
|
||||||
if elem_props.name != "":
|
if props.presentation_layer_index != -1:
|
||||||
layout.label(text=f'Object is part of Presentation layer "{elem_props.name}"')
|
layer = scene_props.presentation_layers[props.presentation_layer_index]
|
||||||
|
layout.label(text=f"Assigned to: {layer.name}")
|
||||||
layout.row().operator("bim.unassign_presentation_layer")
|
layout.row().operator("bim.unassign_presentation_layer")
|
||||||
else:
|
return
|
||||||
if not props.presentation_layers:
|
|
||||||
layout.label(text=f"No presentation layers are available")
|
|
||||||
return
|
|
||||||
|
|
||||||
layout.template_list(
|
if not scene_props.presentation_layers:
|
||||||
"BIM_UL_generic", "", props, "presentation_layers", props, "active_presentation_layer_index",
|
layout.label(text=f"No presentation layers are available")
|
||||||
)
|
return
|
||||||
if props.active_presentation_layer_index < len(props.presentation_layers):
|
|
||||||
op = layout.row().operator("bim.assign_presentation_layer")
|
layout.template_list(
|
||||||
op.index = props.active_presentation_layer_index
|
"BIM_UL_generic", "", scene_props, "presentation_layers", scene_props, "active_presentation_layer_index",
|
||||||
|
)
|
||||||
|
if scene_props.active_presentation_layer_index < len(scene_props.presentation_layers):
|
||||||
|
op = layout.row().operator("bim.assign_presentation_layer")
|
||||||
|
op.index = scene_props.active_presentation_layer_index
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_material(Panel):
|
class BIM_PT_material(Panel):
|
||||||
|
|||||||
Reference in New Issue
Block a user