WIP allow partial editing of spatial container. See #1222.

This commit is contained in:
Dion Moult
2021-01-04 15:57:12 +11:00
parent d9dbda6b5a
commit 23a66b3a72
8 changed files with 142 additions and 4 deletions
@@ -11,6 +11,7 @@ if bpy is not None:
import blenderbim.bim.module.covetool as module_covetool
import blenderbim.bim.module.geometry as module_geometry
import blenderbim.bim.module.model as module_model
import blenderbim.bim.module.spatial as module_spatial
from . import ui, prop, operator
classes = [
@@ -316,6 +317,7 @@ if bpy is not None:
classes.extend(module_covetool.classes)
classes.extend(module_geometry.classes)
classes.extend(module_model.classes)
classes.extend(module_spatial.classes)
def menu_func_export(self, context):
self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)")
@@ -353,6 +355,7 @@ if bpy is not None:
module_covetool.register()
module_geometry.register()
module_model.register()
module_spatial.register()
bpy.app.handlers.depsgraph_update_pre.append(operator.depsgraph_update_pre_handler)
def unregister():
@@ -373,6 +376,7 @@ if bpy is not None:
del bpy.types.Camera.BIMCameraProperties
del bpy.types.TextCurve.BIMTextProperties
bpy.types.SCENE_PT_unit.remove(ui.ifc_units)
module_spatial.unregister()
module_model.unregister()
module_geometry.unregister()
module_covetool.unregister()
@@ -10,8 +10,6 @@ import blenderbim.bim.module.geometry.assign_representation as assign_representa
import blenderbim.bim.module.geometry.add_object_placement as add_object_placement
from blenderbim.bim.ifc import IfcStore
# from blenderbim.bim.module.geometry.data import Data
class EnableReassignClass(bpy.types.Operator):
bl_idname = "bim.enable_reassign_class"
@@ -0,0 +1,15 @@
import bpy
from . import ui, operator
classes = (
operator.AssignContainer,
ui.BIM_PT_spatial,
)
def register():
pass
def unregister():
pass
@@ -0,0 +1,42 @@
import ifcopenshell
class Usecase:
def __init__(self, file, settings=None):
self.file = file
self.settings = {
"product": None,
"relating_structure": None,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
contained_in_structure = self.settings["product"].ContainedInStructure
contains_elements = self.settings["relating_structure"].ContainsElements
if contained_in_structure == contains_elements:
return
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)
if contains_elements:
related_elements = list(contains_elements[0].RelatedElements)
related_elements.append(self.settings["product"])
contains_elements.RelatedElements = related_elements
else:
contains_elements = self.file.create_entity(
"IfcRelContainedInSpatialStructure",
**{
"GlobalId": ifcopenshell.guid.new(),
# TODO "OwnerHistory": None
"RelatedElements": [self.settings["product"]],
"RelatingStructure": self.settings["relating_structure"],
}
)
@@ -0,0 +1,18 @@
from blenderbim.bim.ifc import IfcStore
class Data:
products = {}
@classmethod
def load(cls, product_id):
file = IfcStore.get_file()
if not file:
return
product = file.by_id(product_id)
element = product.ContainedInStructure[0].RelatingStructure if product.ContainedInStructure else None
cls.products[product_id] = {
"type": element.is_a() if element else None,
"Name": element.Name if element else None,
"id": int(element.id()) if element else None
}
@@ -0,0 +1,32 @@
import bpy
import blenderbim.bim.module.spatial.assign_container as assign_container
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.spatial.data import Data
class AssignContainer(bpy.types.Operator):
bl_idname = "bim.assign_container"
bl_label = "Assign Container"
def execute(self, context):
self.file = IfcStore.get_file()
obj = bpy.context.active_object
props = obj.BIMObjectProperties
relating_structure = None
for collection in obj.users_collection:
if "Ifc" in collection.name:
relating_structure = self.file.by_id(
bpy.data.objects.get(collection.name).BIMObjectProperties.ifc_definition_id
)
if not relating_structure:
return {"FINISHED"}
usecase = assign_container.Usecase(
self.file,
{
"product": self.file.by_id(props.ifc_definition_id),
"relating_structure": relating_structure,
},
)
usecase.execute()
Data.load(props.ifc_definition_id)
return {"FINISHED"}
@@ -0,0 +1,31 @@
from bpy.types import Panel
from blenderbim.bim.module.spatial.data import Data
class BIM_PT_spatial(Panel):
bl_label = "IFC Spatial Container"
bl_idname = "BIM_PT_spatial"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
@classmethod
def poll(cls, context):
return bool(context.active_object.BIMObjectProperties.ifc_definition_id)
def draw(self, context):
props = context.active_object.BIMObjectProperties
if not props.ifc_definition_id:
return
if props.ifc_definition_id not in Data.products:
Data.load(props.ifc_definition_id)
if "Ifc" not in context.active_object.name:
return
row = self.layout.row(align=True)
name = "{}/{}".format(
Data.products[props.ifc_definition_id]["type"], Data.products[props.ifc_definition_id]["Name"]
)
row.label(text=name)
row.operator("bim.assign_container", icon="FILE_REFRESH", text="")
@@ -51,8 +51,6 @@ class BIM_PT_object(Panel):
row = layout.row(align=True)
row.prop(props, "relating_type")
row.operator("bim.select_similar_type", icon="RESTRICT_SELECT_OFF", text="")
row = layout.row()
row.prop(props, "relating_structure")
def draw_addresses_ui(self):
layout = self.layout