mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 01:10:01 +00:00
Fix #2847. You can now join meshes and extrusions together.
This commit is contained in:
@@ -27,6 +27,7 @@ classes = (
|
|||||||
operator.OverrideDelete,
|
operator.OverrideDelete,
|
||||||
operator.OverrideDuplicateMove,
|
operator.OverrideDuplicateMove,
|
||||||
operator.OverrideDuplicateMoveLinked,
|
operator.OverrideDuplicateMoveLinked,
|
||||||
|
operator.OverrideJoin,
|
||||||
operator.OverrideModeSetEdit,
|
operator.OverrideModeSetEdit,
|
||||||
operator.OverrideModeSetObject,
|
operator.OverrideModeSetObject,
|
||||||
operator.OverrideOutlinerDelete,
|
operator.OverrideOutlinerDelete,
|
||||||
@@ -58,6 +59,7 @@ def register():
|
|||||||
wm = bpy.context.window_manager
|
wm = bpy.context.window_manager
|
||||||
if wm.keyconfigs.addon:
|
if wm.keyconfigs.addon:
|
||||||
km = wm.keyconfigs.addon.keymaps.new(name="Object Mode", space_type="EMPTY")
|
km = wm.keyconfigs.addon.keymaps.new(name="Object Mode", space_type="EMPTY")
|
||||||
|
kmi = km.keymap_items.new("bim.override_object_join", "J", "PRESS", ctrl=True)
|
||||||
kmi = km.keymap_items.new("bim.override_object_duplicate_move", "D", "PRESS", shift=True)
|
kmi = km.keymap_items.new("bim.override_object_duplicate_move", "D", "PRESS", shift=True)
|
||||||
kmi.properties.is_interactive = True
|
kmi.properties.is_interactive = True
|
||||||
kmi = km.keymap_items.new("bim.override_object_duplicate_move_linked", "D", "PRESS", alt=True)
|
kmi = km.keymap_items.new("bim.override_object_duplicate_move_linked", "D", "PRESS", alt=True)
|
||||||
|
|||||||
@@ -613,6 +613,93 @@ class OverrideDuplicateMoveLinked(bpy.types.Operator):
|
|||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class OverrideJoin(bpy.types.Operator, Operator):
|
||||||
|
bl_idname = "bim.override_object_join"
|
||||||
|
bl_label = "IFC Join"
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
if not tool.Ifc.get():
|
||||||
|
return bpy.ops.object.join()
|
||||||
|
|
||||||
|
if not context.active_object:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.target = context.active_object
|
||||||
|
self.target_element = tool.Ifc.get_entity(self.target)
|
||||||
|
if self.target_element:
|
||||||
|
return self.join_ifc_obj()
|
||||||
|
return self.join_blender_obj()
|
||||||
|
|
||||||
|
def join_ifc_obj(self):
|
||||||
|
representation = tool.Ifc.get().by_id(self.target.data.BIMMeshProperties.ifc_definition_id)
|
||||||
|
if representation.RepresentationType in ("Tessellation", "Brep"):
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
if obj == self.target:
|
||||||
|
continue
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if element:
|
||||||
|
tool.Ifc.delete(element)
|
||||||
|
bpy.ops.object.join()
|
||||||
|
bpy.ops.bim.update_representation(obj=self.target.name, ifc_representation_class="")
|
||||||
|
elif representation.RepresentationType == "SweptSolid":
|
||||||
|
target_placement = np.array(self.target.matrix_world)
|
||||||
|
items = list(representation.Items)
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
if obj == self.target:
|
||||||
|
continue
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
|
||||||
|
# Non IFC elements cannot be join since we cannot guarantee SweptSolid compliance
|
||||||
|
if not element:
|
||||||
|
obj.select_set(False)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Only objects of the same representation type can be joined
|
||||||
|
obj_rep = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||||
|
if obj_rep.RepresentationType != "SweptSolid":
|
||||||
|
obj.select_set(False)
|
||||||
|
continue
|
||||||
|
|
||||||
|
placement = np.array(obj.matrix_world)
|
||||||
|
|
||||||
|
for item in obj_rep.Items:
|
||||||
|
copied_item = ifcopenshell.util.element.copy_deep(tool.Ifc.get(), item)
|
||||||
|
if copied_item.Position:
|
||||||
|
position = ifcopenshell.util.placement.get_axis2placement(copied_item.Position)
|
||||||
|
else:
|
||||||
|
position = np.eye(4)
|
||||||
|
position = placement @ position
|
||||||
|
position = np.linalg.inv(target_placement) @ position
|
||||||
|
copied_item.Position = tool.Ifc.get().createIfcAxis2Placement3D(
|
||||||
|
tool.Ifc.get().createIfcCartesianPoint([float(n) for n in position[:, 3][:3]]),
|
||||||
|
tool.Ifc.get().createIfcDirection([float(n) for n in position[:, 2][:3]]),
|
||||||
|
tool.Ifc.get().createIfcDirection([float(n) for n in position[:, 0][:3]]),
|
||||||
|
)
|
||||||
|
items.append(copied_item)
|
||||||
|
tool.Ifc.delete(element)
|
||||||
|
representation.Items = items
|
||||||
|
bpy.ops.object.join()
|
||||||
|
core.switch_representation(
|
||||||
|
tool.Ifc,
|
||||||
|
tool.Geometry,
|
||||||
|
obj=self.target,
|
||||||
|
representation=representation,
|
||||||
|
should_reload=True,
|
||||||
|
is_global=True,
|
||||||
|
should_sync_changes_first=False,
|
||||||
|
apply_openings=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def join_blender_obj(self):
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
if obj == self.target:
|
||||||
|
continue
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if element:
|
||||||
|
tool.Ifc.delete(element)
|
||||||
|
bpy.ops.object.join()
|
||||||
|
|
||||||
|
|
||||||
class OverridePasteBuffer(bpy.types.Operator):
|
class OverridePasteBuffer(bpy.types.Operator):
|
||||||
bl_idname = "bim.override_paste_buffer"
|
bl_idname = "bim.override_paste_buffer"
|
||||||
bl_label = "IFC Paste BIM Objects"
|
bl_label = "IFC Paste BIM Objects"
|
||||||
|
|||||||
Reference in New Issue
Block a user