WIP implement document assign/unassign. See #1222.

This commit is contained in:
Dion Moult
2021-01-23 11:58:29 +11:00
parent 395d63279f
commit b7f574fa30
6 changed files with 222 additions and 2 deletions
@@ -12,16 +12,25 @@ classes = (
operator.EditInformation,
operator.EditDocumentReference,
operator.RemoveDocument,
operator.EnableAssigningDocument,
operator.DisableAssigningDocument,
operator.AssignDocument,
operator.UnassignDocument,
prop.Document,
prop.BIMDocumentProperties,
prop.BIMObjectDocumentProperties,
ui.BIM_PT_documents,
ui.BIM_PT_object_documents,
ui.BIM_UL_documents,
ui.BIM_UL_object_documents,
)
def register():
bpy.types.Scene.BIMDocumentProperties = bpy.props.PointerProperty(type=prop.BIMDocumentProperties)
bpy.types.Object.BIMObjectDocumentProperties = bpy.props.PointerProperty(type=prop.BIMObjectDocumentProperties)
def unregister():
del bpy.types.Scene.BIMDocumentProperties
del bpy.types.Scene.BIMObjectDocumentProperties
@@ -0,0 +1,42 @@
import ifcopenshell
class Usecase:
def __init__(self, file, settings=None):
self.file = file
self.settings = {
"product": None,
"document": None,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
rel = self.get_document_rel()
related_objects = set(rel.RelatedObjects) if rel.RelatedObjects else set()
related_objects.add(self.settings["product"])
rel.RelatedObjects = list(related_objects)
def get_document_rel(self):
rel = None
if self.file.schema == "IFC2X3":
for association in self.file.by_type("IfcRelAssociatesDocument"):
if association.RelatingDocument == self.settings["document"]:
return rel
else:
if (
hasattr(self.settings["document"], "DocumentRefForObjects")
and self.settings["document"].DocumentRefForObjects
):
return self.settings["document"].DocumentRefForObjects[0]
elif (
hasattr(self.settings["document"], "DocumentInfoForObjects")
and self.settings["document"].DocumentInfoForObjects
):
return self.settings["document"].DocumentInfoForObjects[0]
return self.file.create_entity("IfcRelAssociatesDocument", **{
"GlobalId": ifcopenshell.guid.new(),
# TODO: owner history
"RelatingDocument": self.settings["document"]
})
@@ -5,6 +5,8 @@ import blenderbim.bim.module.document.add_reference as add_reference
import blenderbim.bim.module.document.edit_information as edit_information
import blenderbim.bim.module.document.edit_reference as edit_reference
import blenderbim.bim.module.document.remove_document as remove_document
import blenderbim.bim.module.document.assign_document as assign_document
import blenderbim.bim.module.document.unassign_document as unassign_document
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.document.data import Data
@@ -184,3 +186,65 @@ class RemoveDocument(bpy.types.Operator):
elif props.is_editing == "reference":
bpy.ops.bim.load_document_references()
return {"FINISHED"}
class EnableAssigningDocument(bpy.types.Operator):
bl_idname = "bim.enable_assigning_document"
bl_label = "Enable Assigning Document"
obj: bpy.props.StringProperty()
def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMObjectDocumentProperties
if props.available_document_types == "IfcDocumentInformation":
bpy.ops.bim.load_information()
elif props.available_document_types == "IfcDocumentReference":
bpy.ops.bim.load_document_references()
props.is_adding = props.available_document_types
return {"FINISHED"}
class DisableAssigningDocument(bpy.types.Operator):
bl_idname = "bim.disable_assigning_document"
bl_label = "Disable Assigning Document"
obj: bpy.props.StringProperty()
def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMObjectDocumentProperties
props.is_adding = ""
return {"FINISHED"}
class AssignDocument(bpy.types.Operator):
bl_idname = "bim.assign_document"
bl_label = "Assign Document"
obj: bpy.props.StringProperty()
document: bpy.props.IntProperty()
def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file()
assign_document.Usecase(self.file, {
"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
"document": self.file.by_id(self.document)
}).execute()
Data.load(obj.BIMObjectProperties.ifc_definition_id)
return {"FINISHED"}
class UnassignDocument(bpy.types.Operator):
bl_idname = "bim.unassign_document"
bl_label = "Unassign Document"
obj: bpy.props.StringProperty()
document: bpy.props.IntProperty()
def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file()
unassign_document.Usecase(self.file, {
"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
"document": self.file.by_id(self.document)
}).execute()
Data.load(obj.BIMObjectProperties.ifc_definition_id)
return {"FINISHED"}
@@ -12,6 +12,7 @@ from bpy.props import (
CollectionProperty,
)
class Document(PropertyGroup):
name: StringProperty(name="Name")
identification: StringProperty(name="Identification")
@@ -24,3 +25,10 @@ class BIMDocumentProperties(PropertyGroup):
documents: CollectionProperty(name="Documents", type=Document)
active_document_index: IntProperty(name="Active Document Index")
is_editing: StringProperty(name="Is Editing")
class BIMObjectDocumentProperties(PropertyGroup):
is_adding: StringProperty(name="Is Adding")
available_document_types: EnumProperty(
items=[(d, d, "") for d in ["IfcDocumentInformation", "IfcDocumentReference"]], name="Available Document Types"
)
@@ -23,7 +23,7 @@ class BIM_PT_documents(Panel):
if not self.props.is_editing or self.props.is_editing == "information":
row = self.layout.row(align=True)
row.label(text="{} Documents Found".format(len(Data.information)))
row.label(text="{} Documents Found".format(len(Data.information)), icon="FILE")
if self.props.is_editing == "information":
row.operator("bim.disable_document_editing_ui", text="", icon="CHECKMARK")
row.operator("bim.add_information", text="", icon="ADD")
@@ -32,7 +32,7 @@ class BIM_PT_documents(Panel):
if not self.props.is_editing or self.props.is_editing == "reference":
row = self.layout.row(align=True)
row.label(text="{} References Found".format(len(Data.references)))
row.label(text="{} References Found".format(len(Data.references)), icon="FILE_HIDDEN")
if self.props.is_editing == "reference":
row.operator("bim.disable_document_editing_ui", text="", icon="CHECKMARK")
row.operator("bim.add_document_reference", text="", icon="ADD")
@@ -64,6 +64,77 @@ class BIM_PT_documents(Panel):
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
class BIM_PT_object_documents(Panel):
bl_label = "IFC Documents"
bl_idname = "BIM_PT_object_documents"
bl_options = {"DEFAULT_CLOSED"}
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):
obj = context.active_object
self.oprops = obj.BIMObjectProperties
self.sprops = context.scene.BIMDocumentProperties
self.props = obj.BIMObjectDocumentProperties
self.file = IfcStore.get_file()
if not Data.is_loaded:
Data.load()
if self.oprops.ifc_definition_id not in Data.products:
Data.load(self.oprops.ifc_definition_id)
self.draw_add_ui()
document_ids = Data.products[self.oprops.ifc_definition_id]
if not document_ids:
row = self.layout.row(align=True)
row.label(text="No Documents", icon="FILE")
for document_id in document_ids:
try:
document = Data.information[document_id]
document_type = "IfcDocumentInformation"
icon = "FILE"
except:
document = Data.references[document_id]
document_type = "IfcDocumentReference"
icon = "FILE_HIDDEN"
row = self.layout.row(align=True)
if self.file.schema == "IFC2X3":
if document_type == "IfcDocumentInformation":
row.label(text=document.get("DocumentId") or "*", icon=icon)
elif document_type == "IfcDocumentReference":
row.label(text=document.get("ItemReference") or "*", icon=icon)
else:
row.label(text=document.get("Identification") or "*", icon=icon)
row.label(text=document.get("Name") or "Unnamed")
row.operator("bim.unassign_document", text="", icon="X").document = document_id
def draw_add_ui(self):
if self.props.is_adding:
row = self.layout.row(align=True)
icon = "FILE" if self.props.is_adding == "IfcDocumentInformation" else "FILE_HIDDEN"
row.label(text="Adding {}".format(self.props.is_adding), icon=icon)
row.operator("bim.disable_assigning_document", text="", icon="X")
self.layout.template_list(
"BIM_UL_object_documents",
"",
self.sprops,
"documents",
self.sprops,
"active_document_index",
)
else:
row = self.layout.row(align=True)
row.prop(self.props, "available_document_types", text="")
row.operator("bim.enable_assigning_document", text="", icon="ADD")
class BIM_UL_documents(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item:
@@ -82,3 +153,12 @@ class BIM_UL_documents(UIList):
op = row.operator("bim.enable_editing_document", text="", icon="GREASEPENCIL")
op.document = item.ifc_definition_id
row.operator("bim.remove_document", text="", icon="X").document = item.ifc_definition_id
class BIM_UL_object_documents(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item:
row = layout.row(align=True)
row.label(text=item.identification)
row.label(text=item.name)
row.operator("bim.assign_document", text="", icon="ADD").document = item.ifc_definition_id
@@ -0,0 +1,17 @@
import ifcopenshell
class Usecase:
def __init__(self, file, settings=None):
self.file = file
self.settings = {
"product": None,
"document": None,
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
for rel in self.settings["product"].HasAssociations:
if rel.is_a("IfcRelAssociatesDocument") and rel.RelatingDocument == self.settings["document"]:
self.file.remove(rel)