mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 06:00:51 +00:00
9b12cae8b4
Example - https://imgur.com/a/3ZSGtw7
345 lines
13 KiB
Python
345 lines
13 KiB
Python
# Bonsai - OpenBIM Blender Add-on
|
|
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
|
#
|
|
# This file is part of Bonsai.
|
|
#
|
|
# Bonsai is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Bonsai is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import os
|
|
import bpy
|
|
import bonsai.tool as tool
|
|
from . import bcfstore
|
|
from bpy.types import Panel
|
|
|
|
|
|
class BIM_PT_bcf(Panel):
|
|
bl_label = "BCF Project"
|
|
bl_idname = "BIM_PT_bcf"
|
|
bl_options = {"DEFAULT_CLOSED"}
|
|
bl_space_type = "PROPERTIES"
|
|
bl_region_type = "WINDOW"
|
|
bl_context = "scene"
|
|
bl_parent_id = "BIM_PT_tab_collaboration"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
layout.use_property_split = True
|
|
layout.use_property_decorate = False
|
|
|
|
scene = context.scene
|
|
props = scene.BCFProperties
|
|
|
|
if not bcfstore.BcfStore.get_bcfxml():
|
|
row = layout.row(align=True)
|
|
row.operator("bim.new_bcf_project", text="New Project")
|
|
row.operator("bim.load_bcf_project", text="Load Project")
|
|
layout.prop(props, "bcf_version")
|
|
return
|
|
|
|
row = layout.row(align=True)
|
|
op = row.operator("bim.save_bcf_project", icon="FILE_TICK", text="Save Current Project")
|
|
op.save_current_bcf = True
|
|
row.operator("bim.save_bcf_project", icon="EXPORT", text="Save Project As...")
|
|
row.operator("bim.unload_bcf_project", text="", icon="CANCEL")
|
|
|
|
row = layout.row()
|
|
row.prop(props, "bcf_version", emboss=False)
|
|
row.enabled = False
|
|
|
|
row = layout.row()
|
|
row.prop(props, "name")
|
|
|
|
row = layout.row()
|
|
row.prop(props, "author")
|
|
|
|
props = context.scene.BCFProperties
|
|
row = layout.row()
|
|
row.template_list("BIM_UL_topics", "", props, "topics", props, "active_topic_index")
|
|
col = row.column(align=True)
|
|
col.operator("bim.add_bcf_topic", icon="ADD", text="")
|
|
col.operator("bim.remove_bcf_topic", icon="REMOVE", text="")
|
|
if props.active_topic_index < len(props.topics):
|
|
topic = props.active_topic
|
|
is_editable = topic.is_editable
|
|
col.prop(topic, "is_editable", icon="CHECKMARK" if topic.is_editable else "GREASEPENCIL", icon_only=True)
|
|
|
|
topic = props.active_topic
|
|
row = layout.row()
|
|
row.enabled = is_editable
|
|
row.prop(topic, "description", text="")
|
|
|
|
row = layout.row()
|
|
row.prop(topic, "viewpoints")
|
|
row.operator("bim.activate_bcf_viewpoint", icon="SCENE", text="")
|
|
row.operator("bim.add_bcf_viewpoint", icon="ADD", text="")
|
|
row.operator("bim.remove_bcf_viewpoint", icon="X", text="")
|
|
|
|
col = layout.column(align=True)
|
|
topic_props = ("type", "status", "priority", "stage", "assigned_to", "due_date")
|
|
bl_rna_props = topic.bl_rna.properties
|
|
|
|
def draw_prop(prop_name: str) -> None:
|
|
row = col.row(align=True)
|
|
row.label(text=f"{bl_rna_props[prop_name].name}")
|
|
row.label(text=getattr(topic, prop_name))
|
|
|
|
for prop in topic_props:
|
|
if getattr(topic, prop) or is_editable:
|
|
# Can't just use emboss because search= on props is changing
|
|
# how they look and adds "ui.button_string_clear" button
|
|
# which allows clearing out the string and we don't want to.
|
|
if is_editable:
|
|
col.prop(topic, prop, emboss=is_editable)
|
|
else:
|
|
draw_prop(prop)
|
|
|
|
col = layout.column(align=True)
|
|
if topic.modified_date:
|
|
draw_prop("modified_date")
|
|
draw_prop("modified_author")
|
|
else:
|
|
draw_prop("creation_date")
|
|
draw_prop("creation_author")
|
|
|
|
|
|
class BIM_PT_bcf_metadata(Panel):
|
|
bl_label = "BCF Metadata"
|
|
bl_idname = "BIM_PT_bcf_metadata"
|
|
bl_options = {"DEFAULT_CLOSED"}
|
|
bl_space_type = "PROPERTIES"
|
|
bl_region_type = "WINDOW"
|
|
bl_context = "scene"
|
|
bl_parent_id = "BIM_PT_bcf"
|
|
|
|
def draw(self, context):
|
|
# TODO: in bcf v3 documents can be added to the bcf
|
|
# without adding them to specific topic.
|
|
# Currently we just handle it the same way as in v2
|
|
# documents are accessed and managed from topics.
|
|
layout = self.layout
|
|
layout.use_property_split = True
|
|
layout.use_property_decorate = False
|
|
|
|
scene = context.scene
|
|
props = scene.BCFProperties
|
|
|
|
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
|
if not bcfxml or props.active_topic_index >= len(props.topics):
|
|
layout.label(text="No BCF project is loaded")
|
|
return
|
|
bcf_verison = bcfxml.version.version_id or ""
|
|
bcf_v3 = bcf_verison.startswith("3")
|
|
|
|
topic = props.active_topic
|
|
bcf_topic = bcfxml.topics[topic.name]
|
|
|
|
layout.label(text="Header Files:")
|
|
|
|
if bcf_topic.header:
|
|
for index, f in enumerate(tool.Bcf.get_topic_header_files(bcf_topic)):
|
|
box = self.layout.box()
|
|
row = box.row(align=True)
|
|
row.label(text=f.filename, icon="FILE_BLANK")
|
|
if f.is_external:
|
|
row.operator("bim.open_uri", icon="URL", text="").uri = f.reference
|
|
else:
|
|
op = row.operator("bim.load_bcf_header_ifc_file", icon="FILE_REFRESH", text="")
|
|
op.index = index
|
|
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
|
op.index = index
|
|
op.entity_type = "HEADER_FILE"
|
|
row.operator("bim.remove_bcf_file", icon="X", text="").index = index
|
|
|
|
row = box.row()
|
|
row.label(text="Date")
|
|
row.label(text=str(f.date))
|
|
|
|
if f.ifc_project:
|
|
row = box.row()
|
|
row.label(text="IFC Project")
|
|
row.label(text=f.ifc_project)
|
|
|
|
if f.ifc_spatial_structure_element:
|
|
row = box.row()
|
|
row.label(text="IFC Spatial Structure Element")
|
|
row.label(text=f.ifc_spatial_structure_element)
|
|
|
|
row = layout.row(align=True)
|
|
row.prop(props, "file_reference")
|
|
row.operator("bim.select_bcf_header_file", icon="FILE_FOLDER", text="")
|
|
row = layout.row()
|
|
row.prop(props, "file_ifc_project")
|
|
row = layout.row()
|
|
row.prop(props, "file_ifc_spatial_structure_element")
|
|
|
|
row = layout.row()
|
|
row.operator("bim.add_bcf_header_file")
|
|
|
|
layout.label(text="Reference Links:")
|
|
for index, link in enumerate(topic.reference_links):
|
|
row = layout.row(align=True)
|
|
row.prop(link, "name", text="")
|
|
row.operator("bim.open_uri", icon="URL", text="").uri = link.name
|
|
row.operator("bim.remove_bcf_reference_link", icon="X", text="").index = index
|
|
row = layout.row()
|
|
row.prop(props, "reference_link", text="New Reference Link:")
|
|
row = layout.row()
|
|
row.operator("bim.add_bcf_reference_link")
|
|
|
|
layout.label(text="Labels:")
|
|
for index, label in enumerate(topic.labels):
|
|
row = layout.row(align=True)
|
|
row.prop(label, "name", text="")
|
|
row.operator("bim.remove_bcf_label", icon="X", text="").index = index
|
|
row = layout.row()
|
|
row.prop(props, "label")
|
|
row = layout.row()
|
|
row.operator("bim.add_bcf_label")
|
|
|
|
layout.label(text="BIM Snippet:")
|
|
if topic.bim_snippet.reference:
|
|
row = layout.row(align=True)
|
|
row.prop(topic.bim_snippet, "type", emboss=False)
|
|
if topic.bim_snippet.schema:
|
|
row.operator("bim.open_uri", icon="URL", text="").uri = topic.bim_snippet.schema
|
|
|
|
row = layout.row(align=True)
|
|
row.prop(topic.bim_snippet, "reference", emboss=False)
|
|
if topic.bim_snippet.is_external:
|
|
row.operator("bim.open_uri", icon="URL", text="").uri = topic.bim_snippet.reference
|
|
else:
|
|
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
|
op.entity_type = "BIM_SNIPPET"
|
|
row.operator("bim.remove_bcf_bim_snippet", icon="X", text="")
|
|
else:
|
|
row = layout.row(align=True)
|
|
row.prop(props, "bim_snippet_reference")
|
|
row.operator("bim.select_bcf_bim_snippet_reference", icon="FILE_FOLDER", text="")
|
|
row = layout.row()
|
|
row.prop(props, "bim_snippet_type")
|
|
row = layout.row()
|
|
row.prop(props, "bim_snippet_schema")
|
|
row = layout.row()
|
|
row.operator("bim.add_bcf_bim_snippet")
|
|
|
|
layout.label(text="Document References:")
|
|
for index, doc in enumerate(topic.document_references):
|
|
box = self.layout.box()
|
|
row = box.row(align=True)
|
|
row.prop(doc, "reference", emboss=False)
|
|
if doc.is_external:
|
|
row.operator("bim.open_uri", icon="URL", text="").uri = doc.reference
|
|
else:
|
|
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
|
op.entity_type = "DOCUMENT_REFERENCE"
|
|
op.index = index
|
|
|
|
row.operator("bim.remove_bcf_document_reference", icon="X", text="").index = index
|
|
row = box.row(align=True)
|
|
row.prop(doc, "description", emboss=False)
|
|
row = layout.row(align=True)
|
|
row.prop(props, "document_reference")
|
|
row.operator("bim.select_bcf_document_reference", icon="FILE_FOLDER", text="")
|
|
row = layout.row()
|
|
row.prop(
|
|
props, "document_reference_description", text="Reference Description" if bcf_v3 else "Document Description"
|
|
)
|
|
if bcf_v3:
|
|
row = layout.row()
|
|
row.prop(props, "document_description")
|
|
row = layout.row()
|
|
row.operator("bim.add_bcf_document_reference")
|
|
|
|
layout.label(text="Related Topics:")
|
|
for index, related_topic in enumerate(topic.related_topics):
|
|
try:
|
|
row = layout.row(align=True)
|
|
op = row.operator(
|
|
"bim.view_bcf_topic", text=f"Select {bcfxml.topics[related_topic.name.lower()].topic.title}"
|
|
)
|
|
op.topic_guid = related_topic.name
|
|
row.operator("bim.remove_bcf_related_topic", icon="X", text="").index = index
|
|
except KeyError:
|
|
pass
|
|
|
|
if len(props.topics) == len(topic.related_topics) + 1:
|
|
layout.label(text="No topics to add as related.")
|
|
else:
|
|
row = layout.row()
|
|
row.prop(props, "related_topic")
|
|
row = layout.row()
|
|
row.operator("bim.add_bcf_related_topic")
|
|
|
|
|
|
class BIM_PT_bcf_comments(Panel):
|
|
bl_label = "BCF Comments"
|
|
bl_idname = "BIM_PT_bcf_comments"
|
|
bl_options = {"DEFAULT_CLOSED"}
|
|
bl_space_type = "PROPERTIES"
|
|
bl_region_type = "WINDOW"
|
|
bl_context = "scene"
|
|
bl_parent_id = "BIM_PT_bcf"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
layout.use_property_split = True
|
|
layout.use_property_decorate = False
|
|
|
|
scene = context.scene
|
|
props = scene.BCFProperties
|
|
|
|
if props.active_topic_index >= len(props.topics):
|
|
layout.label(text="No BCF project is loaded")
|
|
return
|
|
|
|
row = layout.row()
|
|
row.prop(props, "comment_text_width")
|
|
|
|
topic = props.active_topic
|
|
for comment in topic.comments:
|
|
box = self.layout.box()
|
|
|
|
author_text = "{} ({})".format(comment.author, comment.date)
|
|
if comment.modified_author:
|
|
author_text = "*{} ({})".format(comment.modified_author, comment.modified_date)
|
|
row = box.row(align=True)
|
|
row.label(text=author_text, icon="WORDWRAP_ON")
|
|
row.prop(
|
|
comment, "is_editable", icon="CHECKMARK" if comment.is_editable else "GREASEPENCIL", icon_only=True
|
|
)
|
|
row.operator("bim.remove_bcf_comment", icon="X", text="").comment_guid = comment.name
|
|
|
|
if comment.is_editable:
|
|
row = box.row()
|
|
row.prop(comment, "comment", text="")
|
|
else:
|
|
col = box.column(align=True)
|
|
col.scale_y = 0.8
|
|
words = comment.comment.split()
|
|
while words:
|
|
total_line_chars = 0
|
|
line_words = []
|
|
while words and total_line_chars < props.comment_text_width:
|
|
word = words.pop(0)
|
|
line_words.append(word)
|
|
total_line_chars += len(word) + 1 # 1 is for the space
|
|
col.label(text=" ".join(line_words))
|
|
|
|
row = layout.row()
|
|
row.prop(props, "comment")
|
|
row = layout.row()
|
|
row.prop(props, "has_related_viewpoint")
|
|
row = layout.row()
|
|
row.operator("bim.add_bcf_comment")
|