diff --git a/src/blenderbim/blenderbim/bim/module/misc/ui.py b/src/blenderbim/blenderbim/bim/module/misc/ui.py index e706fc4caf..910f4a003d 100644 --- a/src/blenderbim/blenderbim/bim/module/misc/ui.py +++ b/src/blenderbim/blenderbim/bim/module/misc/ui.py @@ -50,6 +50,8 @@ class BIM_PT_misc_utilities(bpy.types.Panel): row.operator("bim.draw_system_arrows") row = layout.row() row.operator("bim.clean_wireframes") + row = layout.row() + row.operator("bim.patch_non_parametric_mep_segment") row = layout.row(align=True) row.operator("bim.enable_editing_sketch_extrusion_profile", text="Start Sketching") diff --git a/src/blenderbim/blenderbim/bim/module/model/__init__.py b/src/blenderbim/blenderbim/bim/module/model/__init__.py index 0ea3b71e36..e8d03ee05a 100644 --- a/src/blenderbim/blenderbim/bim/module/model/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/model/__init__.py @@ -86,6 +86,7 @@ classes = ( profile.ExtendProfile, profile.RecalculateProfile, profile.Rotate90, + profile.PatchNonParametricMepSegment, roof.GenerateHippedRoof, slab.DisableEditingExtrusionProfile, slab.DisableEditingSketchExtrusionProfile, diff --git a/src/blenderbim/blenderbim/bim/module/model/profile.py b/src/blenderbim/blenderbim/bim/module/model/profile.py index 172484aa9b..113b192da4 100644 --- a/src/blenderbim/blenderbim/bim/module/model/profile.py +++ b/src/blenderbim/blenderbim/bim/module/model/profile.py @@ -28,6 +28,7 @@ import blenderbim.bim.handler import blenderbim.tool as tool import blenderbim.core.type import blenderbim.core.geometry +import blenderbim.core.material from math import pi, degrees, inf from mathutils import Vector, Matrix, Quaternion from blenderbim.bim.module.geometry.helper import Helper @@ -857,6 +858,25 @@ class Rotate90(bpy.types.Operator, tool.Ifc.Operator): return {"FINISHED"} +class PatchNonParametricMepSegment(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.patch_non_parametric_mep_segment" + bl_label = "Set MEP segment Material Profile" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + return context.active_object + + def _execute(self, context): + styles = tool.Geometry.get_styles(context.active_object) + blenderbim.core.material.patch_non_parametric_mep_segment( + tool.Ifc, tool.Material, tool.Profile, obj=context.active_object + ) + bpy.ops.bim.enable_editing_extrusion_axis() + bpy.ops.bim.edit_extrusion_axis() + styles = tool.Geometry.get_styles(context.active_object) + + class EnableEditingExtrusionAxis(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.enable_editing_extrusion_axis" bl_label = "Enable Editing Extrusion Axis" diff --git a/src/blenderbim/blenderbim/core/material.py b/src/blenderbim/blenderbim/core/material.py index 6203a53fe8..603f02ab75 100644 --- a/src/blenderbim/blenderbim/core/material.py +++ b/src/blenderbim/blenderbim/core/material.py @@ -119,3 +119,19 @@ def unassign_material(ifc, material_tool, objects): ifc.run("material.unassign_material", product=element_type) elif material: ifc.run("material.unassign_material", product=element) + + +def patch_non_parametric_mep_segment(ifc, material_tool, profile_tool, obj): + element = ifc.get_entity(obj) + if not element: + return + if not material_tool.is_a_flow_segment(element): + return + has_material_profile = material_tool.has_material_profile(element) + if has_material_profile: + return + representation_profile = profile_tool.get_profile(element) + if not representation_profile: + return + material_profile = material_tool.replace_material_with_material_profile(element=element) + ifc.run("material.assign_profile", material_profile=material_profile, profile=representation_profile) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 0675b29359..4be2e93a27 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -447,11 +447,14 @@ class Material: def get_material(cls, element, should_inherit): pass def get_name(cls, obj): pass def get_type(cls, element): pass + def has_material_profile(cls, element): pass def import_material_definitions(cls, material_type): pass + def is_a_flow_segment(cls, element): pass def is_a_material_set(cls, material): pass def is_editing_materials(cls): pass def is_material_used_in_sets(cls, material): pass def load_material_attributes(cls, material): pass + def replace_material_with_material_profile(cls, element): pass @interface @@ -551,6 +554,8 @@ class Project: @interface class Profile: def draw_image_for_ifc_profile(cls, draw, profile, size): pass + def is_editing_profile(cls): pass + def get_profile(cls, element): pass @interface diff --git a/src/blenderbim/blenderbim/tool/material.py b/src/blenderbim/blenderbim/tool/material.py index 3047c605e8..7542e08eef 100644 --- a/src/blenderbim/blenderbim/tool/material.py +++ b/src/blenderbim/blenderbim/tool/material.py @@ -193,3 +193,30 @@ class Material(blenderbim.core.tool.Material): material=material, profile=profile, ) + + @classmethod + def has_material_profile(cls, element): + material = cls.get_material(element, should_inherit=False) + inherited_material = cls.get_material(element, should_inherit=True) + if material and "Profile" in material.is_a(): + return True + if inherited_material and "Profile" in inherited_material.is_a(): + return True + return False + + @classmethod + def is_a_flow_segment(cls, element): + return element.is_a("IfcFlowSegment") + + @classmethod + def replace_material_with_material_profile(cls, element): + old_material = cls.get_material(element, should_inherit=False) + old_inherited_material = cls.get_material(element, should_inherit=True) + blenderbim.core.material.unassign_material(tool.Ifc, tool.Material, objects=[tool.Ifc.get_object(element)]) + tool.Ifc.run("material.assign_material", product=element, type="IfcMaterialProfileSet") + assinged_material = cls.get_material(element) + material = old_material if old_material and old_material.is_a("IfcMaterial") else None + if not material and old_inherited_material: + material = old_inherited_material if old_inherited_material.is_a("IfcMaterial") else None + material_profile = tool.Ifc.run("material.add_profile", profile_set=assinged_material, material=material) + return material_profile diff --git a/src/blenderbim/blenderbim/tool/profile.py b/src/blenderbim/blenderbim/tool/profile.py index 1c13fcd3d9..1a1fd9f949 100644 --- a/src/blenderbim/blenderbim/tool/profile.py +++ b/src/blenderbim/blenderbim/tool/profile.py @@ -57,3 +57,16 @@ class Profile(blenderbim.core.tool.Profile): @classmethod def is_editing_profile(cls): return ProfileDecorator.installed + + @classmethod + def get_profile(cls, element): + representations = element.Representation + for representation in representations.Representations: + if not representation.is_a("IfcShapeRepresentation"): + continue + for representation_item in representation.Items: + if representation_item.is_a("IfcExtrudedAreaSolid"): + profile = representation_item.SweptArea + if profile: + return profile + return None