From 9180fdce5aa569fd9238e4174e3d4df2b559afa6 Mon Sep 17 00:00:00 2001 From: Gorgious56 Date: Mon, 5 Jun 2023 18:07:25 +0200 Subject: [PATCH] Edit profile based representations with TAB (#3142) * You can now edit profile based representations with TAB * Minor fix * Minor fix * You can now edit parametric railing paths with TAB Still not sure about the implementation though * use shortcut instead of direct link to railing edition * Add utility to check if a mesh is profile based or its representation is a swept solid * Fix bug when trying to edit an empty object * Prevent editing door, window and stair modifiers since they're fully parameterized by the modifier properties * You can now edit roof modifier, railing modifier and various profile based objects * You can now edit axis profile based objects --- .../bim/module/geometry/operator.py | 51 ++++++++++++++++++- src/blenderbim/blenderbim/tool/geometry.py | 10 ++++ src/blenderbim/blenderbim/tool/profile.py | 5 ++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/geometry/operator.py b/src/blenderbim/blenderbim/bim/module/geometry/operator.py index a82fdbddb3..ac7dbb9383 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/operator.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/operator.py @@ -738,13 +738,18 @@ class OverrideModeSetEdit(bpy.types.Operator): if not obj: continue + if not obj.data: + obj.select_set(False) + continue + element = tool.Ifc.get_entity(obj) if not element: + obj.select_set(False) continue # We are switching from OBJECT to EDIT mode. usage_type = tool.Model.get_usage_type(element) - if usage_type: + if usage_type is not None and usage_type != "PROFILE": # Parametric objects shall not be edited as meshes as they # can be modified to be incompatible with the parametric # constraints. @@ -755,6 +760,37 @@ class OverrideModeSetEdit(bpy.types.Operator): if not representation: continue + if ( + tool.Pset.get_element_pset(element, "BBIM_Door") + or tool.Pset.get_element_pset(element, "BBIM_Window") + or tool.Pset.get_element_pset(element, "BBIM_Stair") + ): + obj.select_set(False) + continue + if usage_type == "PROFILE": + if len(context.selected_objects) == 1: + bpy.ops.bim.hotkey(hotkey="A_E", description="") + obj.data.BIMMeshProperties.mesh_checksum = tool.Geometry.get_mesh_checksum(obj.data) + return {"FINISHED"} + else: + self.report({"INFO"}, "Only a single profile-based representation can be edited at a time.") + obj.select_set(False) + continue + if ( + tool.Geometry.is_profile_based(obj.data) + or tool.Geometry.is_swept_profile(representation) + or tool.Pset.get_element_pset(element, "BBIM_Roof") + or tool.Pset.get_element_pset(element, "BBIM_Railing") + ): + if len(context.selected_objects) == 1: + bpy.ops.bim.hotkey(hotkey="S_E", description="") + obj.data.BIMMeshProperties.mesh_checksum = tool.Geometry.get_mesh_checksum(obj.data) + return {"FINISHED"} + else: + self.report({"INFO"}, "Only a single profile-based representation can be edited at a time.") + obj.select_set(False) + continue + if tool.Geometry.is_meshlike(representation): if getattr(element, "HasOpenings", None): # Mesh elements with openings must disable openings @@ -866,7 +902,18 @@ class OverrideModeSetObject(bpy.types.Operator): if not element: continue - if obj.data.BIMMeshProperties.ifc_definition_id: + if tool.Profile.is_editing_profile(): + if obj.data.BIMMeshProperties.mesh_checksum != tool.Geometry.get_mesh_checksum(obj.data): + if tool.Pset.get_element_pset(element, "BBIM_Railing") or tool.Pset.get_element_pset( + element, "BBIM_Roof" + ): + bpy.ops.bim.cad_hotkey(hotkey="S_Q") + elif tool.Model.get_usage_type(element): + bpy.ops.bim.edit_extrusion_axis() + else: + bpy.ops.bim.edit_extrusion_profile() + return self.execute(context) + elif obj.data.BIMMeshProperties.ifc_definition_id: if not tool.Geometry.has_geometric_data(obj): self.is_valid = False self.should_save = False diff --git a/src/blenderbim/blenderbim/tool/geometry.py b/src/blenderbim/blenderbim/tool/geometry.py index 96676c1117..5e13ab5dd2 100644 --- a/src/blenderbim/blenderbim/tool/geometry.py +++ b/src/blenderbim/blenderbim/tool/geometry.py @@ -356,6 +356,16 @@ class Geometry(blenderbim.core.tool.Geometry): return True return False + @classmethod + def is_profile_based(cls, data): + return data.BIMMeshProperties.subshape_type == "PROFILE" + + @classmethod + def is_swept_profile(cls, representation): + return ifcopenshell.util.representation.resolve_representation(representation).RepresentationType in ( + "SweptSolid", + ) + @classmethod def is_type_product(cls, element): return element.is_a("IfcTypeProduct") diff --git a/src/blenderbim/blenderbim/tool/profile.py b/src/blenderbim/blenderbim/tool/profile.py index ab1402daaf..1c13fcd3d9 100644 --- a/src/blenderbim/blenderbim/tool/profile.py +++ b/src/blenderbim/blenderbim/tool/profile.py @@ -21,6 +21,7 @@ import ifcopenshell.util.unit import ifcopenshell.util.placement import ifcopenshell.util.representation import blenderbim.core.tool +from blenderbim.bim.module.model.decorator import ProfileDecorator class Profile(blenderbim.core.tool.Profile): @@ -52,3 +53,7 @@ class Profile(blenderbim.core.tool.Profile): for e in grouped_edges: draw.line((tuple(grouped_verts[e[0]]), tuple(grouped_verts[e[1]])), fill="white", width=2) + + @classmethod + def is_editing_profile(cls): + return ProfileDecorator.installed