diff --git a/src/bcf/bcf/agnostic/model.py b/src/bcf/bcf/agnostic/model.py new file mode 100644 index 0000000000..726a2e483a --- /dev/null +++ b/src/bcf/bcf/agnostic/model.py @@ -0,0 +1,5 @@ +import bcf.v2.model +import bcf.v3.model +from typing import Union + +BimSnippet = Union[bcf.v2.model.BimSnippet, bcf.v3.model.BimSnippet] diff --git a/src/bonsai/bonsai/bim/module/bcf/operator.py b/src/bonsai/bonsai/bim/module/bcf/operator.py index 117f842a39..3ada5bb89e 100644 --- a/src/bonsai/bonsai/bim/module/bcf/operator.py +++ b/src/bonsai/bonsai/bim/module/bcf/operator.py @@ -387,24 +387,26 @@ class AddBcfBimSnippet(bpy.types.Operator): def execute(self, context): bcfxml = bcfstore.BcfStore.get_bcfxml() assert bcfxml - - if not (version := (bcfxml.version.version_id or "")).startswith("2"): - self.report({"INFO"}, f"BCF {version} is not yet supported: {self.bl_rna.bl_idname}.") - return {"FINISHED"} + bcf_v2 = (bcfxml.version.version_id or "").startswith("2") props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] is_external = "://" in props.bim_snippet_reference - bim_snippet = bcf.v2.model.BimSnippet( + bim_snippet_class = bcf.v2.model.BimSnippet if bcf_v2 else bcf.v3.model.BimSnippet + bim_snippet = bim_snippet_class( reference=props.bim_snippet_reference if is_external else Path(props.bim_snippet_reference).name, reference_schema=props.bim_snippet_schema, snippet_type=props.bim_snippet_type, is_external=is_external, ) - topic.topic.bim_snippet = bim_snippet - with open(props.bim_snippet_reference, "r") as f: - topic.bim_snippet = f.read() + + bim_snippet_bytes = None + if not is_external: + with open(props.bim_snippet_reference, "rb") as f: + bim_snippet_bytes = f.read() + tool.Bcf.set_topic_bim_snippet(topic, bim_snippet, bim_snippet_bytes) + bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index) return {"FINISHED"} @@ -899,14 +901,10 @@ class RemoveBcfBimSnippet(bpy.types.Operator): bcfxml = bcfstore.BcfStore.get_bcfxml() assert bcfxml - if not (version := (bcfxml.version.version_id or "")).startswith("2"): - self.report({"INFO"}, f"BCF {version} is not yet supported: {self.bl_rna.bl_idname}.") - return {"FINISHED"} - props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] - topic.topic.bim_snippet = None + tool.Bcf.set_topic_bim_snippet(topic, None) blender_topic.bim_snippet.schema = "" blender_topic.bim_snippet.reference = "" blender_topic.bim_snippet.type = "" diff --git a/src/bonsai/bonsai/tool/bcf.py b/src/bonsai/bonsai/tool/bcf.py index 2b89aec287..7753be96f0 100644 --- a/src/bonsai/bonsai/tool/bcf.py +++ b/src/bonsai/bonsai/tool/bcf.py @@ -16,7 +16,6 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . -import bcf.agnostic.visinfo import bcf.v2.visinfo import bonsai.core.tool import bonsai.tool as tool @@ -25,8 +24,10 @@ import bcf.v2.model import bcf.v2.topic import bcf.v3.model import bcf.v3.topic +import bcf.agnostic.model import bcf.agnostic.topic -from typing import Any, Union, TypeVar, TypeGuard +import bcf.agnostic.visinfo +from typing import Any, Union, TypeVar, TypeGuard, Optional T = TypeVar("T") @@ -46,6 +47,26 @@ class Bcf(bonsai.core.tool.Bcf): # BCF version agnostic API. ## topic + @classmethod + def set_topic_bim_snippet( + cls, + topic: bcf.agnostic.topic.TopicHandler, + bim_snippet: Union[bcf.agnostic.model.BimSnippet, None], + bim_snippet_bytes: Optional[bytes] = None, + ) -> None: + if isinstance(bim_snippet, bcf.v2.model.BimSnippet): + assert isinstance(topic, bcf.v2.topic.TopicHandler) + topic.topic.bim_snippet = bim_snippet + elif isinstance(bim_snippet, bcf.v3.model.BimSnippet): + assert isinstance(topic, bcf.v3.topic.TopicHandler) + topic.topic.bim_snippet = bim_snippet + else: + topic.topic.bim_snippet = bim_snippet + + if bim_snippet and not bim_snippet.is_external and bim_snippet_bytes is None: + raise Exception("No bytes data provided for non-external bim snippet.") + topic._bim_snippet = bim_snippet_bytes + @classmethod def get_topic_document_references( cls, topic: bcf.agnostic.topic.TopicHandler