WIP port add aggregate and remove container. See #1222.

This commit is contained in:
Dion Moult
2021-01-08 11:41:54 +11:00
parent afbdedaee8
commit 2d061f63fb
8 changed files with 108 additions and 13 deletions
@@ -5,6 +5,7 @@ classes = (
operator.AssignObject,
operator.EnableEditingAggregate,
operator.DisableEditingAggregate,
operator.AddAggregate,
ui.BIM_PT_aggregate,
)
@@ -28,15 +28,19 @@ class AssignObject(bpy.types.Operator):
Data.load(props.ifc_definition_id)
bpy.ops.bim.disable_editing_aggregate(obj=related_object.name)
related_collection = bpy.data.collections.get(related_object.name)
if related_collection:
relating_collection = bpy.data.collections.get(relating_object.name)
self.remove_collection(bpy.context.scene.collection, related_collection)
spatial_collection = bpy.data.collections.get(related_object.name)
relating_collection = bpy.data.collections.get(relating_object.name)
if spatial_collection:
self.remove_collection(bpy.context.scene.collection, spatial_collection)
for collection in bpy.data.collections:
if collection == relating_collection:
collection.children.link(related_collection)
collection.children.link(spatial_collection)
continue
self.remove_collection(collection, related_collection)
self.remove_collection(collection, spatial_collection)
else:
for collection in related_object.users_collection:
collection.objects.unlink(related_object)
relating_collection.objects.link(related_object)
return {"FINISHED"}
def remove_collection(self, parent, child):
@@ -65,3 +69,19 @@ class DisableEditingAggregate(bpy.types.Operator):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
obj.BIMObjectProperties.is_editing_aggregate = False
return {"FINISHED"}
class AddAggregate(bpy.types.Operator):
bl_idname = "bim.add_aggregate"
bl_label = "Add Aggregate"
obj: bpy.props.StringProperty()
def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
aggregate_collection = bpy.data.collections.new("IfcElementAssembly/Assembly")
bpy.context.scene.collection.children.link(aggregate_collection)
aggregate = bpy.data.objects.new("Assembly", None)
aggregate_collection.objects.link(aggregate)
bpy.ops.bim.assign_class(obj=aggregate.name, ifc_class="IfcElementAssembly")
bpy.ops.bim.assign_object(related_object=obj.name, relating_object=aggregate.name)
return {"FINISHED"}
@@ -41,3 +41,4 @@ class BIM_PT_aggregate(Panel):
name = "This object is not part of an aggregation"
row.label(text=name)
row.operator("bim.enable_editing_aggregate", icon="GREASEPENCIL", text="")
row.operator("bim.add_aggregate", icon="ADD", text="")
@@ -152,7 +152,7 @@ class AssignClass(bpy.types.Operator):
def assign_potential_spatial_container(self, obj):
for collection in obj.users_collection:
if "Ifc" not in collection.name:
if "Ifc" not in collection.name or collection.name == obj.name:
continue
bpy.ops.bim.assign_container(relating_structure=collection.name, related_element=obj.name)
break
@@ -3,6 +3,7 @@ from . import ui, operator
classes = (
operator.AssignContainer,
operator.RemoveContainer,
operator.EnableEditingContainer,
operator.DisableEditingContainer,
ui.BIM_PT_spatial,
@@ -1,5 +1,6 @@
import bpy
import blenderbim.bim.module.spatial.assign_container as assign_container
import blenderbim.bim.module.spatial.remove_container as remove_container
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.spatial.data import Data
@@ -12,9 +13,13 @@ class AssignContainer(bpy.types.Operator):
def execute(self, context):
self.file = IfcStore.get_file()
related_element = bpy.data.objects.get(self.related_element) if self.related_element else bpy.context.active_object
related_element = (
bpy.data.objects.get(self.related_element) if self.related_element else bpy.context.active_object
)
props = related_element.BIMObjectProperties
relating_structure = bpy.data.objects.get(self.relating_structure) if self.relating_structure else props.relating_structure
relating_structure = (
bpy.data.objects.get(self.relating_structure) if self.relating_structure else props.relating_structure
)
if not relating_structure or not relating_structure.BIMObjectProperties.ifc_definition_id:
return {"FINISHED"}
assign_container.Usecase(
@@ -27,12 +32,25 @@ class AssignContainer(bpy.types.Operator):
Data.load(props.ifc_definition_id)
bpy.ops.bim.disable_editing_container(obj=related_element.name)
for collection in related_element.users_collection:
collection.objects.unlink(related_element)
collection = bpy.data.collections.get(relating_structure.name)
collection.objects.link(related_element)
aggregate_collection = bpy.data.collections.get(related_element.name)
relating_collection = bpy.data.collections.get(relating_structure.name)
if aggregate_collection:
self.remove_collection(bpy.context.scene.collection, aggregate_collection)
for collection in bpy.data.collections:
self.remove_collection(collection, aggregate_collection)
relating_collection.children.link(aggregate_collection)
else:
for collection in related_element.users_collection:
collection.objects.unlink(related_element)
relating_collection.objects.link(related_element)
return {"FINISHED"}
def remove_collection(self, parent, child):
try:
parent.children.unlink(child)
except:
pass
class EnableEditingContainer(bpy.types.Operator):
bl_idname = "bim.enable_editing_container"
@@ -53,3 +71,34 @@ class DisableEditingContainer(bpy.types.Operator):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
obj.BIMObjectProperties.is_editing_container = False
return {"FINISHED"}
class RemoveContainer(bpy.types.Operator):
bl_idname = "bim.remove_container"
bl_label = "Remvoe Container"
obj: bpy.props.StringProperty()
def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
props = obj.BIMObjectProperties
self.file = IfcStore.get_file()
remove_container.Usecase(self.file, {"product": self.file.by_id(props.ifc_definition_id)}).execute()
Data.load(props.ifc_definition_id)
aggregate_collection = bpy.data.collections.get(obj.name)
if aggregate_collection:
self.remove_collection(bpy.context.scene.collection, aggregate_collection)
for collection in bpy.data.collections:
self.remove_collection(collection, spatial_collection)
bpy.context.scene.collection.children.link(aggregate_collection)
else:
for collection in obj.users_collection:
collection.objects.unlink(obj)
bpy.context.scene.collection.objects.link(obj)
return {"FINISHED"}
def remove_collection(self, parent, child):
try:
parent.children.unlink(child)
except:
pass
@@ -0,0 +1,20 @@
import ifcopenshell
class Usecase:
def __init__(self, file, settings=None):
self.file = file
self.settings = {"product": None}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
contained_in_structure = self.settings["product"].ContainedInStructure
if contained_in_structure:
related_elements = list(contained_in_structure[0].RelatedElements)
related_elements.remove(self.settings["product"])
if related_elements:
contained_in_structure[0].RelatedElements = related_elements
else:
self.file.remove(contained_in_structure)
@@ -11,6 +11,8 @@ class BIM_PT_spatial(Panel):
@classmethod
def poll(cls, context):
if not context.active_object:
return False
props = context.active_object.BIMObjectProperties
if not props.ifc_definition_id:
return False
@@ -41,3 +43,4 @@ class BIM_PT_spatial(Panel):
name = "This object is not spatially contained"
row.label(text=name)
row.operator("bim.enable_editing_container", icon="GREASEPENCIL", text="")
row.operator("bim.remove_container", icon="X", text="")