mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
Orientation slot feature now has limited scope
No support for setting up blender orientation slots for multiple containers or for non-spatial elements. Setting the default container switches to an appropriate orientation slot if the orientation of this container isn't global.
This commit is contained in:
@@ -334,7 +334,7 @@ class SetDefaultContainer(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
core.set_default_container(tool.Spatial, container=tool.Ifc.get().by_id(self.container))
|
core.set_default_container(tool.Spatial, container=tool.Ifc.get().by_id(self.container))
|
||||||
core.set_orientation_slot(spatial=tool.Spatial, product=tool.Ifc.get().by_id(self.container))
|
core.set_orientation_slot(tool.Spatial, container=tool.Ifc.get().by_id(self.container))
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ def import_spatial_decomposition(spatial: tool.Spatial) -> None:
|
|||||||
spatial.import_spatial_decomposition()
|
spatial.import_spatial_decomposition()
|
||||||
|
|
||||||
|
|
||||||
def set_orientation_slot(spatial: tool.Spatial, product: ifcopenshell.entity_instance) -> None:
|
def set_orientation_slot(spatial: tool.Spatial, container: ifcopenshell.entity_instance) -> None:
|
||||||
spatial.create_orientation_slots([product], use=True)
|
spatial.create_orientation_slot(container)
|
||||||
|
|
||||||
|
|
||||||
def contract_container(spatial: tool.Spatial, container: ifcopenshell.entity_instance) -> None:
|
def contract_container(spatial: tool.Spatial, container: ifcopenshell.entity_instance) -> None:
|
||||||
|
|||||||
@@ -502,65 +502,49 @@ class Spatial(bonsai.core.tool.Spatial):
|
|||||||
cls.import_spatial_element(child, level_index + 1)
|
cls.import_spatial_element(child, level_index + 1)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_orientation_slots(cls, products: list[ifcopenshell.entity_instance], use: bool = False) -> None:
|
def create_orientation_slot(cls, container: ifcopenshell.entity_instance) -> None:
|
||||||
active_slot = bpy.context.scene.transform_orientation_slots[0]
|
active_slot = bpy.context.scene.transform_orientation_slots[0]
|
||||||
initial_orientation = active_slot.type
|
placement = container.ObjectPlacement
|
||||||
|
combined_matrix = ifcopenshell.util.placement.get_local_placement(placement)[:3, :3]
|
||||||
|
|
||||||
for product in products:
|
if np.allclose(combined_matrix, np.eye(3), atol=1e-6):
|
||||||
placement = product.ObjectPlacement
|
# this spatial element has global orientation
|
||||||
combined_matrix = ifcopenshell.util.placement.get_local_placement(placement)[:3, :3]
|
active_slot.type = "GLOBAL"
|
||||||
if np.allclose(combined_matrix, np.eye(3), atol=1e-6):
|
return
|
||||||
# this product has global orientation
|
elif (
|
||||||
active_slot.type = "GLOBAL"
|
hasattr(container, "Decomposes")
|
||||||
continue
|
and container.Decomposes
|
||||||
elif (
|
and hasattr(container.Decomposes[0].RelatingObject, "ObjectPlacement")
|
||||||
hasattr(product, "Decomposes")
|
):
|
||||||
and product.Decomposes
|
# this spatial element is part of a decomposition
|
||||||
and hasattr(product.Decomposes[0].RelatingObject, "ObjectPlacement")
|
parent_placement = container.Decomposes[0].RelatingObject.ObjectPlacement
|
||||||
):
|
parent_matrix = ifcopenshell.util.placement.get_local_placement(parent_placement)[:3, :3]
|
||||||
# this product is part of a decomposition
|
if np.allclose(combined_matrix, parent_matrix, atol=1e-6):
|
||||||
parent_placement = product.Decomposes[0].RelatingObject.ObjectPlacement
|
# this spatial element has the same orientation as its parent
|
||||||
parent_matrix = ifcopenshell.util.placement.get_local_placement(parent_placement)[:3, :3]
|
cls.create_orientation_slot(container=container.Decomposes[0].RelatingObject)
|
||||||
if np.allclose(combined_matrix, parent_matrix, atol=1e-6):
|
return
|
||||||
# this product has the same orientation as its parent
|
|
||||||
cls.create_orientation_slots(products=[product.Decomposes[0].RelatingObject], use=use)
|
|
||||||
continue
|
|
||||||
elif (
|
|
||||||
hasattr(product, "ContainedInStructure")
|
|
||||||
and product.ContainedInStructure
|
|
||||||
and hasattr(product.ContainedInStructure[0].RelatingStructure, "Objectplacement")
|
|
||||||
):
|
|
||||||
# contained in a spatial element
|
|
||||||
parent_placement = product.ContainedInStructure[0].RelatingStructure.ObjectPlacement
|
|
||||||
parent_matrix = ifcopenshell.util.placement.get_local_placement(parent_placement)[:3, :3]
|
|
||||||
if np.allclose(combined_matrix, parent_matrix, atol=1e-6):
|
|
||||||
# this product has the same orientation as its container
|
|
||||||
cls.create_orientation_slots(products=[product.ContainedInStructure[0].RelatingStructure], use=use)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# this product has a unique orientation
|
# this spatial element has a unique orientation
|
||||||
orientation_name = product.is_a() + "/" + product.Name
|
orientation_name = container.is_a() + "/" + container.Name
|
||||||
|
|
||||||
# stash selected objects
|
# stash selected objects
|
||||||
active_object = bpy.context.view_layer.objects.active
|
active_object = bpy.context.view_layer.objects.active
|
||||||
selected_objects = list(bpy.context.view_layer.objects.selected)
|
selected_objects = list(bpy.context.view_layer.objects.selected)
|
||||||
# bpy.ops.transform.create_orientation() requires a dummy object
|
|
||||||
bpy.ops.object.empty_add(type="PLAIN_AXES")
|
|
||||||
|
|
||||||
bpy.ops.transform.create_orientation(name=orientation_name, overwrite=True)
|
# bpy.ops.transform.create_orientation() requires a dummy object
|
||||||
active_slot.type = orientation_name
|
bpy.ops.object.empty_add(type="PLAIN_AXES")
|
||||||
active_slot.custom_orientation.matrix = np.linalg.inv(combined_matrix)
|
bpy.ops.transform.create_orientation(name=orientation_name, overwrite=True)
|
||||||
|
active_slot.type = orientation_name
|
||||||
|
active_slot.custom_orientation.matrix = np.linalg.inv(combined_matrix)
|
||||||
|
|
||||||
# delete dummy object
|
# delete dummy object
|
||||||
bpy.ops.object.delete()
|
bpy.ops.object.delete()
|
||||||
# reinstate selected objects
|
|
||||||
for obj in selected_objects:
|
|
||||||
obj.select_set(True)
|
|
||||||
if active_object:
|
|
||||||
bpy.context.view_layer.objects.active = active_object
|
|
||||||
|
|
||||||
if not use:
|
# reinstate selected objects
|
||||||
active_slot.type = initial_orientation
|
for obj in selected_objects:
|
||||||
|
obj.select_set(True)
|
||||||
|
if active_object:
|
||||||
|
bpy.context.view_layer.objects.active = active_object
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def edit_container_attributes(cls, entity: ifcopenshell.entity_instance) -> None:
|
def edit_container_attributes(cls, entity: ifcopenshell.entity_instance) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user