mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
Merge branch 'presentationlayer' of https://github.com/Krande/IfcOpenShell into Krande-presentationlayer
This commit is contained in:
@@ -205,6 +205,11 @@ if bpy is not None:
|
||||
operator.SetViewportShadowFromSun,
|
||||
operator.SetNorthOffset,
|
||||
operator.GetNorthOffset,
|
||||
operator.AddPresentationLayer,
|
||||
operator.AddToPresentationLayer,
|
||||
operator.RemoveFromPresentationLayer,
|
||||
operator.RemovePresentationLayer,
|
||||
operator.UpdatePresentationLayer,
|
||||
operator.AddDrawingStyleAttribute,
|
||||
operator.RemoveDrawingStyleAttribute,
|
||||
operator.CopyPropertyToSelection,
|
||||
@@ -248,6 +253,7 @@ if bpy is not None:
|
||||
prop.BcfTopicDocumentReference,
|
||||
prop.BcfTopicRelatedTopic,
|
||||
prop.Subcontext,
|
||||
prop.PresentationLayer,
|
||||
prop.BIMProperties,
|
||||
prop.BIMDebugProperties,
|
||||
prop.BCFProperties,
|
||||
@@ -286,6 +292,7 @@ if bpy is not None:
|
||||
ui.BIM_PT_qa,
|
||||
ui.BIM_PT_library,
|
||||
ui.BIM_PT_gis,
|
||||
ui.BIM_PT_presentation_layers,
|
||||
ui.BIM_PT_diff,
|
||||
ui.BIM_PT_cobie,
|
||||
ui.BIM_PT_patch,
|
||||
@@ -293,6 +300,7 @@ if bpy is not None:
|
||||
ui.BIM_PT_debug,
|
||||
ui.BIM_PT_material,
|
||||
ui.BIM_PT_mesh,
|
||||
ui.BIM_PT_presentation_layer_data,
|
||||
ui.BIM_PT_object,
|
||||
ui.BIM_PT_object_material,
|
||||
ui.BIM_PT_object_psets,
|
||||
@@ -311,6 +319,7 @@ if bpy is not None:
|
||||
ui.BIM_UL_generic,
|
||||
ui.BIM_UL_clash_sets,
|
||||
ui.BIM_UL_constraints,
|
||||
ui.BIM_UL_presentation_layers,
|
||||
ui.BIM_UL_document_information,
|
||||
ui.BIM_UL_document_references,
|
||||
ui.BIM_UL_topics,
|
||||
|
||||
@@ -975,9 +975,10 @@ class IfcParser:
|
||||
def load_presentation_layer_assignments(self):
|
||||
for representation in self.representations.values():
|
||||
if representation["presentation_layer"]:
|
||||
self.presentation_layer_assignments.setdefault(representation["presentation_layer"], []).append(
|
||||
representation
|
||||
)
|
||||
pl = representation["presentation_layer"]
|
||||
if pl.name == '':
|
||||
continue
|
||||
self.presentation_layer_assignments.setdefault(pl.name, []).append(representation)
|
||||
|
||||
def load_representations(self):
|
||||
if not self.ifc_export_settings.has_representations:
|
||||
@@ -1109,9 +1110,7 @@ class IfcParser:
|
||||
"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_generated": False,
|
||||
"presentation_layer": mesh.BIMMeshProperties.presentation_layer
|
||||
if hasattr(mesh, "BIMMeshProperties")
|
||||
else None,
|
||||
"presentation_layer": obj.BIMObjectProperties.presentation_layer if hasattr(obj, "BIMObjectProperties") else None,
|
||||
"attributes": {"Name": mesh.name},
|
||||
}
|
||||
|
||||
@@ -2033,10 +2032,26 @@ class IfcExporter:
|
||||
return self.file.createIfcStyledItem(representation_item, [surface_style], item["attributes"]["Name"])
|
||||
|
||||
def create_presentation_layer_assignments(self):
|
||||
scene_props = bpy.context.scene.BIMProperties
|
||||
for name, assigned_items in self.ifc_parser.presentation_layer_assignments.items():
|
||||
self.file.createIfcPresentationLayerAssignment(
|
||||
name, None, [i["ifc"].MappedRepresentation for i in assigned_items], None
|
||||
)
|
||||
if name == '':
|
||||
continue
|
||||
pl = scene_props.presentation_layers[name]
|
||||
print("Presentation Export: ", name, pl.identifier, pl.layer_on)
|
||||
|
||||
with_style = False
|
||||
if pl.layer_on is False:
|
||||
with_style = True
|
||||
|
||||
if with_style is False:
|
||||
self.file.createIfcPresentationLayerAssignment(
|
||||
name, pl.description, [i["ifc"].MappedRepresentation for i in assigned_items], pl.identifier
|
||||
)
|
||||
else:
|
||||
self.file.createIfcPresentationLayerWithStyle(
|
||||
name, pl.description, [i["ifc"].MappedRepresentation for i in assigned_items], pl.identifier,
|
||||
pl.layer_on, pl.layer_frozen, pl.layer_blocked, pl.layer_styles
|
||||
)
|
||||
|
||||
def create_materials(self):
|
||||
for material in self.ifc_parser.materials.values():
|
||||
|
||||
@@ -479,6 +479,7 @@ class IfcImporter:
|
||||
self.profile_code("Merging by colour")
|
||||
self.add_project_to_scene()
|
||||
self.profile_code("Add project to scene")
|
||||
self.get_presentation_layers()
|
||||
if self.ifc_import_settings.should_clean_mesh and len(self.file.by_type("IfcElement")) < 10000:
|
||||
self.clean_mesh()
|
||||
self.profile_code("Mesh cleaning")
|
||||
@@ -1326,6 +1327,25 @@ class IfcImporter:
|
||||
self.type_collection.name
|
||||
].hide_viewport = True
|
||||
|
||||
def get_presentation_layers(self):
|
||||
for f in self.file.by_type("IfcPresentationLayerAssignment"):
|
||||
pl = bpy.context.scene.BIMProperties.presentation_layers.add()
|
||||
pl.name = f.Name
|
||||
pl.description = f.Description
|
||||
pl.identifier = f.Identifier
|
||||
if f.is_a() == "IfcPresentationLayerWithStyle":
|
||||
pl.layer_on = f.LayerOn if f.LayerOn is not None else True
|
||||
pl.layer_frozen = f.LayerFrozen if f.LayerFrozen is not None else False
|
||||
pl.layer_blocked = f.LayerBlocked if f.LayerBlocked is not None else False
|
||||
|
||||
for item in f.AssignedItems:
|
||||
guid = item.OfProductRepresentation[0].ShapeOfProduct[0].GlobalId
|
||||
for obj in bpy.context.selectable_objects:
|
||||
global_id = obj.BIMObjectProperties.attributes.get("GlobalId")
|
||||
if global_id and global_id.string_value == guid:
|
||||
obj.BIMObjectProperties.presentation_layer.name = pl.name
|
||||
obj.hide_set(not pl.layer_on)
|
||||
|
||||
def clean_mesh(self):
|
||||
obj = None
|
||||
last_obj = None
|
||||
|
||||
@@ -4324,6 +4324,80 @@ class GetNorthOffset(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddToPresentationLayer(bpy.types.Operator):
|
||||
bl_idname = "bim.add_to_presentation_layer"
|
||||
bl_label = "Add To Presentation Layer"
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
presentation_layer = bpy.context.scene.BIMProperties.presentation_layers[self.index]
|
||||
|
||||
# vl = bpy.context.scene.view_layers[presentation_layer.name]
|
||||
|
||||
for obj in bpy.context.selected_objects:
|
||||
obj.BIMObjectProperties.presentation_layer.name = presentation_layer.name
|
||||
elem_name = obj.BIMObjectProperties.attributes["Name"].string_value
|
||||
obj.hide_set(not presentation_layer.layer_on)
|
||||
print(f'Adding "{elem_name}" to View/Presentation Layer "({self.index} - {presentation_layer.name})"')
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemoveFromPresentationLayer(bpy.types.Operator):
|
||||
bl_idname = "bim.remove_from_presentation_layer"
|
||||
bl_label = "Remove Selected From Presentation Layer"
|
||||
|
||||
def execute(self, context):
|
||||
for el in bpy.context.selected_objects:
|
||||
if el.BIMObjectProperties.presentation_layer.name != "":
|
||||
el.BIMObjectProperties.presentation_layer.name = ""
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddPresentationLayer(bpy.types.Operator):
|
||||
bl_idname = "bim.add_presentation_layer"
|
||||
bl_label = "Add Presentation Layer"
|
||||
|
||||
def execute(self, context):
|
||||
new = bpy.context.scene.BIMProperties.presentation_layers.add()
|
||||
|
||||
# Default values of a new presentation layer
|
||||
new.name = "New Presentation Layer"
|
||||
new.description = "A Description"
|
||||
new.identifier = "Something"
|
||||
new.layer_on = True
|
||||
new.layer_frozen = False
|
||||
new.layer_blocked = False
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemovePresentationLayer(bpy.types.Operator):
|
||||
bl_idname = "bim.remove_presentation_layer"
|
||||
bl_label = "Remove Presentation Layer"
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
bpy.context.scene.BIMProperties.presentation_layers.remove(self.index)
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class UpdatePresentationLayer(bpy.types.Operator):
|
||||
bl_idname = "bim.update_presentation_layer"
|
||||
bl_label = "Hide/Show selected Presentation Layer"
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
pl = bpy.context.scene.BIMProperties.presentation_layers[self.index]
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.BIMObjectProperties.presentation_layer.name == pl.name:
|
||||
set_status = obj.hide_get()
|
||||
obj.hide_set(not obj.hide_get())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddDrawingStyleAttribute(bpy.types.Operator):
|
||||
bl_idname = "bim.add_drawing_style_attribute"
|
||||
bl_label = "Add Drawing Style Attribute"
|
||||
|
||||
@@ -792,6 +792,16 @@ class ClashSet(PropertyGroup):
|
||||
b: CollectionProperty(name="Group B", type=ClashSource)
|
||||
|
||||
|
||||
class PresentationLayer(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
description: StringProperty(name="Description")
|
||||
identifier: StringProperty(name="Identifier")
|
||||
layer_on: BoolProperty(name="LayerOn", default=True)
|
||||
layer_frozen: BoolProperty(name="LayerFrozen", default=False)
|
||||
layer_blocked: BoolProperty(name="LayerBlocked", default=False)
|
||||
layer_styles: EnumProperty(items=[], name="LayerStyles")
|
||||
|
||||
|
||||
class Constraint(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
description: StringProperty(name="Description")
|
||||
@@ -1564,6 +1574,8 @@ class BIMProperties(PropertyGroup):
|
||||
override_colour: FloatVectorProperty(
|
||||
name="Override Colour", subtype="COLOR", default=(1, 0, 0, 1), min=0.0, max=1.0, size=4
|
||||
)
|
||||
active_presentation_layer_index: IntProperty(name="Active Presentation Layer Index")
|
||||
presentation_layers: CollectionProperty(name="Presentation Layers", type=PresentationLayer)
|
||||
|
||||
|
||||
class BCFProperties(PropertyGroup):
|
||||
@@ -1668,6 +1680,7 @@ class BIMObjectProperties(PropertyGroup):
|
||||
qto_name: EnumProperty(items=getQtoNames, name="Qto Name")
|
||||
has_boundary_condition: BoolProperty(name="Has Boundary Condition")
|
||||
boundary_condition: PointerProperty(name="Boundary Condition", type=BoundaryCondition)
|
||||
presentation_layer: PointerProperty(name="Presentation Layer", type=PresentationLayer)
|
||||
structural_member_connection: PointerProperty(name="Structural Member Connection", type=bpy.types.Object)
|
||||
representation_contexts: CollectionProperty(name="Representation Contexts", type=Subcontext)
|
||||
# Address applies to IfcSite's SiteAddress and IfcBuilding's BuildingAddress
|
||||
@@ -1711,7 +1724,7 @@ class BIMMeshProperties(PropertyGroup):
|
||||
is_swept_solid: BoolProperty(name="Is Swept Solid")
|
||||
swept_solids: CollectionProperty(name="Swept Solids", type=SweptSolid)
|
||||
is_parametric: BoolProperty(name="Is Parametric", default=False)
|
||||
presentation_layer: StringProperty(name="Presentation Layer")
|
||||
presentation_layer: PointerProperty(name="Presentation Layer", type=PresentationLayer)
|
||||
geometry_type: StringProperty(name="Geometry Type")
|
||||
ifc_definition: StringProperty(name="IFC Definition")
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
|
||||
@@ -774,9 +774,6 @@ class BIM_PT_mesh(Panel):
|
||||
row.prop(ifc_parameter, "value", text="")
|
||||
row.operator("bim.update_ifc_representation", icon="FILE_REFRESH", text="").index = index
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, "presentation_layer")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, "is_parametric")
|
||||
row = layout.row()
|
||||
@@ -804,6 +801,51 @@ class BIM_PT_mesh(Panel):
|
||||
row.prop(props, "swept_solids")
|
||||
|
||||
|
||||
class BIM_PT_presentation_layer_data(Panel):
|
||||
bl_label = "IFC Presentation Layers"
|
||||
bl_idname = "BIM_PT_presentation"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "data"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (
|
||||
context.active_object is not None
|
||||
and context.active_object.type == "MESH"
|
||||
and hasattr(context.active_object.data, "BIMMeshProperties")
|
||||
)
|
||||
|
||||
def draw(self, context):
|
||||
if not context.active_object.data:
|
||||
return
|
||||
layout = self.layout
|
||||
elem_props = context.active_object.BIMObjectProperties.presentation_layer
|
||||
scene_props = context.scene.BIMProperties
|
||||
|
||||
if elem_props.name != "":
|
||||
layout.label(text=f'Object is part of Presentation layer "{elem_props.name}"')
|
||||
layout.row().operator("bim.remove_from_presentation_layer")
|
||||
else:
|
||||
layout.label(text="Not included in any presentation layer")
|
||||
|
||||
if scene_props.presentation_layers:
|
||||
layout.template_list(
|
||||
"BIM_UL_presentation_layers",
|
||||
"",
|
||||
scene_props,
|
||||
"presentation_layers",
|
||||
scene_props,
|
||||
"active_presentation_layer_index",
|
||||
)
|
||||
pres_layer = scene_props.presentation_layers[scene_props.active_presentation_layer_index]
|
||||
if pres_layer.name in bpy.context.scene.BIMProperties.presentation_layers:
|
||||
op = layout.row().operator("bim.add_to_presentation_layer")
|
||||
op.index = scene_props.active_presentation_layer_index
|
||||
else:
|
||||
layout.label(text="Presentation Layer is invalid")
|
||||
|
||||
|
||||
class BIM_PT_material(Panel):
|
||||
bl_label = "IFC Materials"
|
||||
bl_idname = "BIM_PT_material"
|
||||
@@ -909,6 +951,56 @@ class BIM_PT_gis(Panel):
|
||||
row.operator("bim.set_north_offset")
|
||||
|
||||
|
||||
class BIM_PT_presentation_layers(Panel):
|
||||
bl_label = "IFC Presentation Layers"
|
||||
bl_idname = "BIM_PT_presentation_layer"
|
||||
bl_options = {"DEFAULT_CLOSED"}
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "scene"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
props = context.scene.BIMProperties
|
||||
|
||||
layout.row().prop(props, "presentation_layers")
|
||||
layout.row().operator("bim.add_presentation_layer")
|
||||
|
||||
if props.presentation_layers:
|
||||
layout.template_list(
|
||||
"BIM_UL_presentation_layers", "", props, "presentation_layers", props, "active_presentation_layer_index"
|
||||
)
|
||||
pres_layer = props.presentation_layers[props.active_presentation_layer_index]
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(pres_layer, "name")
|
||||
if pres_layer.name in bpy.context.scene.BIMProperties.presentation_layers:
|
||||
pres_layer = bpy.context.scene.BIMProperties.presentation_layers[pres_layer.name]
|
||||
row.operator(
|
||||
"bim.remove_presentation_layer", icon="X", text=""
|
||||
).index = props.active_presentation_layer_index
|
||||
row = layout.row()
|
||||
row.prop(pres_layer, "description")
|
||||
row = layout.row()
|
||||
row.prop(pres_layer, "identifier")
|
||||
row = layout.row()
|
||||
row.prop(pres_layer, "layer_on")
|
||||
row = layout.row()
|
||||
row.prop(pres_layer, "layer_frozen")
|
||||
row = layout.row()
|
||||
row.prop(pres_layer, "layer_blocked")
|
||||
row = layout.row()
|
||||
row.prop(pres_layer, "layer_styles")
|
||||
|
||||
op = layout.row().operator("bim.update_presentation_layer")
|
||||
op.index = props.active_presentation_layer_index
|
||||
|
||||
|
||||
else:
|
||||
layout.label(text="Presentation Layer is invalid")
|
||||
|
||||
|
||||
class BIM_PT_drawings(Panel):
|
||||
bl_label = "SVG Drawings"
|
||||
bl_idname = "BIM_PT_drawings"
|
||||
@@ -1981,6 +2073,15 @@ class BIM_UL_constraints(bpy.types.UIList):
|
||||
layout.label(text="", translate=False)
|
||||
|
||||
|
||||
class BIM_UL_presentation_layers(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
ob = data
|
||||
if item:
|
||||
layout.prop(item, "name", text="", emboss=False)
|
||||
else:
|
||||
layout.label(text="", translate=False)
|
||||
|
||||
|
||||
class BIM_UL_document_information(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
ob = data
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
*
|
||||
!.gitignore
|
||||
!ifcopenshell.pth
|
||||
!OCC.pth
|
||||
!svgwrite.pth
|
||||
+1
-1
Submodule test/input updated: 828994fa4c...a75c92451c
Reference in New Issue
Block a user