This commit is contained in:
Andrej730
2025-02-17 12:33:15 +05:00
parent 8f261be338
commit b0fbea60ae
32 changed files with 381 additions and 185 deletions
+4 -2
View File
@@ -21,6 +21,7 @@ import bpy
import bcf import bcf
import bcf.bcfxml import bcf.bcfxml
import bcf.v2.bcfxml import bcf.v2.bcfxml
import bonsai.tool as tool
from typing import Union from typing import Union
@@ -30,7 +31,8 @@ class BcfStore:
@classmethod @classmethod
def get_bcfxml(cls) -> Union[bcf.bcfxml.BcfXml, None]: def get_bcfxml(cls) -> Union[bcf.bcfxml.BcfXml, None]:
if not cls.bcfxml: if not cls.bcfxml:
bcf_filepath = bpy.context.scene.BCFProperties.bcf_file props = tool.Bcf.get_bcf_props()
bcf_filepath = props.bcf_file
if not os.path.isabs(bcf_filepath): if not os.path.isabs(bcf_filepath):
bcf_filepath = os.path.abspath(os.path.join(bpy.path.abspath("//"), bcf_filepath)) bcf_filepath = os.path.abspath(os.path.join(bpy.path.abspath("//"), bcf_filepath))
if bcf_filepath: if bcf_filepath:
@@ -46,7 +48,7 @@ class BcfStore:
@classmethod @classmethod
def set(cls, bcfxml: Union[bcf.bcfxml.BcfXml, None], filepath: str) -> None: def set(cls, bcfxml: Union[bcf.bcfxml.BcfXml, None], filepath: str) -> None:
cls.bcfxml = bcfxml cls.bcfxml = bcfxml
props = bpy.context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
props.bcf_file = filepath props.bcf_file = filepath
# Set bcf_version prop on load. # Set bcf_version prop on load.
+70 -51
View File
@@ -55,7 +55,7 @@ class NewBcfProject(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
bcf_v2 = props.bcf_version == "2" bcf_v2 = props.bcf_version == "2"
bcf_class = bcf.v2.bcfxml.BcfXml if bcf_v2 else bcf.v3.bcfxml.BcfXml bcf_class = bcf.v2.bcfxml.BcfXml if bcf_v2 else bcf.v3.bcfxml.BcfXml
bcfxml = bcf_class.create_new("New Project") bcfxml = bcf_class.create_new("New Project")
@@ -103,7 +103,8 @@ class LoadBcfProject(bpy.types.Operator):
assert bcfxml.project assert bcfxml.project
if bcfxml.project.name is None: if bcfxml.project.name is None:
bcfxml.project.name = nameless bcfxml.project.name = nameless
context.scene.BCFProperties.name = bcfxml.project.name props = tool.Bcf.get_bcf_props()
props.name = bcfxml.project.name
bpy.ops.bim.load_bcf_topics() bpy.ops.bim.load_bcf_topics()
self.report({"INFO"}, f"BCF Project '{Path(self.filepath).name}' is loaded.") self.report({"INFO"}, f"BCF Project '{Path(self.filepath).name}' is loaded.")
return {"FINISHED"} return {"FINISHED"}
@@ -131,7 +132,7 @@ class LoadBcfTopics(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
props.topics.clear() props.topics.clear()
# workaround, one non standard topic would break reading entire bcf # workaround, one non standard topic would break reading entire bcf
# ignored these topics ATM # ignored these topics ATM
@@ -163,7 +164,8 @@ class LoadBcfTopic(bpy.types.Operator):
assert bcfxml assert bcfxml
topic = bcfxml.topics[self.topic_guid] topic = bcfxml.topics[self.topic_guid]
bcfxml.get_header(self.topic_guid) bcfxml.get_header(self.topic_guid)
new = context.scene.BCFProperties.topics[self.topic_index] props = tool.Bcf.get_bcf_props()
new = props.topics[self.topic_index]
data_map = { data_map = {
"name": topic.guid, "name": topic.guid,
"title": topic.topic.title, "title": topic.topic.title,
@@ -244,7 +246,8 @@ class LoadBcfComments(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
blender_topic = context.scene.BCFProperties.topics.get(self.topic_guid) props = tool.Bcf.get_bcf_props()
blender_topic = props.topics.get(self.topic_guid)
blender_topic.comments.clear() blender_topic.comments.clear()
for comment in bcfxml.topics[self.topic_guid].comments: for comment in bcfxml.topics[self.topic_guid].comments:
new = blender_topic.comments.add() new = blender_topic.comments.add()
@@ -274,7 +277,9 @@ class EditBcfProjectName(bpy.types.Operator):
# Bonsai creates default project on load. # Bonsai creates default project on load.
assert bcfxml.project assert bcfxml.project
bcfxml.project.name = context.scene.BCFProperties.name
props = tool.Bcf.get_bcf_props()
bcfxml.project.name = props.name
return {"FINISHED"} return {"FINISHED"}
@@ -284,7 +289,7 @@ class EditBcfTopicName(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
@@ -300,7 +305,7 @@ class EditBcfTopic(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
@@ -371,13 +376,15 @@ class AddBcfTopic(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.scene.BCFProperties.author props = tool.Bcf.get_bcf_props()
return props.author
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
bcfxml.add_topic("New Topic", "", context.scene.BCFProperties.author) props = tool.Bcf.get_bcf_props()
bcfxml.add_topic("New Topic", "", props.author)
bpy.ops.bim.load_bcf_topics() bpy.ops.bim.load_bcf_topics()
return {"FINISHED"} return {"FINISHED"}
@@ -389,7 +396,7 @@ class AddBcfBimSnippet(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
props_are_filled = all( props_are_filled = all(
(getattr(props, attr) for attr in ("bim_snippet_reference", "bim_snippet_schema", "bim_snippet_type")) (getattr(props, attr) for attr in ("bim_snippet_reference", "bim_snippet_schema", "bim_snippet_type"))
) )
@@ -403,7 +410,7 @@ class AddBcfBimSnippet(bpy.types.Operator):
assert bcfxml assert bcfxml
bcf_v2 = (bcfxml.version.version_id or "").startswith("2") bcf_v2 = (bcfxml.version.version_id or "").startswith("2")
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
is_external = "://" in props.bim_snippet_reference is_external = "://" in props.bim_snippet_reference
@@ -435,7 +442,7 @@ class AddBcfRelatedTopic(bpy.types.Operator):
assert bcfxml assert bcfxml
bcf_v2 = (bcfxml.version.version_id or "").startswith("2") bcf_v2 = (bcfxml.version.version_id or "").startswith("2")
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
related_topics = tool.Bcf.get_topic_related_topics(topic) related_topics = tool.Bcf.get_topic_related_topics(topic)
@@ -462,14 +469,15 @@ class AddBcfHeaderFile(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.scene.BCFProperties.file_reference props = tool.Bcf.get_bcf_props()
return props.file_reference
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
bcf_v2 = (bcfxml.version.version_id or "").startswith("2") bcf_v2 = (bcfxml.version.version_id or "").startswith("2")
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
@@ -519,9 +527,10 @@ class ViewBcfTopic(bpy.types.Operator):
topic_guid: bpy.props.StringProperty() topic_guid: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
for index, topic in enumerate(context.scene.BCFProperties.topics): props = tool.Bcf.get_bcf_props()
for index, topic in enumerate(props.topics):
if topic.name.lower() == self.topic_guid.lower(): if topic.name.lower() == self.topic_guid.lower():
context.scene.BCFProperties.active_topic_index = index props.active_topic_index = index
break break
return {"FINISHED"} return {"FINISHED"}
@@ -546,7 +555,7 @@ class AddBcfViewpoint(bpy.types.Operator):
blender_camera = context.scene.camera blender_camera = context.scene.camera
assert blender_camera assert blender_camera
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
@@ -675,7 +684,7 @@ class RemoveBcfViewpoint(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
if not bcfxml: if not bcfxml:
return False return False
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
topic = props.active_topic topic = props.active_topic
if not topic: if not topic:
return False return False
@@ -690,7 +699,7 @@ class RemoveBcfViewpoint(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
del topic.viewpoints[blender_topic.viewpoints] del topic.viewpoints[blender_topic.viewpoints]
@@ -715,7 +724,7 @@ class RemoveBcfFile(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
header_files = tool.Bcf.get_topic_header_files(topic) header_files = tool.Bcf.get_topic_header_files(topic)
@@ -733,13 +742,14 @@ class RemoveBcfTopic(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.scene.BCFProperties.topics props = tool.Bcf.get_bcf_props()
return props.topics
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
del bcfxml.topics[props.active_topic.name] del bcfxml.topics[props.active_topic.name]
bpy.ops.bim.load_bcf_topics() bpy.ops.bim.load_bcf_topics()
return {"FINISHED"} return {"FINISHED"}
@@ -752,13 +762,14 @@ class AddBcfReferenceLink(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.scene.BCFProperties.reference_link props = tool.Bcf.get_bcf_props()
return bool(props.reference_link)
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
reference_links = tool.Bcf.get_topic_reference_links(topic) reference_links = tool.Bcf.get_topic_reference_links(topic)
@@ -776,14 +787,15 @@ class AddBcfDocumentReference(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.scene.BCFProperties.document_reference props = tool.Bcf.get_bcf_props()
return bool(props.document_reference)
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
bcf_v2 = (bcfxml.version.version_id or "").startswith("2") bcf_v2 = (bcfxml.version.version_id or "").startswith("2")
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
@@ -855,13 +867,14 @@ class AddBcfLabel(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.scene.BCFProperties.label props = tool.Bcf.get_bcf_props()
return bool(props.label)
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
new = blender_topic.labels.add() new = blender_topic.labels.add()
@@ -883,7 +896,7 @@ class EditBcfReferenceLinks(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
reference_links = [r.name for r in blender_topic.reference_links] reference_links = [r.name for r in blender_topic.reference_links]
@@ -900,7 +913,7 @@ class EditBcfLabels(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
labels = [l.name for l in blender_topic.labels] labels = [l.name for l in blender_topic.labels]
@@ -918,7 +931,7 @@ class RemoveBcfReferenceLink(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
reference_links = tool.Bcf.get_topic_reference_links(topic) reference_links = tool.Bcf.get_topic_reference_links(topic)
@@ -938,7 +951,7 @@ class RemoveBcfLabel(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
labels = tool.Bcf.get_topic_labels(topic) labels = tool.Bcf.get_topic_labels(topic)
@@ -957,7 +970,7 @@ class RemoveBcfBimSnippet(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
tool.Bcf.set_topic_bim_snippet(topic, None) tool.Bcf.set_topic_bim_snippet(topic, None)
@@ -978,7 +991,7 @@ class RemoveBcfDocumentReference(bpy.types.Operator):
assert bcfxml assert bcfxml
bcf_v2 = (bcfxml.version.version_id or "").startswith("2") bcf_v2 = (bcfxml.version.version_id or "").startswith("2")
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
@@ -1043,7 +1056,7 @@ class RemoveBcfRelatedTopic(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
related_topics = tool.Bcf.get_topic_related_topics(topic) related_topics = tool.Bcf.get_topic_related_topics(topic)
@@ -1063,7 +1076,7 @@ class RemoveBcfComment(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
comments = topic.comments comments = topic.comments
@@ -1084,7 +1097,7 @@ class EditBcfComment(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
blender_comment = blender_topic.comments.get(self.comment_guid) blender_comment = blender_topic.comments.get(self.comment_guid)
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
@@ -1092,7 +1105,7 @@ class EditBcfComment(bpy.types.Operator):
if comment.guid == self.comment_guid: if comment.guid == self.comment_guid:
comment.comment = blender_comment.comment comment.comment = blender_comment.comment
comment.modified_date = XmlDateTime.now() comment.modified_date = XmlDateTime.now()
comment.modified_author = context.scene.BCFProperties.author comment.modified_author = props.author
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid) bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
return {"FINISHED"} return {"FINISHED"}
@@ -1105,7 +1118,7 @@ class AddBcfComment(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
if not props.comment: if not props.comment:
cls.poll_message_set("No comment to add.") cls.poll_message_set("No comment to add.")
return False return False
@@ -1128,7 +1141,7 @@ class AddBcfComment(bpy.types.Operator):
assert bcfxml assert bcfxml
bcf_v2 = (bcfxml.version.version_id or "").startswith("2") bcf_v2 = (bcfxml.version.version_id or "").startswith("2")
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
comments = topic.comments comments = topic.comments
@@ -1136,7 +1149,7 @@ class AddBcfComment(bpy.types.Operator):
if bcf_v2: if bcf_v2:
comment = bcf.v2.model.Comment( comment = bcf.v2.model.Comment(
date=XmlDateTime.now(), date=XmlDateTime.now(),
author=context.scene.BCFProperties.author, author=props.author,
comment=props.comment, comment=props.comment,
guid=str(uuid.uuid4()), guid=str(uuid.uuid4()),
) )
@@ -1149,7 +1162,7 @@ class AddBcfComment(bpy.types.Operator):
else: else:
comment = bcf.v3.model.Comment( comment = bcf.v3.model.Comment(
date=XmlDateTime.now(), date=XmlDateTime.now(),
author=context.scene.BCFProperties.author, author=props.author,
comment=props.comment, comment=props.comment,
guid=str(uuid.uuid4()), guid=str(uuid.uuid4()),
) )
@@ -1179,7 +1192,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
if blender_topic is None: if blender_topic is None:
cls.poll_message_set("No topic is active.") cls.poll_message_set("No topic is active.")
@@ -1197,7 +1210,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic blender_topic = props.active_topic
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
if self.viewpoint_guid: if self.viewpoint_guid:
@@ -1517,7 +1530,8 @@ class OpenBcfReferenceLink(bpy.types.Operator):
index: bpy.props.IntProperty() index: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
webbrowser.open(context.scene.BCFProperties.topic_links[self.index].name) props = tool.Bcf.get_bcf_props()
webbrowser.open(props.topic_links[self.index].name)
return {"FINISHED"} return {"FINISHED"}
@@ -1530,7 +1544,8 @@ class SelectBcfHeaderFile(bpy.types.Operator):
def execute(self, context): def execute(self, context):
if self.filepath: if self.filepath:
context.scene.BCFProperties.file_reference = self.filepath props = tool.Bcf.get_bcf_props()
props.file_reference = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -1546,7 +1561,8 @@ class SelectBcfBimSnippetReference(bpy.types.Operator):
def execute(self, context): def execute(self, context):
if self.filepath: if self.filepath:
context.scene.BCFProperties.bim_snippet_reference = self.filepath props = tool.Bcf.get_bcf_props()
props.bim_snippet_reference = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -1562,7 +1578,8 @@ class SelectBcfDocumentReference(bpy.types.Operator):
def execute(self, context): def execute(self, context):
if self.filepath: if self.filepath:
context.scene.BCFProperties.document_reference = self.filepath props = tool.Bcf.get_bcf_props()
props.document_reference = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -1585,7 +1602,8 @@ class LoadBcfHeaderIfcFile(bpy.types.Operator):
assert bcfxml assert bcfxml
bcf_path = tool.Bcf.get_path() bcf_path = tool.Bcf.get_path()
topic = bcfxml.topics[context.scene.BCFProperties.active_topic.name] props = tool.Bcf.get_bcf_props()
topic = bcfxml.topics[props.active_topic.name]
entity = tool.Bcf.get_topic_header_files(topic)[self.index] entity = tool.Bcf.get_topic_header_files(topic)[self.index]
ifc_path = bcf.agnostic.topic.extract_file(topic, entity) ifc_path = bcf.agnostic.topic.extract_file(topic, entity)
bpy.ops.bim.load_project(filepath=ifc_path) bpy.ops.bim.load_project(filepath=ifc_path)
@@ -1605,7 +1623,8 @@ class ExtractBcfFile(bpy.types.Operator):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
topic = bcfxml.topics[context.scene.BCFProperties.active_topic.name] props = tool.Bcf.get_bcf_props()
topic = bcfxml.topics[props.active_topic.name]
if self.entity_type == "HEADER_FILE": if self.entity_type == "HEADER_FILE":
entity = tool.Bcf.get_topic_header_files(topic)[self.index] entity = tool.Bcf.get_topic_header_files(topic)[self.index]
+75 -4
View File
@@ -17,6 +17,7 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import bonsai.tool as tool
from . import bcfstore from . import bcfstore
from bonsai.bim.prop import StrProperty from bonsai.bim.prop import StrProperty
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
@@ -34,6 +35,7 @@ from functools import partial
from typing import Literal from typing import Literal
from typing_extensions import assert_never from typing_extensions import assert_never
from bcf.agnostic.extensions import get_extensions_attributes from bcf.agnostic.extensions import get_extensions_attributes
from typing import TYPE_CHECKING, Union
bcfviewpoints_enum = None bcfviewpoints_enum = None
@@ -95,7 +97,7 @@ def getBcfViewpoints(self, context, force_update=False):
global bcfviewpoints_enum global bcfviewpoints_enum
if bcfviewpoints_enum is None or force_update: # Retrieving Viewpoints is slow. Make sure we only do when needed if bcfviewpoints_enum is None or force_update: # Retrieving Viewpoints is slow. Make sure we only do when needed
bcfviewpoints_enum = [] bcfviewpoints_enum = []
props = context.scene.BCFProperties props = tool.Bcf.get_bcf_props()
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml assert bcfxml
topic = props.active_topic topic = props.active_topic
@@ -110,6 +112,12 @@ class BcfBimSnippet(PropertyGroup):
type: StringProperty(name="Type") type: StringProperty(name="Type")
is_external: BoolProperty(name="Is External") is_external: BoolProperty(name="Is External")
if TYPE_CHECKING:
schema: str
reference: str
type: str
is_external: bool
class BcfDocumentReference(PropertyGroup): class BcfDocumentReference(PropertyGroup):
reference: StringProperty(name="Reference") reference: StringProperty(name="Reference")
@@ -117,6 +125,12 @@ class BcfDocumentReference(PropertyGroup):
guid: StringProperty(name="GUID") guid: StringProperty(name="GUID")
is_external: BoolProperty(name="Is External") is_external: BoolProperty(name="Is External")
if TYPE_CHECKING:
reference: str
description: str
guid: str
is_external: bool
class BcfComment(PropertyGroup): class BcfComment(PropertyGroup):
name: StringProperty(name="GUID") name: StringProperty(name="GUID")
@@ -128,6 +142,16 @@ class BcfComment(PropertyGroup):
modified_author: StringProperty(name="Modified Author") modified_author: StringProperty(name="Modified Author")
is_editable: BoolProperty(name="Is Editable", default=False, update=updateBcfCommentIsEditable) is_editable: BoolProperty(name="Is Editable", default=False, update=updateBcfCommentIsEditable)
if TYPE_CHECKING:
name: str
date: str
author: str
comment: str
viewpoint: str
modified_date: str
modified_author: str
is_editable: bool
def get_extensions_items( def get_extensions_items(
self: "BCFProperties", context: bpy.types.Context, edit_text: str, extensions_attr: str self: "BCFProperties", context: bpy.types.Context, edit_text: str, extensions_attr: str
@@ -183,6 +207,30 @@ class BcfTopic(PropertyGroup):
comments: CollectionProperty(name="Comments", type=BcfComment) comments: CollectionProperty(name="Comments", type=BcfComment)
is_editable: BoolProperty(name="Edit Topic Attributes", default=False, update=updateBcfTopicIsEditable) is_editable: BoolProperty(name="Edit Topic Attributes", default=False, update=updateBcfTopicIsEditable)
if TYPE_CHECKING:
name: str
title: str
type: str
status: str
priority: str
stage: str
creation_date: str
creation_author: str
modified_date: str
modified_author: str
assigned_to: str
due_date: str
description: str
viewpoints: str
files: bpy.types.bpy_prop_collection_idprop[StrProperty]
reference_links: bpy.types.bpy_prop_collection_idprop[BcfReferenceLink]
labels: bpy.types.bpy_prop_collection_idprop[BcfLabel]
bim_snippet: BcfBimSnippet
document_references: bpy.types.bpy_prop_collection_idprop[BcfDocumentReference]
related_topics: bpy.types.bpy_prop_collection_idprop[StrProperty]
comments: bpy.types.bpy_prop_collection_idprop[BcfComment]
is_editable: bool
def get_related_topics(self: "BCFProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]: def get_related_topics(self: "BCFProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
global RELATED_TOPICS_ENUM_ITEMS global RELATED_TOPICS_ENUM_ITEMS
@@ -235,7 +283,30 @@ class BCFProperties(PropertyGroup):
comment: StringProperty(default="", name="Comment") comment: StringProperty(default="", name="Comment")
has_related_viewpoint: BoolProperty(name="Has Related Viewpoint", default=False) has_related_viewpoint: BoolProperty(name="Has Related Viewpoint", default=False)
def clear_input_fields(self): if TYPE_CHECKING:
bcf_file: str
bcf_version: str
comment_text_width: int
name: str
author: str
topics: bpy.types.bpy_prop_collection_idprop[BcfTopic]
active_topic_index: int
file_reference: str
file_ifc_project: str
file_ifc_spatial_structure_element: str
reference_link: str
label: str
bim_snippet_reference: str
bim_snippet_type: str
bim_snippet_schema: str
document_reference: str
document_reference_description: str
document_description: str
related_topic: str
comment: str
has_related_viewpoint: bool
def clear_input_fields(self) -> None:
self.file_reference = "" self.file_reference = ""
self.file_ifc_project = "" self.file_ifc_project = ""
self.file_ifc_spatial_structure_element = "" self.file_ifc_spatial_structure_element = ""
@@ -250,7 +321,7 @@ class BCFProperties(PropertyGroup):
self.has_related_viewpoint = False self.has_related_viewpoint = False
@property @property
def active_topic(self): def active_topic(self) -> Union[BcfTopic, None]:
if len(self.topics) == 0: if len(self.topics) == 0:
return None return None
if self.active_topic_index < 0: if self.active_topic_index < 0:
@@ -259,5 +330,5 @@ class BCFProperties(PropertyGroup):
self.active_topic_index = len(self.topics) - 1 self.active_topic_index = len(self.topics) - 1
return self.topics[self.active_topic_index] return self.topics[self.active_topic_index]
def refresh_topic(self, context): def refresh_topic(self, context: bpy.types.Context) -> None:
refreshBcfTopic(self, context) refreshBcfTopic(self, context)
+6 -10
View File
@@ -37,8 +37,7 @@ class BIM_PT_bcf(Panel):
layout.use_property_split = True layout.use_property_split = True
layout.use_property_decorate = False layout.use_property_decorate = False
scene = context.scene props = tool.Bcf.get_bcf_props()
props = scene.BCFProperties
if not bcfstore.BcfStore.get_bcfxml(): if not bcfstore.BcfStore.get_bcfxml():
row = layout.row(align=True) row = layout.row(align=True)
@@ -63,18 +62,17 @@ class BIM_PT_bcf(Panel):
row = layout.row() row = layout.row()
row.prop(props, "author") row.prop(props, "author")
props = context.scene.BCFProperties
row = layout.row() row = layout.row()
row.template_list("BIM_UL_topics", "", props, "topics", props, "active_topic_index") row.template_list("BIM_UL_topics", "", props, "topics", props, "active_topic_index")
col = row.column(align=True) col = row.column(align=True)
col.operator("bim.add_bcf_topic", icon="ADD", text="") col.operator("bim.add_bcf_topic", icon="ADD", text="")
col.operator("bim.remove_bcf_topic", icon="REMOVE", text="") col.operator("bim.remove_bcf_topic", icon="REMOVE", text="")
if props.active_topic_index < len(props.topics):
topic = props.active_topic topic = props.active_topic
if topic is not None:
is_editable = topic.is_editable is_editable = topic.is_editable
col.prop(topic, "is_editable", icon="CHECKMARK" if topic.is_editable else "GREASEPENCIL", icon_only=True) col.prop(topic, "is_editable", icon="CHECKMARK" if topic.is_editable else "GREASEPENCIL", icon_only=True)
topic = props.active_topic
row = layout.row() row = layout.row()
row.enabled = is_editable row.enabled = is_editable
row.prop(topic, "description", text="") row.prop(topic, "description", text="")
@@ -131,8 +129,7 @@ class BIM_PT_bcf_metadata(Panel):
layout.use_property_split = True layout.use_property_split = True
layout.use_property_decorate = False layout.use_property_decorate = False
scene = context.scene props = tool.Bcf.get_bcf_props()
props = scene.BCFProperties
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
if not bcfxml or props.active_topic_index >= len(props.topics): if not bcfxml or props.active_topic_index >= len(props.topics):
@@ -296,8 +293,7 @@ class BIM_PT_bcf_comments(Panel):
layout.use_property_split = True layout.use_property_split = True
layout.use_property_decorate = False layout.use_property_decorate = False
scene = context.scene props = tool.Bcf.get_bcf_props()
props = scene.BCFProperties
if props.active_topic_index >= len(props.topics): if props.active_topic_index >= len(props.topics):
layout.label(text="No BCF project is loaded") layout.label(text="No BCF project is loaded")
@@ -118,7 +118,7 @@ class MaterialClassificationsData(ReferencesData):
def references(cls): def references(cls):
results = [] results = []
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
if props.materials and props.active_material_index < len(props.materials): if props.materials and props.active_material_index < len(props.materials):
material = props.materials[props.active_material_index] material = props.materials[props.active_material_index]
if material.ifc_definition_id: if material.ifc_definition_id:
@@ -312,7 +312,7 @@ class BIM_PT_material_classifications(Panel, ReferenceUI):
def poll(cls, context): def poll(cls, context):
if not tool.Ifc.get(): if not tool.Ifc.get():
return False return False
props = context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
if props.is_editing and (material := props.active_material) and material.ifc_definition_id: if props.is_editing and (material := props.active_material) and material.ifc_definition_id:
return True return True
return False return False
@@ -689,13 +689,15 @@ class PurgeUnusedObjects(bpy.types.Operator, tool.Ifc.Operator):
scene = context.scene scene = context.scene
if object_type == "PROFILE": if object_type == "PROFILE":
if scene.BIMProfileProperties.is_editing: props = tool.Profile.get_profile_props()
if props.is_editing:
bpy.ops.bim.load_profiles() bpy.ops.bim.load_profiles()
elif object_type == "STYLE": elif object_type == "STYLE":
if scene.BIMStylesProperties.is_editing: if scene.BIMStylesProperties.is_editing:
bpy.ops.bim.load_styles() bpy.ops.bim.load_styles()
elif object_type == "MATERIAL": elif object_type == "MATERIAL":
if scene.BIMMaterialProperties.is_editing: props = tool.Material.get_material_props()
if props.is_editing:
bpy.ops.bim.load_materials() bpy.ops.bim.load_materials()
@@ -737,13 +739,15 @@ class MergeIdenticalObjects(bpy.types.Operator, tool.Ifc.Operator):
scene = context.scene scene = context.scene
if object_type == "PROFILE": if object_type == "PROFILE":
if scene.BIMProfileProperties.is_editing: props = tool.Profile.get_profile_props()
if props.is_editing:
bpy.ops.bim.load_profiles() bpy.ops.bim.load_profiles()
elif object_type == "STYLE": elif object_type == "STYLE":
if scene.BIMStylesProperties.is_editing: if scene.BIMStylesProperties.is_editing:
bpy.ops.bim.load_styles() bpy.ops.bim.load_styles()
elif object_type == "MATERIAL": elif object_type == "MATERIAL":
if scene.BIMMaterialProperties.is_editing: props = tool.Material.get_material_props()
if props.is_editing:
bpy.ops.bim.load_materials() bpy.ops.bim.load_materials()
@@ -2136,7 +2136,8 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator):
continue continue
if tool.Profile.is_editing_profile(): if tool.Profile.is_editing_profile():
profile_id = context.scene.BIMProfileProperties.active_profile_id props = tool.Profile.get_profile_props()
profile_id = props.active_profile_id
if profile_id: if profile_id:
profile = tool.Ifc.get().by_id(profile_id) profile = tool.Ifc.get().by_id(profile_id)
if tool.Ifc.get_object(profile): # We are editing an arbitrary profile if tool.Ifc.get_object(profile): # We are editing an arbitrary profile
@@ -2148,7 +2149,7 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator):
elif tool.Model.get_usage_type(element) == "PROFILE": elif tool.Model.get_usage_type(element) == "PROFILE":
bpy.ops.bim.edit_extrusion_axis() bpy.ops.bim.edit_extrusion_axis()
# if in the process of editing arbitrary profile # if in the process of editing arbitrary profile
elif context.scene.BIMProfileProperties.active_arbitrary_profile_id: elif props.active_arbitrary_profile_id:
bpy.ops.bim.edit_arbitrary_profile() bpy.ops.bim.edit_arbitrary_profile()
else: else:
bpy.ops.bim.edit_extrusion_profile() bpy.ops.bim.edit_extrusion_profile()
+3 -2
View File
@@ -47,7 +47,8 @@ class LibrariesData:
@classmethod @classmethod
def library_attributes(cls): def library_attributes(cls):
library_id = bpy.context.scene.BIMLibraryProperties.active_library_id props = tool.Library.get_library_props()
library_id = props.active_library_id
if not library_id: if not library_id:
return [] return []
results = [] results = []
@@ -63,7 +64,7 @@ class LibrariesData:
@classmethod @classmethod
def reference_attributes(cls): def reference_attributes(cls):
props = bpy.context.scene.BIMLibraryProperties props = tool.Library.get_library_props()
try: try:
reference_id = props.references[props.active_reference_index].ifc_definition_id reference_id = props.references[props.active_reference_index].ifc_definition_id
except: except:
@@ -30,6 +30,7 @@ from bpy.props import (
FloatVectorProperty, FloatVectorProperty,
CollectionProperty, CollectionProperty,
) )
from typing import TYPE_CHECKING, Literal
def update_active_reference_index(self, context): def update_active_reference_index(self, context):
@@ -40,6 +41,10 @@ class LibraryReference(PropertyGroup):
name: StringProperty(name="Name") name: StringProperty(name="Name")
ifc_definition_id: IntProperty(name="IFC Definition ID") ifc_definition_id: IntProperty(name="IFC Definition ID")
if TYPE_CHECKING:
name: str
ifc_definition_id: int
class BIMLibraryProperties(PropertyGroup): class BIMLibraryProperties(PropertyGroup):
editing_mode: EnumProperty( editing_mode: EnumProperty(
@@ -58,3 +63,12 @@ class BIMLibraryProperties(PropertyGroup):
active_reference_id: IntProperty(name="Active Reference Id") active_reference_id: IntProperty(name="Active Reference Id")
references: CollectionProperty(type=LibraryReference, name="References") references: CollectionProperty(type=LibraryReference, name="References")
active_reference_index: IntProperty(name="Active Reference Index", update=update_active_reference_index) active_reference_index: IntProperty(name="Active Reference Index", update=update_active_reference_index)
if TYPE_CHECKING:
editing_mode: Literal["NONE", "LIBRARY", "REFERENCES", "REFERENCE"]
library_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
active_library_id: int
reference_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
active_reference_id: int
references: bpy.types.bpy_prop_collection_idprop[LibraryReference]
active_reference_index: int
+14 -4
View File
@@ -16,10 +16,16 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy
import bonsai.bim.helper import bonsai.bim.helper
import bonsai.tool as tool import bonsai.tool as tool
from bpy.types import Panel, UIList from bpy.types import Panel, UIList
from bonsai.bim.module.library.data import LibrariesData, LibraryReferencesData from bonsai.bim.module.library.data import LibrariesData, LibraryReferencesData
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from bonsai.bim.module.library.prop import BIMLibraryProperties, LibraryReference
class BIM_PT_libraries(Panel): class BIM_PT_libraries(Panel):
@@ -38,7 +44,7 @@ class BIM_PT_libraries(Panel):
def draw(self, context): def draw(self, context):
if not LibrariesData.is_loaded: if not LibrariesData.is_loaded:
LibrariesData.load() LibrariesData.load()
self.props = context.scene.BIMLibraryProperties self.props = tool.Library.get_library_props()
if self.props.editing_mode == "LIBRARY": if self.props.editing_mode == "LIBRARY":
self.draw_editable_library_ui() self.draw_editable_library_ui()
@@ -110,7 +116,7 @@ class BIM_PT_library_references(Panel):
def draw(self, context): def draw(self, context):
if not LibraryReferencesData.is_loaded: if not LibraryReferencesData.is_loaded:
LibraryReferencesData.load() LibraryReferencesData.load()
self.props = context.scene.BIMLibraryProperties self.props = tool.Library.get_library_props()
if self.props.editing_mode == "REFERENCES": if self.props.editing_mode == "REFERENCES":
self.layout.template_list( self.layout.template_list(
@@ -129,7 +135,9 @@ class BIM_PT_library_references(Panel):
class BIM_UL_library_references(UIList): class BIM_UL_library_references(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: LibraryReference, icon, active_data, active_propname
):
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.label(text=item.name) row.label(text=item.name)
@@ -140,7 +148,9 @@ class BIM_UL_library_references(UIList):
class BIM_UL_object_library_references(UIList): class BIM_UL_object_library_references(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: LibraryReference, icon, active_data, active_propname
):
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.label(text=item.name) row.label(text=item.name)
@@ -48,7 +48,8 @@ class MaterialsData:
@classmethod @classmethod
def total_materials(cls): def total_materials(cls):
return len(tool.Ifc.get().by_type(bpy.context.scene.BIMMaterialProperties.material_type)) props = tool.Material.get_material_props()
return len(tool.Ifc.get().by_type(props.material_type))
@classmethod @classmethod
def material_types(cls): def material_types(cls):
@@ -101,7 +102,7 @@ class MaterialsData:
@classmethod @classmethod
def material_styles_data(cls) -> dict[int, list[dict[str, Any]]]: def material_styles_data(cls) -> dict[int, list[dict[str, Any]]]:
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
material_styles_data: dict[int, list[dict[str, Any]]] = {} material_styles_data: dict[int, list[dict[str, Any]]] = {}
for material_item in props.materials: for material_item in props.materials:
@@ -19,6 +19,7 @@
import bpy import bpy
import json import json
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.material
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.attribute import ifcopenshell.util.attribute
import ifcopenshell.util.representation import ifcopenshell.util.representation
@@ -40,7 +41,8 @@ class LoadMaterials(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
core.load_materials(tool.Material, context.scene.BIMMaterialProperties.material_type) props = tool.Material.get_material_props()
core.load_materials(tool.Material, props.material_type)
return {"FINISHED"} return {"FINISHED"}
@@ -327,12 +329,13 @@ class AddProfile(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
props = tool.Material.get_material_props()
ifcopenshell.api.run( ifcopenshell.api.run(
"material.add_profile", "material.add_profile",
self.file, self.file,
profile_set=self.file.by_id(self.profile_set), profile_set=self.file.by_id(self.profile_set),
material=self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), material=self.file.by_id(int(obj.BIMObjectMaterialProperties.material)),
profile=self.file.by_id(int(context.scene.BIMMaterialProperties.profiles)), profile=self.file.by_id(int(props.profiles)),
) )
@@ -662,7 +665,7 @@ class EnableEditingMaterialSetItem(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.mprops = context.scene.BIMMaterialProperties self.mprops = tool.Material.get_material_props()
self.props = obj.BIMObjectMaterialProperties self.props = obj.BIMObjectMaterialProperties
self.props.active_material_set_item_id = self.material_set_item self.props.active_material_set_item_id = self.material_set_item
@@ -706,7 +709,7 @@ class EditMaterialSetItem(bpy.types.Operator, tool.Ifc.Operator):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
props = obj.BIMObjectMaterialProperties props = obj.BIMObjectMaterialProperties
mprops = context.scene.BIMMaterialProperties mprops = tool.Material.get_material_props()
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
material = ifcopenshell.util.element.get_material(element, should_skip_usage=True) material = ifcopenshell.util.element.get_material(element, should_skip_usage=True)
@@ -763,7 +766,7 @@ class ExpandMaterialCategory(bpy.types.Operator):
return self.execute(context) return self.execute(context)
def execute(self, context): def execute(self, context):
props = context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
for index, category in ( for index, category in (
(i, c) (i, c)
for i, c in enumerate(props.materials) for i, c in enumerate(props.materials)
@@ -792,7 +795,7 @@ class ContractMaterialCategory(bpy.types.Operator):
return self.execute(context) return self.execute(context)
def execute(self, context): def execute(self, context):
props = context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
for index, category in ( for index, category in (
(i, c) (i, c)
for i, c in enumerate(props.materials) for i, c in enumerate(props.materials)
@@ -812,7 +815,7 @@ class EnableEditingMaterialStyle(bpy.types.Operator):
material: bpy.props.IntProperty() material: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
props.active_material_id = self.material props.active_material_id = self.material
props.editing_material_type = "STYLE" props.editing_material_type = "STYLE"
@@ -843,7 +846,7 @@ class EditMaterialStyle(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
material = ifc_file.by_id(props.active_material_id) material = ifc_file.by_id(props.active_material_id)
style = ifc_file.by_id(int(props.styles)) style = ifc_file.by_id(int(props.styles))
@@ -867,7 +870,7 @@ class UnassignMaterialStyle(bpy.types.Operator, tool.Ifc.Operator):
context: bpy.props.IntProperty() context: bpy.props.IntProperty()
def _execute(self, context): def _execute(self, context):
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
material = tool.Ifc.get().by_id(props.materials[props.active_material_index].ifc_definition_id) material = tool.Ifc.get().by_id(props.materials[props.active_material_index].ifc_definition_id)
style = tool.Ifc.get().by_id(self.style) style = tool.Ifc.get().by_id(self.style)
context = tool.Ifc.get().by_id(self.context) context = tool.Ifc.get().by_id(self.context)
@@ -888,7 +891,7 @@ class SelectMaterialInMaterialsUI(bpy.types.Operator):
material_id: int material_id: int
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
material_id = self.material_id material_id = self.material_id
material = ifc_file.by_id(material_id) material = ifc_file.by_id(material_id)
@@ -121,7 +121,7 @@ def set_material_name(self: "Material", new_category_name: str) -> None:
material.Category = new_category_name material.Category = new_category_name
# Reload UI elements if necessary. # Reload UI elements if necessary.
props: "BIMMaterialProperties" = self.id_data.BIMMaterialProperties props = tool.Material.get_material_props()
new_category_name_already_in_use = bool( new_category_name_already_in_use = bool(
next((m for m in props.materials if m.is_category and m.name == new_category_name), None) next((m for m in props.materials if m.is_category and m.name == new_category_name), None)
) )
+12 -6
View File
@@ -29,7 +29,7 @@ from bonsai.bim.module.drawing.helper import format_distance
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from bonsai.bim.module.material.prop import Material from bonsai.bim.module.material.prop import Material, BIMMaterialProperties
class BIM_PT_materials(Panel): class BIM_PT_materials(Panel):
@@ -49,7 +49,7 @@ class BIM_PT_materials(Panel):
if not MaterialsData.is_loaded: if not MaterialsData.is_loaded:
MaterialsData.load() MaterialsData.load()
self.props = context.scene.BIMMaterialProperties self.props = tool.Material.get_material_props()
material = tool.Material.get_active_material_item() material = tool.Material.get_active_material_item()
material_id = material.ifc_definition_id if material else None material_id = material.ifc_definition_id if material else None
@@ -156,7 +156,7 @@ class BIM_PT_object_material(Panel):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
self.oprops = context.active_object.BIMObjectProperties self.oprops = context.active_object.BIMObjectProperties
self.props = context.active_object.BIMObjectMaterialProperties self.props = context.active_object.BIMObjectMaterialProperties
self.mprops = context.scene.BIMMaterialProperties self.mprops = tool.Material.get_material_props()
if not ObjectMaterialData.data["materials"]: if not ObjectMaterialData.data["materials"]:
row = self.layout.row(align=True) row = self.layout.row(align=True)
@@ -401,10 +401,16 @@ class BIM_PT_object_material(Panel):
class BIM_UL_materials(UIList): class BIM_UL_materials(UIList):
def draw_item( def draw_item(
self, context, layout: bpy.types.UILayout, data, item: Material, icon, active_data, active_propname self,
context,
layout: bpy.types.UILayout,
data: BIMMaterialProperties,
item: Material,
icon,
active_data,
active_propname,
) -> None: ) -> None:
mprops = context.scene.BIMMaterialProperties material_type = data.material_type
material_type = mprops.material_type
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
+2 -2
View File
@@ -51,7 +51,7 @@ class ProfileData:
@classmethod @classmethod
def active_profile_users(cls): def active_profile_users(cls):
profiles_props = bpy.context.scene.BIMProfileProperties profiles_props = tool.Profile.get_profile_props()
if profiles_props.active_profile_index >= len(profiles_props.profiles): if profiles_props.active_profile_index >= len(profiles_props.profiles):
return 0 return 0
profile_prop = profiles_props.profiles[profiles_props.active_profile_index] profile_prop = profiles_props.profiles[profiles_props.active_profile_index]
@@ -83,7 +83,7 @@ class ProfileData:
@classmethod @classmethod
def is_arbitrary_profile(cls): def is_arbitrary_profile(cls):
props = bpy.context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
if props.active_profile_id: if props.active_profile_id:
profile = tool.Ifc.get().by_id(props.active_profile_id) profile = tool.Ifc.get().by_id(props.active_profile_id)
if profile.is_a("IfcArbitraryClosedProfileDef"): if profile.is_a("IfcArbitraryClosedProfileDef"):
@@ -35,7 +35,7 @@ class LoadProfiles(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
props.profiles.clear() props.profiles.clear()
filter_material_profiles = props.is_filtering_material_profiles filter_material_profiles = props.is_filtering_material_profiles
@@ -64,7 +64,8 @@ class DisableProfileEditingUI(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
context.scene.BIMProfileProperties.is_editing = False props = tool.Profile.get_profile_props()
props.is_editing = False
return {"FINISHED"} return {"FINISHED"}
@@ -75,7 +76,7 @@ class RemoveProfileDef(bpy.types.Operator, tool.Ifc.Operator):
profile: bpy.props.IntProperty() profile: bpy.props.IntProperty()
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
current_index = props.active_profile_index current_index = props.active_profile_index
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
@@ -113,7 +114,7 @@ class EnableEditingProfile(bpy.types.Operator):
profile: bpy.props.IntProperty() profile: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
props.profile_attributes.clear() props.profile_attributes.clear()
bonsai.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.profile), props.profile_attributes) bonsai.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.profile), props.profile_attributes)
props.active_profile_id = self.profile props.active_profile_id = self.profile
@@ -126,7 +127,8 @@ class DisableEditingProfile(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
context.scene.BIMProfileProperties.active_profile_id = 0 props = tool.Profile.get_profile_props()
props.active_profile_id = 0
bpy.ops.bim.disable_editing_arbitrary_profile() bpy.ops.bim.disable_editing_arbitrary_profile()
return {"FINISHED"} return {"FINISHED"}
@@ -137,7 +139,7 @@ class EditProfile(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
attributes = bonsai.bim.helper.export_attributes(props.profile_attributes) attributes = bonsai.bim.helper.export_attributes(props.profile_attributes)
profile = tool.Ifc.get().by_id(props.active_profile_id) profile = tool.Ifc.get().by_id(props.active_profile_id)
ifcopenshell.api.run("profile.edit_profile", tool.Ifc.get(), profile=profile, attributes=attributes) ifcopenshell.api.run("profile.edit_profile", tool.Ifc.get(), profile=profile, attributes=attributes)
@@ -152,7 +154,7 @@ class AddProfileDef(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
profile_class = props.profile_classes profile_class = props.profile_classes
if profile_class == "IfcArbitraryClosedProfileDef": if profile_class == "IfcArbitraryClosedProfileDef":
obj = props.object_to_profile obj = props.object_to_profile
@@ -229,7 +231,7 @@ class EnableEditingArbitraryProfile(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
active_profile = props.profiles[props.active_profile_index] active_profile = props.profiles[props.active_profile_index]
profile_id = active_profile.ifc_definition_id profile_id = active_profile.ifc_definition_id
props.active_arbitrary_profile_id = profile_id props.active_arbitrary_profile_id = profile_id
@@ -253,7 +255,7 @@ def disable_editing_arbitrary_profile(context):
bpy.data.objects.remove(obj) bpy.data.objects.remove(obj)
bpy.data.meshes.remove(profile_mesh) bpy.data.meshes.remove(profile_mesh)
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
props.active_arbitrary_profile_id = 0 props.active_arbitrary_profile_id = 0
# need to update profile manager ui # need to update profile manager ui
# if this was called from decorator # if this was called from decorator
@@ -276,7 +278,7 @@ class EditArbitraryProfile(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
old_profile = tool.Ifc.get().by_id(props.active_arbitrary_profile_id) old_profile = tool.Ifc.get().by_id(props.active_arbitrary_profile_id)
obj = context.active_object obj = context.active_object
@@ -322,7 +324,7 @@ class SelectProfileInProfilesUI(bpy.types.Operator):
profile_id: bpy.props.IntProperty() profile_id: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
profile = ifc_file.by_id(self.profile_id) profile = ifc_file.by_id(self.profile_id)
bpy.ops.bim.load_profiles() bpy.ops.bim.load_profiles()
+13 -2
View File
@@ -35,7 +35,7 @@ from bpy.props import (
FloatVectorProperty, FloatVectorProperty,
CollectionProperty, CollectionProperty,
) )
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Union
def get_profile_classes(self, context): def get_profile_classes(self, context):
@@ -91,6 +91,17 @@ class BIMProfileProperties(PropertyGroup):
poll=lambda self, obj: obj.type == "MESH", poll=lambda self, obj: obj.type == "MESH",
) )
if TYPE_CHECKING:
is_editing: bool
profiles: bpy.types.bpy_prop_collection_idprop[Profile]
active_profile_index: int
active_profile_id: int
active_arbitrary_profile_id: int
profile_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
profile_classes: str
is_filtering_material_profiles: bool
object_to_profile: Union[bpy.types.Object, None]
def generate_thumbnail_for_active_profile(): def generate_thumbnail_for_active_profile():
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
@@ -98,7 +109,7 @@ def generate_thumbnail_for_active_profile():
if bpy.app.background: if bpy.app.background:
return return
props = bpy.context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
preview_collection = ProfileData.preview_collection preview_collection = ProfileData.preview_collection
+16 -3
View File
@@ -16,12 +16,17 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy import bpy
import bonsai.bim.helper import bonsai.bim.helper
import bonsai.tool as tool import bonsai.tool as tool
from bpy.types import Panel, UIList from bpy.types import Panel, UIList
from bonsai.bim.module.profile.data import ProfileData from bonsai.bim.module.profile.data import ProfileData
from bonsai.bim.module.profile.prop import generate_thumbnail_for_active_profile from bonsai.bim.module.profile.prop import generate_thumbnail_for_active_profile
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from bonsai.bim.module.profile.prop import BIMProfileProperties, Profile
class BIM_PT_profiles(Panel): class BIM_PT_profiles(Panel):
@@ -40,7 +45,7 @@ class BIM_PT_profiles(Panel):
def draw(self, context): def draw(self, context):
if not ProfileData.is_loaded: if not ProfileData.is_loaded:
ProfileData.load() ProfileData.load()
self.props = context.scene.BIMProfileProperties self.props = tool.Profile.get_profile_props()
active_profile = None active_profile = None
if self.props.is_editing and (active_profile := tool.Profile.get_active_profile_ui()): if self.props.is_editing and (active_profile := tool.Profile.get_active_profile_ui()):
@@ -129,8 +134,16 @@ class BIM_PT_profiles(Panel):
class BIM_UL_profiles(UIList): class BIM_UL_profiles(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
props = context.scene.BIMProfileProperties self,
context,
layout: bpy.types.UILayout,
data: BIMProfileProperties,
item: Profile,
icon,
active_data,
active_propname,
):
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.prop(item, "name", text="", emboss=False) row.prop(item, "name", text="", emboss=False)
+2 -2
View File
@@ -175,7 +175,7 @@ class MaterialPsetsData(Data):
@classmethod @classmethod
def load(cls): def load(cls):
ifc_definition_id = None ifc_definition_id = None
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
if props.materials and props.active_material_index < len(props.materials): if props.materials and props.active_material_index < len(props.materials):
ifc_definition_id = props.materials[props.active_material_index].ifc_definition_id ifc_definition_id = props.materials[props.active_material_index].ifc_definition_id
@@ -188,7 +188,7 @@ class MaterialPsetsData(Data):
@classmethod @classmethod
def pset_name(cls): def pset_name(cls):
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
if props.materials and props.active_material_index < len(props.materials): if props.materials and props.active_material_index < len(props.materials):
material = props.materials[props.active_material_index] material = props.materials[props.active_material_index]
if material.ifc_definition_id: if material.ifc_definition_id:
+1 -1
View File
@@ -173,7 +173,7 @@ def get_group_qto_names(self, context):
def get_profile_pset_names(self, context): def get_profile_pset_names(self, context):
global psetnames global psetnames
pprops = context.scene.BIMProfileProperties pprops = tool.Profile.get_profile_props()
ifc_class = IfcStore.get_file().by_id(pprops.profiles[pprops.active_profile_index].ifc_definition_id).is_a() ifc_class = IfcStore.get_file().by_id(pprops.profiles[pprops.active_profile_index].ifc_definition_id).is_a()
if ifc_class not in psetnames: if ifc_class not in psetnames:
psets = bonsai.bim.schema.ifc.psetqto.get_applicable(ifc_class, pset_only=True, schema=tool.Ifc.get_schema()) psets = bonsai.bim.schema.ifc.psetqto.get_applicable(ifc_class, pset_only=True, schema=tool.Ifc.get_schema())
+4 -4
View File
@@ -403,13 +403,13 @@ class BIM_PT_material_psets(Panel):
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
if not ifc_file or ifc_file.schema == "IFC2X3": if not ifc_file or ifc_file.schema == "IFC2X3":
return False # We don't support material psets in IFC2X3 because they suck return False # We don't support material psets in IFC2X3 because they suck
props = context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
if props.is_editing and (material := props.active_material) and material.ifc_definition_id: if props.is_editing and (material := props.active_material) and material.ifc_definition_id:
return True return True
return False return False
def draw(self, context): def draw(self, context):
props = context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
if props.materials and props.active_material_index < len(props.materials): if props.materials and props.active_material_index < len(props.materials):
ifc_definition_id = props.materials[props.active_material_index].ifc_definition_id ifc_definition_id = props.materials[props.active_material_index].ifc_definition_id
@@ -663,10 +663,10 @@ class BIM_PT_profile_psets(Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
props = context.scene.BIMProfileProperties props = tool.Profile.get_profile_props()
if not props.is_editing: if not props.is_editing:
return False return False
total_profiles = len(context.scene.BIMProfileProperties.profiles) total_profiles = len(props.profiles)
if total_profiles > 0 and props.active_profile_index < total_profiles: if total_profiles > 0 and props.active_profile_index < total_profiles:
return True return True
return False return False
+11 -2
View File
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bcf.v2.visinfo import bcf.v2.visinfo
import bonsai.core.tool import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
@@ -32,16 +33,24 @@ import bcf.agnostic.model
import bcf.agnostic.topic import bcf.agnostic.topic
import bcf.agnostic.visinfo import bcf.agnostic.visinfo
from typing import Any, Union, TypeVar, TypeGuard, Optional from typing import Any, Union, TypeVar, TypeGuard, Optional, TYPE_CHECKING
if TYPE_CHECKING:
from bonsai.bim.module.bcf.prop import BCFProperties
T = TypeVar("T") T = TypeVar("T")
class Bcf(bonsai.core.tool.Bcf): class Bcf(bonsai.core.tool.Bcf):
@classmethod
def get_bcf_props(cls) -> "BCFProperties":
return bpy.context.scene.BCFProperties
@classmethod @classmethod
def get_path(cls) -> str: def get_path(cls) -> str:
return bpy.context.scene.BCFProperties.bcf_file props = cls.get_bcf_props()
return props.bcf_file
@classmethod @classmethod
def is_list_of(cls, a: list[Any], t: type[T]) -> TypeGuard[list[T]]: def is_list_of(cls, a: list[Any], t: type[T]) -> TypeGuard[list[T]]:
+4 -6
View File
@@ -191,9 +191,8 @@ class Blender(bonsai.core.tool.Blender):
if obj_type == "Object": if obj_type == "Object":
return bpy.data.objects.get(obj).BIMObjectProperties.ifc_definition_id return bpy.data.objects.get(obj).BIMObjectProperties.ifc_definition_id
elif obj_type == "Material": elif obj_type == "Material":
return context.scene.BIMMaterialProperties.materials[ props = tool.Material.get_material_props()
context.scene.BIMMaterialProperties.active_material_index return props.materials[props.active_material_index].ifc_definition_id
].ifc_definition_id
elif obj_type == "MaterialSetItem": elif obj_type == "MaterialSetItem":
return bpy.data.objects.get(obj).BIMObjectMaterialProperties.active_material_set_item_id return bpy.data.objects.get(obj).BIMObjectMaterialProperties.active_material_set_item_id
elif obj_type == "Task": elif obj_type == "Task":
@@ -208,9 +207,8 @@ class Blender(bonsai.core.tool.Blender):
context.scene.BIMResourceProperties.active_resource_index context.scene.BIMResourceProperties.active_resource_index
].ifc_definition_id ].ifc_definition_id
elif obj_type == "Profile": elif obj_type == "Profile":
return context.scene.BIMProfileProperties.profiles[ props = tool.Profile.get_profile_props()
context.scene.BIMProfileProperties.active_profile_index return props.profiles[props.active_profile_index].ifc_definition_id
].ifc_definition_id
elif obj_type == "WorkSchedule": elif obj_type == "WorkSchedule":
return context.scene.BIMWorkScheduleProperties.active_work_schedule_id return context.scene.BIMWorkScheduleProperties.active_work_schedule_id
elif obj_type == "Group": elif obj_type == "Group":
+24 -12
View File
@@ -16,52 +16,62 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import ifcopenshell import ifcopenshell
import bpy import bpy
import bonsai.bim.helper import bonsai.bim.helper
import bonsai.core.tool import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
from typing import Literal, Any, Union from typing import Literal, Any, Union, TYPE_CHECKING
if TYPE_CHECKING:
from bonsai.bim.module.library.prop import BIMLibraryProperties
class Library(bonsai.core.tool.Library): class Library(bonsai.core.tool.Library):
@classmethod
def get_library_props(cls) -> BIMLibraryProperties:
return bpy.context.scene.BIMLibraryProperties
@classmethod @classmethod
def clear_editing_mode(cls) -> None: def clear_editing_mode(cls) -> None:
bpy.context.scene.BIMLibraryProperties.editing_mode = "NONE" cls.get_library_props().editing_mode = "NONE"
@classmethod @classmethod
def export_library_attributes(cls) -> dict[str, Any]: def export_library_attributes(cls) -> dict[str, Any]:
props = bpy.context.scene.BIMLibraryProperties props = cls.get_library_props()
return bonsai.bim.helper.export_attributes(props.library_attributes) return bonsai.bim.helper.export_attributes(props.library_attributes)
@classmethod @classmethod
def export_reference_attributes(cls) -> dict[str, Any]: def export_reference_attributes(cls) -> dict[str, Any]:
props = bpy.context.scene.BIMLibraryProperties props = cls.get_library_props()
return bonsai.bim.helper.export_attributes(props.reference_attributes) return bonsai.bim.helper.export_attributes(props.reference_attributes)
@classmethod @classmethod
def get_active_library(cls) -> ifcopenshell.entity_instance: def get_active_library(cls) -> ifcopenshell.entity_instance:
return tool.Ifc.get().by_id(bpy.context.scene.BIMLibraryProperties.active_library_id) props = cls.get_library_props()
return tool.Ifc.get().by_id(props.active_library_id)
@classmethod @classmethod
def get_active_reference(cls) -> ifcopenshell.entity_instance: def get_active_reference(cls) -> ifcopenshell.entity_instance:
return tool.Ifc.get().by_id(bpy.context.scene.BIMLibraryProperties.active_reference_id) props = cls.get_library_props()
return tool.Ifc.get().by_id(props.active_reference_id)
@classmethod @classmethod
def import_library_attributes(cls, library: ifcopenshell.entity_instance) -> None: def import_library_attributes(cls, library: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMLibraryProperties props = cls.get_library_props()
props.library_attributes.clear() props.library_attributes.clear()
bonsai.bim.helper.import_attributes2(library, props.library_attributes) bonsai.bim.helper.import_attributes2(library, props.library_attributes)
@classmethod @classmethod
def import_reference_attributes(cls, reference: ifcopenshell.entity_instance) -> None: def import_reference_attributes(cls, reference: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMLibraryProperties props = cls.get_library_props()
props.reference_attributes.clear() props.reference_attributes.clear()
bonsai.bim.helper.import_attributes2(reference, props.reference_attributes) bonsai.bim.helper.import_attributes2(reference, props.reference_attributes)
@classmethod @classmethod
def import_references(cls, library: ifcopenshell.entity_instance) -> None: def import_references(cls, library: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMLibraryProperties props = cls.get_library_props()
props.references.clear() props.references.clear()
if tool.Ifc.get_schema() == "IFC2X3": if tool.Ifc.get_schema() == "IFC2X3":
references = library.LibraryReference references = library.LibraryReference
@@ -74,7 +84,7 @@ class Library(bonsai.core.tool.Library):
@classmethod @classmethod
def set_active_library(cls, library: Union[ifcopenshell.entity_instance, None]) -> None: def set_active_library(cls, library: Union[ifcopenshell.entity_instance, None]) -> None:
props = bpy.context.scene.BIMLibraryProperties props = cls.get_library_props()
if library is None: if library is None:
props.active_library_id = 0 props.active_library_id = 0
else: else:
@@ -82,8 +92,10 @@ class Library(bonsai.core.tool.Library):
@classmethod @classmethod
def set_active_reference(cls, reference: ifcopenshell.entity_instance) -> None: def set_active_reference(cls, reference: ifcopenshell.entity_instance) -> None:
bpy.context.scene.BIMLibraryProperties.active_reference_id = reference.id() props = cls.get_library_props()
props.active_reference_id = reference.id()
@classmethod @classmethod
def set_editing_mode(cls, mode: Literal["LIBRARY", "REFERENCES", "REFERENCE"]) -> None: def set_editing_mode(cls, mode: Literal["LIBRARY", "REFERENCES", "REFERENCE"]) -> None:
bpy.context.scene.BIMLibraryProperties.editing_mode = mode props = cls.get_library_props()
props.editing_mode = mode
+20 -10
View File
@@ -33,12 +33,18 @@ from typing_extensions import assert_never
if TYPE_CHECKING: if TYPE_CHECKING:
# Avoid circular imports. # Avoid circular imports.
from bonsai.bim.module.material.prop import Material as MaterialItem from bonsai.bim.module.material.prop import Material as MaterialItem
from bonsai.bim.module.material.prop import BIMMaterialProperties
class Material(bonsai.core.tool.Material): class Material(bonsai.core.tool.Material):
@classmethod
def get_material_props(cls) -> BIMMaterialProperties:
return bpy.context.scene.BIMMaterialProperties
@classmethod @classmethod
def disable_editing_materials(cls) -> None: def disable_editing_materials(cls) -> None:
bpy.context.scene.BIMMaterialProperties.is_editing = False props = tool.Material.get_material_props()
props.is_editing = False
@classmethod @classmethod
def duplicate_material(cls, material: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance: def duplicate_material(cls, material: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
@@ -55,11 +61,13 @@ class Material(bonsai.core.tool.Material):
@classmethod @classmethod
def enable_editing_materials(cls) -> None: def enable_editing_materials(cls) -> None:
bpy.context.scene.BIMMaterialProperties.is_editing = True props = tool.Material.get_material_props()
props.is_editing = True
@classmethod @classmethod
def get_active_material_type(cls) -> str: def get_active_material_type(cls) -> str:
return bpy.context.scene.BIMMaterialProperties.material_type props = tool.Material.get_material_props()
return props.material_type
@classmethod @classmethod
def get_elements_by_material(cls, material: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]: def get_elements_by_material(cls, material: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
@@ -68,7 +76,7 @@ class Material(bonsai.core.tool.Material):
@classmethod @classmethod
def get_active_material_item(cls) -> Union[MaterialItem, None]: def get_active_material_item(cls) -> Union[MaterialItem, None]:
"""Get active material props item if index is valid, otherwise, return None.""" """Get active material props item if index is valid, otherwise, return None."""
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
if 0 <= props.active_material_index < len(props.materials): if 0 <= props.active_material_index < len(props.materials):
return props.materials[props.active_material_index] return props.materials[props.active_material_index]
return None return None
@@ -80,7 +88,7 @@ class Material(bonsai.core.tool.Material):
@classmethod @classmethod
def import_material_definitions(cls, material_type: str) -> None: def import_material_definitions(cls, material_type: str) -> None:
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
# Store active category name to reselect it later. # Store active category name to reselect it later.
# Occurs when we expand/contract all categories. # Occurs when we expand/contract all categories.
@@ -140,7 +148,8 @@ class Material(bonsai.core.tool.Material):
@classmethod @classmethod
def is_editing_materials(cls) -> bool: def is_editing_materials(cls) -> bool:
return bpy.context.scene.BIMMaterialProperties.is_editing props = tool.Material.get_material_props()
return props.is_editing
@classmethod @classmethod
def is_material_used_in_sets(cls, material: ifcopenshell.entity_instance) -> bool: def is_material_used_in_sets(cls, material: ifcopenshell.entity_instance) -> bool:
@@ -156,23 +165,24 @@ class Material(bonsai.core.tool.Material):
@classmethod @classmethod
def load_material_attributes(cls, material: ifcopenshell.entity_instance) -> None: def load_material_attributes(cls, material: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
props.material_attributes.clear() props.material_attributes.clear()
bonsai.bim.helper.import_attributes2(material, props.material_attributes) bonsai.bim.helper.import_attributes2(material, props.material_attributes)
@classmethod @classmethod
def enable_editing_material(cls, material: ifcopenshell.entity_instance) -> None: def enable_editing_material(cls, material: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
props.active_material_id = material.id() props.active_material_id = material.id()
props.editing_material_type = "ATTRIBUTES" props.editing_material_type = "ATTRIBUTES"
@classmethod @classmethod
def get_material_attributes(cls) -> dict[str, Any]: def get_material_attributes(cls) -> dict[str, Any]:
return bonsai.bim.helper.export_attributes(bpy.context.scene.BIMMaterialProperties.material_attributes) props = tool.Material.get_material_props()
return bonsai.bim.helper.export_attributes(props.material_attributes)
@classmethod @classmethod
def disable_editing_material(cls) -> None: def disable_editing_material(cls) -> None:
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
props.active_material_id = 0 props.active_material_id = 0
props.editing_material_type = "" props.editing_material_type = ""
+3 -2
View File
@@ -26,6 +26,7 @@ import collections.abc
import numpy as np import numpy as np
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.grid
import ifcopenshell.api.pset import ifcopenshell.api.pset
import ifcopenshell.geom import ifcopenshell.geom
import ifcopenshell.util.element import ifcopenshell.util.element
@@ -1973,14 +1974,14 @@ class Model(bonsai.core.tool.Model):
extrusion.Position = position extrusion.Position = position
@classmethod @classmethod
def get_existing_x_angle(cls, extrusion): def get_existing_x_angle(cls, extrusion: ifcopenshell.entity_instance) -> float:
x, y, z = extrusion.ExtrudedDirection.DirectionRatios x, y, z = extrusion.ExtrudedDirection.DirectionRatios
x_angle = Vector((0, 1)).angle_signed(Vector((y, z))) x_angle = Vector((0, 1)).angle_signed(Vector((y, z)))
return x_angle return x_angle
@classmethod @classmethod
def create_axis_curve(cls, obj: bpy.types.Object, grid_axis: ifcopenshell.entity_instance): def create_axis_curve(cls, obj: bpy.types.Object, grid_axis: ifcopenshell.entity_instance) -> None:
m = tool.Surveyor.get_absolute_matrix(obj) m = tool.Surveyor.get_absolute_matrix(obj)
points = [m @ np.array(v.co.to_4d()) for v in obj.data.vertices[0:2]] points = [m @ np.array(v.co.to_4d()) for v in obj.data.vertices[0:2]]
ifcopenshell.api.grid.create_axis_curve( ifcopenshell.api.grid.create_axis_curve(
+6 -1
View File
@@ -33,9 +33,14 @@ from typing import Union, TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
import bonsai.bim.module.profile.prop import bonsai.bim.module.profile.prop
from bonsai.bim.module.profile.prop import BIMProfileProperties
class Profile(bonsai.core.tool.Profile): class Profile(bonsai.core.tool.Profile):
@classmethod
def get_profile_props(cls) -> BIMProfileProperties:
return bpy.context.scene.BIMProfileProperties
@classmethod @classmethod
def draw_image_for_ifc_profile( def draw_image_for_ifc_profile(
cls, draw: PIL.ImageDraw.ImageDraw, profile: ifcopenshell.entity_instance, size: float cls, draw: PIL.ImageDraw.ImageDraw, profile: ifcopenshell.entity_instance, size: float
@@ -116,7 +121,7 @@ class Profile(bonsai.core.tool.Profile):
@classmethod @classmethod
def get_active_profile_ui(cls) -> Union[bonsai.bim.module.profile.prop.Profile, None]: def get_active_profile_ui(cls) -> Union[bonsai.bim.module.profile.prop.Profile, None]:
props = bpy.context.scene.BIMProfileProperties props = cls.get_profile_props()
index = props.active_profile_index index = props.active_profile_index
if len(props.profiles) > index >= 0: if len(props.profiles) > index >= 0:
return props.profiles[index] return props.profiles[index]
+10 -7
View File
@@ -31,7 +31,7 @@ class TestImplementsTool(NewFile):
class TestClearEditingMode(NewFile): class TestClearEditingMode(NewFile):
def test_run(self): def test_run(self):
props = bpy.context.scene.BIMLibraryProperties props = tool.Library.get_library_props()
props.editing_mode = "LIBRARY" props.editing_mode = "LIBRARY"
subject.clear_editing_mode() subject.clear_editing_mode()
assert props.editing_mode == "NONE" assert props.editing_mode == "NONE"
@@ -78,7 +78,7 @@ class TestImportLibraryAttributes(NewFile):
tool.Ifc.set(ifc := ifcopenshell.file()) tool.Ifc.set(ifc := ifcopenshell.file())
library = ifc.createIfcLibraryInformation("Name", "Version", None, "VersionDate", "Location", "Description") library = ifc.createIfcLibraryInformation("Name", "Version", None, "VersionDate", "Location", "Description")
subject.import_library_attributes(library) subject.import_library_attributes(library)
props = bpy.context.scene.BIMLibraryProperties props = tool.Library.get_library_props()
assert props.library_attributes.get("Name").string_value == "Name" assert props.library_attributes.get("Name").string_value == "Name"
assert props.library_attributes.get("Version").string_value == "Version" assert props.library_attributes.get("Version").string_value == "Version"
assert props.library_attributes.get("VersionDate").string_value == "VersionDate" assert props.library_attributes.get("VersionDate").string_value == "VersionDate"
@@ -91,7 +91,7 @@ class TestImportReferenceAttributes(NewFile):
tool.Ifc.set(ifc := ifcopenshell.file()) tool.Ifc.set(ifc := ifcopenshell.file())
reference = ifc.createIfcLibraryReference("Location", "Identification", "Name", "Description", "Language") reference = ifc.createIfcLibraryReference("Location", "Identification", "Name", "Description", "Language")
subject.import_reference_attributes(reference) subject.import_reference_attributes(reference)
props = bpy.context.scene.BIMLibraryProperties props = tool.Library.get_library_props()
assert props.reference_attributes.get("Location").string_value == "Location" assert props.reference_attributes.get("Location").string_value == "Location"
assert props.reference_attributes.get("Identification").string_value == "Identification" assert props.reference_attributes.get("Identification").string_value == "Identification"
assert props.reference_attributes.get("Name").string_value == "Name" assert props.reference_attributes.get("Name").string_value == "Name"
@@ -105,7 +105,7 @@ class TestImportReferences(NewFile):
library = ifc.createIfcLibraryInformation() library = ifc.createIfcLibraryInformation()
reference = ifc.createIfcLibraryReference(Name="Reference", ReferencedLibrary=library) reference = ifc.createIfcLibraryReference(Name="Reference", ReferencedLibrary=library)
subject.import_references(library) subject.import_references(library)
props = bpy.context.scene.BIMLibraryProperties props = tool.Library.get_library_props()
assert props.references[0].ifc_definition_id == reference.id() assert props.references[0].ifc_definition_id == reference.id()
assert props.references[0].name == "Reference" assert props.references[0].name == "Reference"
@@ -116,7 +116,8 @@ class TestSetActiveLibrary(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
library = ifc.createIfcLibraryInformation() library = ifc.createIfcLibraryInformation()
subject.set_active_library(library) subject.set_active_library(library)
assert bpy.context.scene.BIMLibraryProperties.active_library_id == library.id() props = tool.Library.get_library_props()
assert props.active_library_id == library.id()
class TestSetActiveReference(NewFile): class TestSetActiveReference(NewFile):
@@ -125,10 +126,12 @@ class TestSetActiveReference(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
reference = ifc.createIfcLibraryReference() reference = ifc.createIfcLibraryReference()
subject.set_active_reference(reference) subject.set_active_reference(reference)
assert bpy.context.scene.BIMLibraryProperties.active_reference_id == reference.id() props = tool.Library.get_library_props()
assert props.active_reference_id == reference.id()
class TestSetEditingMode(NewFile): class TestSetEditingMode(NewFile):
def test_run(self): def test_run(self):
subject.set_editing_mode("LIBRARY") subject.set_editing_mode("LIBRARY")
assert bpy.context.scene.BIMLibraryProperties.editing_mode == "LIBRARY" props = tool.Library.get_library_props()
assert props.editing_mode == "LIBRARY"
+18 -14
View File
@@ -35,25 +35,28 @@ class TestImplementsTool(NewFile):
class TestDisableEditingMaterials(NewFile): class TestDisableEditingMaterials(NewFile):
def test_run(self): def test_run(self):
bpy.context.scene.BIMMaterialProperties.is_editing = True props = tool.Material.get_material_props()
props.is_editing = True
subject.disable_editing_materials() subject.disable_editing_materials()
assert bpy.context.scene.BIMMaterialProperties.is_editing is False assert props.is_editing is False
class TestEnableEditingMaterials(NewFile): class TestEnableEditingMaterials(NewFile):
def test_run(self): def test_run(self):
bpy.context.scene.BIMMaterialProperties.is_editing = False props = tool.Material.get_material_props()
props.is_editing = False
subject.enable_editing_materials() subject.enable_editing_materials()
assert bpy.context.scene.BIMMaterialProperties.is_editing is True assert props.is_editing is True
class TestGetActiveMaterialType(NewFile): class TestGetActiveMaterialType(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
bpy.context.scene.BIMMaterialProperties.material_type = "IfcMaterial" props = tool.Material.get_material_props()
props.material_type = "IfcMaterial"
assert subject.get_active_material_type() == "IfcMaterial" assert subject.get_active_material_type() == "IfcMaterial"
bpy.context.scene.BIMMaterialProperties.material_type = "IfcMaterialLayerSet" props.material_type = "IfcMaterialLayerSet"
assert subject.get_active_material_type() == "IfcMaterialLayerSet" assert subject.get_active_material_type() == "IfcMaterialLayerSet"
@@ -73,7 +76,7 @@ class TestImportMaterialDefinitions(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
material = ifc.createIfcMaterial(Name="Name", Category="Category") material = ifc.createIfcMaterial(Name="Name", Category="Category")
subject.import_material_definitions("IfcMaterial") subject.import_material_definitions("IfcMaterial")
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
assert props.materials[0].ifc_definition_id == 0 assert props.materials[0].ifc_definition_id == 0
assert props.materials[0].name == "Category" assert props.materials[0].name == "Category"
assert props.materials[0].is_category is True assert props.materials[0].is_category is True
@@ -85,7 +88,7 @@ class TestImportMaterialDefinitions(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
material = ifc.createIfcMaterial(Name="Name", Category="Category") material = ifc.createIfcMaterial(Name="Name", Category="Category")
subject.import_material_definitions("IfcMaterial") subject.import_material_definitions("IfcMaterial")
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
props.materials[0].is_expanded = True props.materials[0].is_expanded = True
subject.import_material_definitions("IfcMaterial") subject.import_material_definitions("IfcMaterial")
assert len(props.materials) == 2 assert len(props.materials) == 2
@@ -98,7 +101,7 @@ class TestImportMaterialDefinitions(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
material = ifc.createIfcMaterialLayerSet(LayerSetName="Name") material = ifc.createIfcMaterialLayerSet(LayerSetName="Name")
subject.import_material_definitions("IfcMaterialLayerSet") subject.import_material_definitions("IfcMaterialLayerSet")
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
assert props.materials[0].ifc_definition_id == material.id() assert props.materials[0].ifc_definition_id == material.id()
assert props.materials[0].name == "Name" assert props.materials[0].name == "Name"
assert props.materials[0].total_elements == 0 assert props.materials[0].total_elements == 0
@@ -108,7 +111,7 @@ class TestImportMaterialDefinitions(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
material = ifc.createIfcMaterialProfileSet(Name="Name") material = ifc.createIfcMaterialProfileSet(Name="Name")
subject.import_material_definitions("IfcMaterialProfileSet") subject.import_material_definitions("IfcMaterialProfileSet")
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
assert props.materials[0].ifc_definition_id == material.id() assert props.materials[0].ifc_definition_id == material.id()
assert props.materials[0].name == "Name" assert props.materials[0].name == "Name"
assert props.materials[0].total_elements == 0 assert props.materials[0].total_elements == 0
@@ -118,7 +121,7 @@ class TestImportMaterialDefinitions(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
material = ifc.createIfcMaterialConstituentSet(Name="Name") material = ifc.createIfcMaterialConstituentSet(Name="Name")
subject.import_material_definitions("IfcMaterialConstituentSet") subject.import_material_definitions("IfcMaterialConstituentSet")
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
assert props.materials[0].ifc_definition_id == material.id() assert props.materials[0].ifc_definition_id == material.id()
assert props.materials[0].name == "Name" assert props.materials[0].name == "Name"
assert props.materials[0].total_elements == 0 assert props.materials[0].total_elements == 0
@@ -128,7 +131,7 @@ class TestImportMaterialDefinitions(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
material = ifc.createIfcMaterialList() material = ifc.createIfcMaterialList()
subject.import_material_definitions("IfcMaterialList") subject.import_material_definitions("IfcMaterialList")
props = bpy.context.scene.BIMMaterialProperties props = tool.Material.get_material_props()
assert props.materials[0].ifc_definition_id == material.id() assert props.materials[0].ifc_definition_id == material.id()
assert props.materials[0].name == "Unnamed" assert props.materials[0].name == "Unnamed"
assert props.materials[0].total_elements == 0 assert props.materials[0].total_elements == 0
@@ -136,9 +139,10 @@ class TestImportMaterialDefinitions(NewFile):
class TestIsEditingMaterials(NewFile): class TestIsEditingMaterials(NewFile):
def test_run(self): def test_run(self):
bpy.context.scene.BIMMaterialProperties.is_editing = False props = tool.Material.get_material_props()
props.is_editing = False
assert subject.is_editing_materials() is False assert subject.is_editing_materials() is False
bpy.context.scene.BIMMaterialProperties.is_editing = True props.is_editing = True
assert subject.is_editing_materials() is True assert subject.is_editing_materials() is True
@@ -22,13 +22,14 @@ import ifcopenshell.util.element
import ifcopenshell.util.unit import ifcopenshell.util.unit
import ifcopenshell.util.placement import ifcopenshell.util.placement
import numpy as np import numpy as np
from ifcopenshell.util.shape_builder import VectorType, V, ifc_safe_vector_type
def create_axis_curve( def create_axis_curve(
file: ifcopenshell.file, file: ifcopenshell.file,
*, *,
p1: np.ndarray, p1: VectorType,
p2: np.ndarray, p2: VectorType,
grid_axis: ifcopenshell.entity_instance, grid_axis: ifcopenshell.entity_instance,
is_si: bool = True, is_si: bool = True,
) -> None: ) -> None:
@@ -60,7 +61,7 @@ def create_axis_curve(
model, p1=np.array((0., 0., 0.)), p2=np.array((0., 10., 0.)), grid_axis=axis_1) model, p1=np.array((0., 0., 0.)), p2=np.array((0., 10., 0.)), grid_axis=axis_1)
""" """
existing_curve = grid_axis.AxisCurve existing_curve = grid_axis.AxisCurve
p1, p2 = V(p1), V(p2)
if is_si: if is_si:
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
p1 /= unit_scale p1 /= unit_scale
@@ -70,8 +71,8 @@ def create_axis_curve(
grid_matrix_i = np.linalg.inv(ifcopenshell.util.placement.get_local_placement(grid.ObjectPlacement)) grid_matrix_i = np.linalg.inv(ifcopenshell.util.placement.get_local_placement(grid.ObjectPlacement))
grid_axis.AxisCurve = file.createIfcPolyline( grid_axis.AxisCurve = file.createIfcPolyline(
( (
file.createIfcCartesianPoint((grid_matrix_i @ p1).tolist()), file.createIfcCartesianPoint(ifc_safe_vector_type(grid_matrix_i @ p1)),
file.createIfcCartesianPoint((grid_matrix_i @ p2).tolist()), file.createIfcCartesianPoint(ifc_safe_vector_type(grid_matrix_i @ p2)),
) )
) )
@@ -264,7 +264,6 @@ class Usecase:
"IfcProductDefinitionShape": ["HasShapeAspects"], "IfcProductDefinitionShape": ["HasShapeAspects"],
"IfcRepresentationMap": ["HasShapeAspects"], "IfcRepresentationMap": ["HasShapeAspects"],
} }
print('appending type product!')
self.existing_contexts = self.file.by_type("IfcGeometricRepresentationContext") self.existing_contexts = self.file.by_type("IfcGeometricRepresentationContext")
element = self.add_element(self.settings["element"]) element = self.add_element(self.settings["element"])
self.reuse_existing_contexts() self.reuse_existing_contexts()