mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-23 21:58:46 +00:00
fix container operators after a9a4b0c + mention a limitation
If you would select container1 + obj1 with intention to copy obj1 to container1 - running bim.copy_to_container would also copy container1. Similar issue for referencing/dereferncing structures in other structures in ifc4x3.
This commit is contained in:
@@ -29,11 +29,21 @@ import blenderbim.bim.handler
|
|||||||
class ReferenceStructure(bpy.types.Operator, tool.Ifc.Operator):
|
class ReferenceStructure(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.reference_structure"
|
bl_idname = "bim.reference_structure"
|
||||||
bl_label = "Reference Structure"
|
bl_label = "Reference Structure"
|
||||||
|
bl_description = (
|
||||||
|
"Reference selected objects from all selected structures.\n\n"
|
||||||
|
"Currently we do not support referencing structures in other structures "
|
||||||
|
"though it is allowed in IFC4X3"
|
||||||
|
)
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
|
objs = tool.Spatial.get_selected_objects_without_containers()
|
||||||
|
if not objs:
|
||||||
|
self.report({"INFO"}, "No non-spatial objects are selected.")
|
||||||
|
return
|
||||||
|
|
||||||
containers = tool.Spatial.get_selected_containers()
|
containers = tool.Spatial.get_selected_containers()
|
||||||
for obj in context.selected_objects:
|
for obj in objs:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
if not element:
|
if not element:
|
||||||
continue
|
continue
|
||||||
@@ -44,11 +54,21 @@ class ReferenceStructure(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
class DereferenceStructure(bpy.types.Operator, tool.Ifc.Operator):
|
class DereferenceStructure(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.dereference_structure"
|
bl_idname = "bim.dereference_structure"
|
||||||
bl_label = "Dereference Structure"
|
bl_label = "Dereference Structure"
|
||||||
|
bl_description = (
|
||||||
|
"Dereference selected objects from all selected structures.\n\n"
|
||||||
|
"Currently we do not support referencing structures in other structures "
|
||||||
|
"though it is allowed in IFC4X3"
|
||||||
|
)
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
|
objs = tool.Spatial.get_selected_objects_without_containers()
|
||||||
|
if not objs:
|
||||||
|
self.report({"INFO"}, "No non-spatial objects are selected.")
|
||||||
|
return
|
||||||
|
|
||||||
containers = tool.Spatial.get_selected_containers()
|
containers = tool.Spatial.get_selected_containers()
|
||||||
for obj in context.selected_objects:
|
for obj in objs:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
if not element:
|
if not element:
|
||||||
continue
|
continue
|
||||||
@@ -100,29 +120,36 @@ class RemoveContainer(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
class CopyToContainer(bpy.types.Operator, tool.Ifc.Operator):
|
class CopyToContainer(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
"""
|
"""
|
||||||
Copies selected 3D elements in the viewport to checkmarked spatial containers
|
Copies selected 3D elements in the viewport to the selected spatial containers
|
||||||
|
|
||||||
Example: bulk copy a wall to multiple storeys
|
Example: bulk copy a wall to multiple storeys
|
||||||
|
|
||||||
1. Select one or more 3D elements in the viewport
|
1. Select one or more 3D elements in the viewport
|
||||||
2. Enable the checkmark next to one or more containers in the container list below to select it
|
2. Select one or more spatial containers in the viewport
|
||||||
3. Press this button
|
3. Press this button
|
||||||
4. The copied elements will have a new position relative to the destination containers
|
4. The copied elements will have a new position relative to the destination containers
|
||||||
"""
|
|
||||||
|
Copying containers to other containers currently is not supported."""
|
||||||
|
|
||||||
bl_idname = "bim.copy_to_container"
|
bl_idname = "bim.copy_to_container"
|
||||||
bl_label = "Copy To Container"
|
bl_label = "Copy To Container"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
# Track decompositions so they can be recreated after the operation
|
objs = tool.Spatial.get_selected_objects_without_containers()
|
||||||
relationships = tool.Root.get_decomposition_relationships(context.selected_objects)
|
if not objs:
|
||||||
old_to_new = {}
|
self.report({"INFO"}, "No non-spatial objects are selected.")
|
||||||
|
return
|
||||||
|
|
||||||
containers = tool.Spatial.get_selected_containers()
|
containers = tool.Spatial.get_selected_containers()
|
||||||
for obj in context.selected_objects:
|
# Track decompositions so they can be recreated after the operation
|
||||||
|
relationships = tool.Root.get_decomposition_relationships(objs)
|
||||||
|
old_to_new = {}
|
||||||
|
for obj in objs:
|
||||||
result_objs = core.copy_to_container(tool.Ifc, tool.Collector, tool.Spatial, obj=obj, containers=containers)
|
result_objs = core.copy_to_container(tool.Ifc, tool.Collector, tool.Spatial, obj=obj, containers=containers)
|
||||||
if result_objs:
|
if result_objs:
|
||||||
old_to_new[tool.Ifc.get_entity(obj)] = result_objs
|
old_to_new[tool.Ifc.get_entity(obj)] = result_objs
|
||||||
|
|
||||||
# Recreate decompositions
|
# Recreate decompositions
|
||||||
tool.Root.recreate_decompositions(relationships, old_to_new)
|
tool.Root.recreate_decompositions(relationships, old_to_new)
|
||||||
blenderbim.bim.handler.refresh_ui_data()
|
blenderbim.bim.handler.refresh_ui_data()
|
||||||
|
|||||||
@@ -866,3 +866,18 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
if (element := tool.Ifc.get_entity(obj)) and tool.Root.is_spatial_element(element):
|
if (element := tool.Ifc.get_entity(obj)) and tool.Root.is_spatial_element(element):
|
||||||
results.append(element)
|
results.append(element)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_selected_objects_without_containers(cls) -> list[bpy.types.Object]:
|
||||||
|
"""Get selected objects skipping spatial elements.
|
||||||
|
|
||||||
|
Useful for operators that are using selected objects to identify selected containers.
|
||||||
|
Note that those operators are typically have a limitation since they can't tell
|
||||||
|
objects to operate on from containers that should be used in the operation.
|
||||||
|
|
||||||
|
E.g. we cannot bim.copy_to_container containers to other containers."""
|
||||||
|
results: list[bpy.types.Object] = []
|
||||||
|
for obj in tool.Blender.get_selected_objects():
|
||||||
|
if (element := tool.Ifc.get_entity(obj)) and not tool.Root.is_spatial_element(element):
|
||||||
|
results.append(obj)
|
||||||
|
return results
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ Scenario: Copy to container
|
|||||||
And I set "scene.BIMRootProperties.ifc_product" to "IfcElement"
|
And I set "scene.BIMRootProperties.ifc_product" to "IfcElement"
|
||||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||||
And I press "bim.assign_class"
|
And I press "bim.assign_class"
|
||||||
And the object "IfcWall/Cube" is selected
|
And the object "IfcSite/My Site" is selected
|
||||||
|
And additionally the object "IfcWall/Cube" is selected
|
||||||
And I press "bim.enable_editing_container"
|
And I press "bim.enable_editing_container"
|
||||||
When I set "scene.BIMSpatialProperties.containers[0].is_selected" to "True"
|
When I press "bim.copy_to_container"
|
||||||
And I press "bim.copy_to_container"
|
|
||||||
Then the object "IfcWall/Cube.001" is in the collection "IfcSite/My Site"
|
Then the object "IfcWall/Cube.001" is in the collection "IfcSite/My Site"
|
||||||
|
|
||||||
Scenario: Reference structure
|
Scenario: Reference structure
|
||||||
|
|||||||
Reference in New Issue
Block a user