mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 10:06:47 +00:00
Integrate aggregate mode toggle with Bonsai's TAB edit mode override.
This commit is contained in:
committed by
Bruno Perdigão
parent
e9cc205ddd
commit
91d3b8161e
@@ -30,9 +30,6 @@ classes = (
|
||||
operator.BIM_OT_aggregate_unassign_object,
|
||||
operator.BIM_OT_break_link_to_other_aggregates,
|
||||
operator.BIM_OT_select_linked_aggregates,
|
||||
operator.BIM_OT_mode_set_aggregate,
|
||||
operator.BIM_OT_disable_mode_set_aggregate,
|
||||
operator.BIM_OT_toggle_mode_set_aggregate,
|
||||
prop.BIMObjectAggregateProperties,
|
||||
prop.NotEditingObjects,
|
||||
prop.BIMAggregateProperties,
|
||||
@@ -40,24 +37,12 @@ classes = (
|
||||
ui.BIM_PT_linked_aggregate,
|
||||
)
|
||||
|
||||
addon_keymaps = []
|
||||
|
||||
def register():
|
||||
bpy.types.Object.BIMObjectAggregateProperties = bpy.props.PointerProperty(type=prop.BIMObjectAggregateProperties)
|
||||
bpy.types.Scene.BIMAggregateProperties = bpy.props.PointerProperty(type=prop.BIMAggregateProperties)
|
||||
wm = bpy.context.window_manager
|
||||
if wm.keyconfigs.addon:
|
||||
km = wm.keyconfigs.addon.keymaps.new(name="Object Mode", space_type="EMPTY")
|
||||
kmi = km.keymap_items.new("bim.toggle_mode_set_aggregate", "TAB", "PRESS", ctrl=True)
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
|
||||
def unregister():
|
||||
del bpy.types.Object.BIMObjectAggregateProperties
|
||||
del bpy.types.Scene.BIMAggregateProperties
|
||||
wm = bpy.context.window_manager
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc:
|
||||
for km, kmi in addon_keymaps:
|
||||
km.keymap_items.remove(kmi)
|
||||
addon_keymaps.clear()
|
||||
|
||||
@@ -24,7 +24,6 @@ import bonsai.tool as tool
|
||||
import bonsai.core.aggregate as core
|
||||
import bonsai.core.spatial
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.bim.module.aggregate.decorator import AggregateModeDecorator
|
||||
|
||||
|
||||
class BIM_OT_aggregate_assign_object(bpy.types.Operator, tool.Ifc.Operator):
|
||||
@@ -371,106 +370,3 @@ class BIM_OT_select_linked_aggregates(bpy.types.Operator):
|
||||
obj.select_set(True)
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
class BIM_OT_toggle_mode_set_aggregate(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_description = "Toggle Aggregate mode on and off"
|
||||
bl_idname = "bim.toggle_mode_set_aggregate"
|
||||
bl_label = "IFC Toggle Mode Set Aggregate"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, is_invoke=True)
|
||||
|
||||
def _invoke(self, context, event):
|
||||
if not tool.Ifc.get():
|
||||
return {"FINISHED"}
|
||||
return self.execute(context)
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMAggregateProperties
|
||||
if props.in_aggregate_mode:
|
||||
AggregateModeDecorator.uninstall()
|
||||
BIM_OT_disable_mode_set_aggregate._execute(self, context)
|
||||
else:
|
||||
AggregateModeDecorator.install(context)
|
||||
BIM_OT_mode_set_aggregate._execute(self, context)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BIM_OT_mode_set_aggregate(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_description = "Switch from Object to Aggregate Edit mode"
|
||||
bl_idname = "bim.aggregate_mode_set_edit"
|
||||
bl_label = "IFC Aggregate Mode Set Edit"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, is_invoke=True)
|
||||
|
||||
def _invoke(self, context, event):
|
||||
if not tool.Ifc.get():
|
||||
return {"FINISHED"}
|
||||
return self.execute(context)
|
||||
|
||||
def _execute(self, context):
|
||||
active_object = context.active_object
|
||||
props = context.scene.BIMAggregateProperties
|
||||
if props.in_aggregate_mode:
|
||||
BIM_OT_disable_mode_set_aggregate._execute(self, context)
|
||||
|
||||
element = tool.Ifc.get_entity(active_object)
|
||||
if not element:
|
||||
return {"FINISHED"}
|
||||
aggregate = ifcopenshell.util.element.get_aggregate(element)
|
||||
parts = ifcopenshell.util.element.get_parts(element)
|
||||
if not aggregate and not parts:
|
||||
return {"FINISHED"}
|
||||
if not parts:
|
||||
parts = ifcopenshell.util.element.get_parts(aggregate)
|
||||
if parts:
|
||||
props.editing_aggregate = tool.Ifc.get_object(aggregate) if aggregate else tool.Ifc.get_object(element)
|
||||
parts_objs = [tool.Ifc.get_object(part) for part in parts]
|
||||
objs = []
|
||||
visible_objects = tool.Raycast.get_visible_objects(context)
|
||||
for obj in visible_objects:
|
||||
if obj.visible_in_viewport_get(context.space_data):
|
||||
objs.append(obj.original)
|
||||
for obj in objs:
|
||||
if obj.original not in parts_objs:
|
||||
if not obj.data:
|
||||
continue
|
||||
obj.original.display_type = "BOUNDS"
|
||||
obj.hide_select = True
|
||||
not_editing_obj = props.not_editing_objects.add()
|
||||
not_editing_obj.obj = obj.original
|
||||
|
||||
props.in_aggregate_mode = True
|
||||
return {"FINISHED"}
|
||||
|
||||
class BIM_OT_disable_mode_set_aggregate(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_description = "Switch from Aggregate to Object Edit mode"
|
||||
bl_idname = "bim.disable_aggregate_mode_set_edit"
|
||||
bl_label = "IFC Disable Aggregate Mode Set Edit"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, is_invoke=True)
|
||||
|
||||
def _invoke(self, context, event):
|
||||
if not tool.Ifc.get():
|
||||
return {"FINISHED"}
|
||||
return self.execute(context)
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMAggregateProperties
|
||||
objs = [o.obj for o in props.not_editing_objects]
|
||||
for obj in objs:
|
||||
obj.original.display_type = "TEXTURED"
|
||||
obj.hide_select = False
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
continue
|
||||
|
||||
props.in_aggregate_mode = False
|
||||
props.not_editing_objects.clear()
|
||||
|
||||
@@ -32,7 +32,7 @@ from bpy.props import (
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from bonsai.bim.module.aggregate.decorator import AggregateDecorator
|
||||
from bonsai.bim.module.aggregate.decorator import AggregateDecorator, AggregateModeDecorator
|
||||
|
||||
|
||||
def can_aggregate(relating_obj: bpy.types.Object, related_obj: bpy.types.Object) -> bool:
|
||||
@@ -81,6 +81,13 @@ def update_aggregate_decorator(self, context):
|
||||
AggregateDecorator.uninstall()
|
||||
|
||||
|
||||
def update_aggregate_mode_decorator(self, context):
|
||||
if self.in_aggregate_mode:
|
||||
AggregateModeDecorator.install(bpy.context)
|
||||
else:
|
||||
AggregateModeDecorator.uninstall()
|
||||
|
||||
|
||||
class BIMObjectAggregateProperties(PropertyGroup):
|
||||
is_editing: BoolProperty(name="Is Editing")
|
||||
relating_object: PointerProperty(name="Relating Whole", type=bpy.types.Object, poll=poll_relating_object)
|
||||
@@ -90,12 +97,14 @@ class BIMObjectAggregateProperties(PropertyGroup):
|
||||
type=bpy.types.Object,
|
||||
poll=poll_related_object,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class NotEditingObjects(bpy.types.PropertyGroup):
|
||||
obj: PointerProperty(type=bpy.types.Object)
|
||||
|
||||
|
||||
|
||||
class BIMAggregateProperties(PropertyGroup):
|
||||
in_aggregate_mode: BoolProperty(name="In Edit Mode")
|
||||
in_aggregate_mode: BoolProperty(name="In Edit Mode", update=update_aggregate_mode_decorator)
|
||||
editing_aggregate: PointerProperty(name="Editing Aggregate", type=bpy.types.Object)
|
||||
not_editing_objects: CollectionProperty(type=NotEditingObjects)
|
||||
aggregate_decorator: BoolProperty(
|
||||
|
||||
@@ -86,6 +86,15 @@ def add_part_to_object(
|
||||
assign_object(ifc, aggregator, collector, relating_obj=obj, related_obj=part_obj)
|
||||
blender.set_active_object(obj)
|
||||
|
||||
def enable_aggregate_mode(aggregator: tool.Aggregate, obj: bpy.types.Object,):
|
||||
if aggregator.get_aggregate_mode():
|
||||
disable_aggregate_mode(aggregator)
|
||||
|
||||
aggregator.enable_aggregate_mode(obj)
|
||||
|
||||
def disable_aggregate_mode(aggregator: tool.Aggregate):
|
||||
aggregator.disable_aggregate_mode()
|
||||
|
||||
|
||||
class IncompatibleAggregateError(Exception):
|
||||
pass
|
||||
|
||||
@@ -106,3 +106,56 @@ class Aggregate(bonsai.core.tool.Aggregate):
|
||||
if constraint:
|
||||
bpy.context.view_layer.objects.active = part
|
||||
bpy.ops.constraint.apply(constraint=constraint.name)
|
||||
|
||||
@classmethod
|
||||
def get_aggregate_mode(cls):
|
||||
return bpy.context.scene.BIMAggregateProperties.in_aggregate_mode
|
||||
|
||||
@classmethod
|
||||
def enable_aggregate_mode(cls, active_object: bpy.types.Object):
|
||||
context = bpy.context
|
||||
props = context.scene.BIMAggregateProperties
|
||||
|
||||
element = tool.Ifc.get_entity(active_object)
|
||||
if not element:
|
||||
return {"FINISHED"}
|
||||
aggregate = ifcopenshell.util.element.get_aggregate(element)
|
||||
parts = ifcopenshell.util.element.get_parts(element)
|
||||
if not aggregate and not parts:
|
||||
return {"FINISHED"}
|
||||
if not parts:
|
||||
parts = ifcopenshell.util.element.get_parts(aggregate)
|
||||
if parts:
|
||||
props.editing_aggregate = tool.Ifc.get_object(aggregate) if aggregate else tool.Ifc.get_object(element)
|
||||
parts_objs = [tool.Ifc.get_object(part) for part in parts]
|
||||
objs = []
|
||||
visible_objects = tool.Raycast.get_visible_objects(context)
|
||||
for obj in visible_objects:
|
||||
if obj.visible_in_viewport_get(context.space_data):
|
||||
objs.append(obj.original)
|
||||
for obj in objs:
|
||||
if obj.original not in parts_objs:
|
||||
if not obj.data and not tool.Ifc.get_entity(obj.original).is_a("IfcElementAssembly"):
|
||||
continue
|
||||
obj.original.display_type = "BOUNDS"
|
||||
obj.hide_select = True
|
||||
not_editing_obj = props.not_editing_objects.add()
|
||||
not_editing_obj.obj = obj.original
|
||||
|
||||
props.in_aggregate_mode = True
|
||||
return {"FINISHED"}
|
||||
|
||||
@classmethod
|
||||
def disable_aggregate_mode(cls):
|
||||
context = bpy.context
|
||||
props = context.scene.BIMAggregateProperties
|
||||
objs = [o.obj for o in props.not_editing_objects]
|
||||
for obj in objs:
|
||||
obj.original.display_type = "TEXTURED"
|
||||
obj.hide_select = False
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
continue
|
||||
|
||||
props.in_aggregate_mode = False
|
||||
props.not_editing_objects.clear()
|
||||
|
||||
Reference in New Issue
Block a user