mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 02:10:59 +00:00
WIP port add aggregate and remove container. See #1222.
This commit is contained in:
@@ -5,6 +5,7 @@ classes = (
|
|||||||
operator.AssignObject,
|
operator.AssignObject,
|
||||||
operator.EnableEditingAggregate,
|
operator.EnableEditingAggregate,
|
||||||
operator.DisableEditingAggregate,
|
operator.DisableEditingAggregate,
|
||||||
|
operator.AddAggregate,
|
||||||
ui.BIM_PT_aggregate,
|
ui.BIM_PT_aggregate,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -28,15 +28,19 @@ class AssignObject(bpy.types.Operator):
|
|||||||
Data.load(props.ifc_definition_id)
|
Data.load(props.ifc_definition_id)
|
||||||
bpy.ops.bim.disable_editing_aggregate(obj=related_object.name)
|
bpy.ops.bim.disable_editing_aggregate(obj=related_object.name)
|
||||||
|
|
||||||
related_collection = bpy.data.collections.get(related_object.name)
|
spatial_collection = bpy.data.collections.get(related_object.name)
|
||||||
if related_collection:
|
relating_collection = bpy.data.collections.get(relating_object.name)
|
||||||
relating_collection = bpy.data.collections.get(relating_object.name)
|
if spatial_collection:
|
||||||
self.remove_collection(bpy.context.scene.collection, related_collection)
|
self.remove_collection(bpy.context.scene.collection, spatial_collection)
|
||||||
for collection in bpy.data.collections:
|
for collection in bpy.data.collections:
|
||||||
if collection == relating_collection:
|
if collection == relating_collection:
|
||||||
collection.children.link(related_collection)
|
collection.children.link(spatial_collection)
|
||||||
continue
|
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"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def remove_collection(self, parent, child):
|
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 = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
|
||||||
obj.BIMObjectProperties.is_editing_aggregate = False
|
obj.BIMObjectProperties.is_editing_aggregate = False
|
||||||
return {"FINISHED"}
|
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"
|
name = "This object is not part of an aggregation"
|
||||||
row.label(text=name)
|
row.label(text=name)
|
||||||
row.operator("bim.enable_editing_aggregate", icon="GREASEPENCIL", text="")
|
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):
|
def assign_potential_spatial_container(self, obj):
|
||||||
for collection in obj.users_collection:
|
for collection in obj.users_collection:
|
||||||
if "Ifc" not in collection.name:
|
if "Ifc" not in collection.name or collection.name == obj.name:
|
||||||
continue
|
continue
|
||||||
bpy.ops.bim.assign_container(relating_structure=collection.name, related_element=obj.name)
|
bpy.ops.bim.assign_container(relating_structure=collection.name, related_element=obj.name)
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from . import ui, operator
|
|||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
operator.AssignContainer,
|
operator.AssignContainer,
|
||||||
|
operator.RemoveContainer,
|
||||||
operator.EnableEditingContainer,
|
operator.EnableEditingContainer,
|
||||||
operator.DisableEditingContainer,
|
operator.DisableEditingContainer,
|
||||||
ui.BIM_PT_spatial,
|
ui.BIM_PT_spatial,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import blenderbim.bim.module.spatial.assign_container as assign_container
|
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.ifc import IfcStore
|
||||||
from blenderbim.bim.module.spatial.data import Data
|
from blenderbim.bim.module.spatial.data import Data
|
||||||
|
|
||||||
@@ -12,9 +13,13 @@ class AssignContainer(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
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
|
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:
|
if not relating_structure or not relating_structure.BIMObjectProperties.ifc_definition_id:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
assign_container.Usecase(
|
assign_container.Usecase(
|
||||||
@@ -27,12 +32,25 @@ class AssignContainer(bpy.types.Operator):
|
|||||||
Data.load(props.ifc_definition_id)
|
Data.load(props.ifc_definition_id)
|
||||||
bpy.ops.bim.disable_editing_container(obj=related_element.name)
|
bpy.ops.bim.disable_editing_container(obj=related_element.name)
|
||||||
|
|
||||||
for collection in related_element.users_collection:
|
aggregate_collection = bpy.data.collections.get(related_element.name)
|
||||||
collection.objects.unlink(related_element)
|
relating_collection = bpy.data.collections.get(relating_structure.name)
|
||||||
collection = bpy.data.collections.get(relating_structure.name)
|
if aggregate_collection:
|
||||||
collection.objects.link(related_element)
|
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"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def remove_collection(self, parent, child):
|
||||||
|
try:
|
||||||
|
parent.children.unlink(child)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingContainer(bpy.types.Operator):
|
class EnableEditingContainer(bpy.types.Operator):
|
||||||
bl_idname = "bim.enable_editing_container"
|
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 = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
|
||||||
obj.BIMObjectProperties.is_editing_container = False
|
obj.BIMObjectProperties.is_editing_container = False
|
||||||
return {"FINISHED"}
|
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
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
|
if not context.active_object:
|
||||||
|
return False
|
||||||
props = context.active_object.BIMObjectProperties
|
props = context.active_object.BIMObjectProperties
|
||||||
if not props.ifc_definition_id:
|
if not props.ifc_definition_id:
|
||||||
return False
|
return False
|
||||||
@@ -41,3 +43,4 @@ class BIM_PT_spatial(Panel):
|
|||||||
name = "This object is not spatially contained"
|
name = "This object is not spatially contained"
|
||||||
row.label(text=name)
|
row.label(text=name)
|
||||||
row.operator("bim.enable_editing_container", icon="GREASEPENCIL", text="")
|
row.operator("bim.enable_editing_container", icon="GREASEPENCIL", text="")
|
||||||
|
row.operator("bim.remove_container", icon="X", text="")
|
||||||
|
|||||||
Reference in New Issue
Block a user