mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 10:06:47 +00:00
Fix #3357. Remove Shift-E for parametric objects (superseded by tab) and you can now extend to anything not just slabs.
This Shift-E still needs more polish as we figure out the best hotkeys and what's most natural to users when they select different combinations of objects, so expect the conditionals that govern when Shift-E does things to still change in the future.
This commit is contained in:
@@ -66,12 +66,13 @@ classes = (
|
||||
product.SetActiveType,
|
||||
workspace.Hotkey,
|
||||
workspace.BIM_MT_add_representation_item,
|
||||
wall.AddWallsFromSlab,
|
||||
wall.AlignWall,
|
||||
wall.ChangeExtrusionDepth,
|
||||
wall.ChangeExtrusionXAngle,
|
||||
wall.ChangeLayerLength,
|
||||
wall.AddWallsFromSlab,
|
||||
wall.DrawPolylineWall,
|
||||
wall.ExtendWallsToUnderside,
|
||||
wall.FlipWall,
|
||||
wall.MergeWall,
|
||||
wall.RecalculateWall,
|
||||
|
||||
@@ -36,7 +36,7 @@ import bonsai.core.geometry
|
||||
import bonsai.core.model as core
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from math import pi, sin, cos, degrees, radians
|
||||
from math import pi, sin, cos, degrees
|
||||
from mathutils import Vector, Matrix
|
||||
from bonsai.bim.module.model.opening import FilledOpeningGenerator
|
||||
from bonsai.bim.module.model.decorator import PolylineDecorator, ProductDecorator
|
||||
@@ -58,6 +58,26 @@ class UnjoinWalls(bpy.types.Operator, tool.Ifc.Operator):
|
||||
core.unjoin_walls(tool.Ifc, tool.Blender, tool.Geometry, DumbWallJoiner(), tool.Model)
|
||||
|
||||
|
||||
class ExtendWallsToUnderside(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.extend_walls_to_underside"
|
||||
bl_label = "Extend Walls To Underside"
|
||||
bl_description = "Extend and clip selected walls at the bottom faces of an object"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
slab = None
|
||||
walls = []
|
||||
if (obj := tool.Blender.get_active_object(is_selected=True)) and (element := tool.Ifc.get_entity(obj)):
|
||||
slab = obj
|
||||
for obj in tool.Blender.get_selected_objects(include_active=False):
|
||||
if (element := tool.Ifc.get_entity(obj)) and tool.Model.get_usage_type(element) == "LAYER2":
|
||||
walls.append(obj)
|
||||
if slab and walls:
|
||||
core.extend_wall_to_slab(tool.Ifc, tool.Geometry, tool.Model, slab, walls)
|
||||
else:
|
||||
self.report({"ERROR"}, "Please select at least one LAYER2 element and an active element")
|
||||
|
||||
|
||||
class AlignWall(bpy.types.Operator):
|
||||
bl_idname = "bim.align_wall"
|
||||
bl_label = "Align Wall"
|
||||
|
||||
@@ -675,13 +675,12 @@ class CreateObjectUI:
|
||||
for _ in range(4):
|
||||
row2.operator("bim.launch_type_manager", text="", emboss=False)
|
||||
else:
|
||||
op = box.operator(
|
||||
box.operator(
|
||||
"bim.load_type_thumbnails",
|
||||
text="",
|
||||
icon="FILE_REFRESH",
|
||||
emboss=False,
|
||||
)
|
||||
op.ifc_class = ifc_class
|
||||
|
||||
row = box.row(align=True)
|
||||
row.alignment = "CENTER"
|
||||
@@ -848,7 +847,7 @@ class EditObjectUI:
|
||||
elif AuthoringData.data["active_material_usage"] == "LAYER3":
|
||||
if "LAYER2" in AuthoringData.data["selected_material_usages"]:
|
||||
row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row
|
||||
add_layout_hotkey_operator(cls.layout, "Extend Wall To Slab", "S_E", "", ui_context)
|
||||
add_layout_hotkey_operator(cls.layout, "Extend To Underside", "S_E", "", ui_context)
|
||||
if AuthoringData.data["relating_type_data"].get("usage") == "LAYER2":
|
||||
row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row
|
||||
add_layout_hotkey_operator(
|
||||
@@ -907,6 +906,11 @@ class EditObjectUI:
|
||||
row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row
|
||||
add_layout_hotkey_operator(row, "Rotate 90", "S_R", bpy.ops.bim.rotate_90.__doc__, ui_context)
|
||||
|
||||
else:
|
||||
if "LAYER2" in AuthoringData.data["selected_material_usages"]:
|
||||
row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row
|
||||
add_layout_hotkey_operator(cls.layout, "Extend To Undersideb", "S_E", "", ui_context)
|
||||
|
||||
if AuthoringData.data["is_flippable_element"]:
|
||||
cls.draw_flip(ui_context, row)
|
||||
|
||||
@@ -1167,23 +1171,6 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if not bpy.context.selected_objects or not (active_object := bpy.context.active_object):
|
||||
return
|
||||
|
||||
# NOTE: placing it before the other operations because railing can also be SweptSolid
|
||||
# and it might conflict with one of the conditions below
|
||||
if (
|
||||
tool.Model.is_parametric_railing_active()
|
||||
and not tool.Model.get_railing_props(active_object).is_editing_path
|
||||
):
|
||||
bpy.ops.bim.enable_editing_railing_path()
|
||||
return
|
||||
|
||||
elif tool.Model.is_parametric_roof_active() and not tool.Model.get_roof_props(active_object).is_editing_path:
|
||||
# undo the unselection done above because roof has no usage type
|
||||
bpy.ops.bim.enable_editing_roof_path()
|
||||
return
|
||||
|
||||
elif tool.Model.is_parametric_window_active() or tool.Model.is_parametric_door_active():
|
||||
return
|
||||
|
||||
selected_usages: dict[str, list[bpy.types.Object]] = {}
|
||||
for obj in bpy.context.selected_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
@@ -1194,11 +1181,6 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if not usage:
|
||||
representation = tool.Geometry.get_active_representation(obj)
|
||||
representation = tool.Geometry.resolve_mapped_representation(representation)
|
||||
if representation and representation.RepresentationType == "SweptSolid":
|
||||
usage = "SWEPTSOLID"
|
||||
else:
|
||||
obj.select_set(False)
|
||||
continue
|
||||
selected_usages.setdefault(usage, []).append(obj)
|
||||
|
||||
if len(bpy.context.selected_objects) == 1:
|
||||
@@ -1227,9 +1209,6 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
elif self.active_material_usage == "PROFILE":
|
||||
# Extend PROFILE to cursor
|
||||
bpy.ops.bim.extend_profile(join_type="T")
|
||||
else:
|
||||
# Edit SWEPTSOLID profile (assuming single profile for now)
|
||||
bpy.ops.bim.enable_editing_extrusion_profile()
|
||||
|
||||
elif self.active_material_usage == "LAYER2" and selected_usages.get("PROFILE", []):
|
||||
# Extend PROFILEs to LAYER2
|
||||
@@ -1237,22 +1216,6 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
[o.select_set(False) for o in selected_usages.get("LAYER2", []) if o != bpy.context.active_object]
|
||||
bpy.ops.bim.extend_profile(join_type="T")
|
||||
|
||||
elif self.active_material_usage == "LAYER3" and selected_usages.get("LAYER2", []):
|
||||
# Extend LAYER2s to LAYER3
|
||||
[o.select_set(False) for o in selected_usages.get("PROFILE", [])]
|
||||
[o.select_set(False) for o in selected_usages.get("LAYER3", []) if o != bpy.context.active_object]
|
||||
slab = None
|
||||
walls = []
|
||||
if (obj := tool.Blender.get_active_object(is_selected=True)) and (element := tool.Ifc.get_entity(obj)) and tool.Model.get_usage_type(element) == "LAYER3":
|
||||
slab = obj
|
||||
for obj in tool.Blender.get_selected_objects(include_active=False):
|
||||
if (element := tool.Ifc.get_entity(obj)) and tool.Model.get_usage_type(element) == "LAYER2":
|
||||
walls.append(obj)
|
||||
if slab and walls:
|
||||
core.extend_wall_to_slab(tool.Ifc, tool.Geometry, tool.Model, slab, walls)
|
||||
else:
|
||||
self.report({"ERROR"}, "Please select at least one LAYER2 element and an active LAYER3 element")
|
||||
|
||||
elif self.active_material_usage == "LAYER2":
|
||||
# Extend LAYER2s to LAYER2
|
||||
[o.select_set(False) for o in selected_usages.get("LAYER3", [])]
|
||||
@@ -1268,6 +1231,9 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
[o.select_set(False) for o in selected_usages.get("LAYER2", [])]
|
||||
bpy.ops.bim.extend_profile(join_type="T")
|
||||
|
||||
else:
|
||||
bpy.ops.bim.extend_walls_to_underside()
|
||||
|
||||
def hotkey_S_F(self):
|
||||
if not bpy.context.selected_objects:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user