diff --git a/src/bcf/bcf/agnostic/topic.py b/src/bcf/bcf/agnostic/topic.py new file mode 100644 index 0000000000..166ab9091d --- /dev/null +++ b/src/bcf/bcf/agnostic/topic.py @@ -0,0 +1,5 @@ +import bcf.v2.topic +import bcf.v3.topic +from typing import Union + +TopicHandler = Union[bcf.v2.topic.TopicHandler, bcf.v3.topic.TopicHandler] diff --git a/src/bcf/bcf/agnostic/visinfo.py b/src/bcf/bcf/agnostic/visinfo.py new file mode 100644 index 0000000000..27adf56bdf --- /dev/null +++ b/src/bcf/bcf/agnostic/visinfo.py @@ -0,0 +1,5 @@ +import bcf.v2.visinfo +import bcf.v3.visinfo +from typing import Union + +VisualizationInfoHandler = Union[bcf.v2.visinfo.VisualizationInfoHandler, bcf.v3.visinfo.VisualizationInfoHandler] diff --git a/src/bonsai/bonsai/bim/module/bcf/operator.py b/src/bonsai/bonsai/bim/module/bcf/operator.py index 955eee1f20..a992a09388 100644 --- a/src/bonsai/bonsai/bim/module/bcf/operator.py +++ b/src/bonsai/bonsai/bim/module/bcf/operator.py @@ -27,6 +27,8 @@ import bcf.v2.bcfxml import bcf.v2.model import bcf.v2.topic import bcf.v2.visinfo +import bcf.agnostic.visinfo +import bcf.agnostic.topic import uuid import numpy as np import tempfile @@ -113,7 +115,6 @@ class LoadBcfTopics(bpy.types.Operator): topics2use = [] for topic_guid in bcfxml.topics.keys(): try: - topic_titel = bcfxml.topics[topic_guid].topic.title topics2use.append(topic_guid) except: print("Problems on reading topic, thus ignored: {}".format(topic_guid)) @@ -216,6 +217,11 @@ class LoadBcfComments(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"} + blender_topic = context.scene.BCFProperties.topics.get(self.topic_guid) blender_topic.comments.clear() for comment in bcfxml.topics[self.topic_guid].comments: @@ -243,6 +249,11 @@ class EditBcfProjectName(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"} + bcfxml.project.name = context.scene.BCFProperties.name return {"FINISHED"} @@ -255,6 +266,11 @@ class EditBcfAuthor(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"} + bcfxml.author = context.scene.BCFProperties.author return {"FINISHED"} @@ -269,6 +285,11 @@ class EditBcfTopicName(bpy.types.Operator): blender_topic = props.active_topic 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"} + topic = bcfxml.topics[blender_topic.name].topic topic.title = blender_topic.title return {"FINISHED"} @@ -285,6 +306,10 @@ class EditBcfTopic(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"} + topic = bcfxml.topics[blender_topic.name].topic topic.title = blender_topic.title or None topic.priority = blender_topic.priority or None @@ -330,6 +355,11 @@ class AddBcfTopic(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"} + bcfxml.add_topic("New Topic", "", context.scene.BCFProperties.author) bpy.ops.bim.load_bcf_topics() return {"FINISHED"} @@ -352,6 +382,11 @@ 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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -400,6 +435,11 @@ class AddBcfRelatedTopic(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -425,6 +465,11 @@ class AddBcfHeaderFile(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -479,6 +524,11 @@ class AddBcfViewpoint(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"} + blender_camera = context.scene.camera assert blender_camera props = context.scene.BCFProperties @@ -562,6 +612,11 @@ class RemoveBcfViewpoint(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -586,6 +641,11 @@ class RemoveBcfFile(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -607,6 +667,11 @@ class RemoveBcfTopic(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"} + props = context.scene.BCFProperties del bcfxml.topics[props.active_topic.name] bpy.ops.bim.load_bcf_topics() @@ -625,6 +690,11 @@ class AddBcfReferenceLink(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.") + return {"FINISHED"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -646,6 +716,11 @@ class AddBcfDocumentReference(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -684,12 +759,16 @@ class AddBcfLabel(bpy.types.Operator): def execute(self, context): bcfxml = bcfstore.BcfStore.get_bcfxml() assert bcfxml + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] new = blender_topic.labels.add() new.name = props.label - topic.topic.labels.append(props.label) + + labels = tool.Bcf.get_topic_labels(topic) + labels.append(props.label) + tool.Bcf.set_topic_labels(topic, labels) props.label = "" return {"FINISHED"} @@ -702,6 +781,11 @@ class EditBcfReferenceLinks(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.") + return {"FINISHED"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -720,15 +804,12 @@ class EditBcfLabels(bpy.types.Operator): def execute(self, context): bcfxml = bcfstore.BcfStore.get_bcfxml() assert bcfxml + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] - for index, label in enumerate(blender_topic.labels): - if index >= len(topic.topic.labels): - break - if label.name == topic.topic.labels[index]: - continue - topic.topic.labels[index] = blender_topic.labels[index].name + labels = [l.name for l in blender_topic.labels] + tool.Bcf.set_topic_labels(topic, labels) return {"FINISHED"} @@ -741,6 +822,11 @@ class RemoveBcfReferenceLink(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.") + return {"FINISHED"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -758,10 +844,13 @@ class RemoveBcfLabel(bpy.types.Operator): def execute(self, context): bcfxml = bcfstore.BcfStore.get_bcfxml() assert bcfxml + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] - del topic.topic.labels[self.index] + labels = tool.Bcf.get_topic_labels(topic) + del labels[self.index] + tool.Bcf.set_topic_labels(topic, labels) blender_topic.labels.remove(self.index) return {"FINISHED"} @@ -774,6 +863,11 @@ class RemoveBcfBimSnippet(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -793,6 +887,11 @@ class RemoveBcfDocumentReference(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -810,6 +909,11 @@ class RemoveBcfRelatedTopic(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -827,6 +931,11 @@ class RemoveBcfComment(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -847,6 +956,11 @@ class EditBcfComment(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic blender_comment = blender_topic.comments.get(self.comment_guid) @@ -878,6 +992,11 @@ class AddBcfComment(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"} + props = context.scene.BCFProperties blender_topic = props.active_topic topic = bcfxml.topics[blender_topic.name] @@ -967,7 +1086,7 @@ class ActivateBcfViewpoint(bpy.types.Operator): self.create_clipping_planes(viewpoint) self.delete_bitmaps(context) - if viewpoint.visualization_info.bitmap: + if tool.Bcf.get_viewpoint_bitmaps(viewpoint): self.create_bitmaps(bcfxml, viewpoint, topic) self.setup_camera(viewpoint, obj, cam_aspect, context) @@ -975,7 +1094,7 @@ class ActivateBcfViewpoint(bpy.types.Operator): def setup_camera( self, - viewpoint: bcf.v2.visinfo.VisualizationInfoHandler, + viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler, obj: bpy.types.Object, cam_aspect: float, context: bpy.types.Context, @@ -1026,7 +1145,7 @@ class ActivateBcfViewpoint(bpy.types.Operator): obj.matrix_world = Matrix(matrix.tolist()) def set_viewpoint_components( - self, viewpoint: bcf.v2.visinfo.VisualizationInfoHandler, context: bpy.types.Context + self, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler, context: bpy.types.Context ) -> None: if not viewpoint.visualization_info.components: return @@ -1040,7 +1159,9 @@ class ActivateBcfViewpoint(bpy.types.Operator): self.set_selection(viewpoint) self.set_colours(viewpoint) - def set_exceptions(self, viewpoint: bcf.v2.visinfo.VisualizationInfoHandler, context: bpy.types.Context) -> None: + def set_exceptions( + self, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler, context: bpy.types.Context + ) -> None: visibility_settings = viewpoint.get_elements_visibility() if visibility_settings is None: return @@ -1083,7 +1204,7 @@ class ActivateBcfViewpoint(bpy.types.Operator): obj.hide_select = True def set_view_setup_hints( - self, viewpoint: bcf.v2.visinfo.VisualizationInfoHandler, context: bpy.types.Context + self, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler, context: bpy.types.Context ) -> None: if viewpoint.visualization_info.components.view_setup_hints: if not viewpoint.visualization_info.components.view_setup_hints.spaces_visible: @@ -1107,7 +1228,7 @@ class ActivateBcfViewpoint(bpy.types.Operator): def set_openings_visibility(self, is_visible, context): pass # We no longer have an openings collection - def set_selection(self, viewpoint: bcf.v2.visinfo.VisualizationInfoHandler) -> None: + def set_selection(self, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler) -> None: selected_global_ids = viewpoint.get_selected_guids() if selected_global_ids is None: return @@ -1118,7 +1239,7 @@ class ActivateBcfViewpoint(bpy.types.Operator): obj.select_set(True) obj.hide_set(False) - def set_colours(self, viewpoint: bcf.v2.visinfo.VisualizationInfoHandler) -> None: + def set_colours(self, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler) -> None: if not viewpoint.visualization_info.components or not viewpoint.visualization_info.components.coloring: return global_id_colours = {} @@ -1130,7 +1251,7 @@ class ActivateBcfViewpoint(bpy.types.Operator): if obj: obj.color = self.hex_to_rgb(color) - def draw_lines(self, viewpoint: bcf.v2.visinfo.VisualizationInfoHandler, context: bpy.types.Context) -> None: + def draw_lines(self, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler, context: bpy.types.Context) -> None: gp = bpy.data.grease_pencils.new("BCF") scene = context.scene scene.grease_pencil = gp @@ -1149,7 +1270,7 @@ class ActivateBcfViewpoint(bpy.types.Operator): ) stroke.points.foreach_set("co", coords) - def create_clipping_planes(self, viewpoint: bcf.v2.visinfo.VisualizationInfoHandler) -> None: + def create_clipping_planes(self, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler) -> None: n = 0 for plane in viewpoint.visualization_info.clipping_planes.clipping_plane: bpy.ops.bim.add_section_plane() @@ -1181,15 +1302,16 @@ class ActivateBcfViewpoint(bpy.types.Operator): bpy.data.objects.remove(bitmap) def create_bitmaps( - self, bcfxml, viewpoint: bcf.v2.visinfo.VisualizationInfoHandler, topic: bcf.v2.topic.TopicHandler + self, bcfxml, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler, topic: bcf.agnostic.topic.TopicHandler ) -> None: collection = bpy.data.collections.get("Bitmaps") if not collection: collection = bpy.data.collections.new("Bitmaps") - for bitmap in viewpoint.visualization_info.bitmap: + for bitmap in tool.Bcf.get_viewpoint_bitmaps(viewpoint): obj = bpy.data.objects.new("Bitmap", None) obj.empty_display_type = "IMAGE" # image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, bitmap.reference)) + # TODO: suuport bcf v3. with tempfile.NamedTemporaryFile(delete=False) as f: topic.extract_file(bitmap, f.name) # f.write(bitmap.what) @@ -1295,8 +1417,12 @@ class LoadBcfHeaderIfcFile(bpy.types.Operator): def execute(self, context): bcfxml = bcfstore.BcfStore.get_bcfxml() assert bcfxml - bcf_path = tool.Bcf.get_path() + 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_path = tool.Bcf.get_path() topic = bcfxml.topics[context.scene.BCFProperties.active_topic.name] entity = topic.header.file[self.index] ifc_path = str(topic.extract_file(entity)) @@ -1316,6 +1442,11 @@ class ExtractBcfFile(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"} + topic = bcfxml.topics[context.scene.BCFProperties.active_topic.name] if self.entity_type == "HEADER_FILE": diff --git a/src/bonsai/bonsai/bim/module/bcf/ui.py b/src/bonsai/bonsai/bim/module/bcf/ui.py index e7c76e849a..92e259e443 100644 --- a/src/bonsai/bonsai/bim/module/bcf/ui.py +++ b/src/bonsai/bonsai/bim/module/bcf/ui.py @@ -18,6 +18,7 @@ import os import bpy +import bonsai.tool as tool from . import bcfstore from bpy.types import Panel @@ -122,18 +123,18 @@ class BIM_PT_bcf_metadata(Panel): scene = context.scene props = scene.BCFProperties - if props.active_topic_index >= len(props.topics): + bcfxml = bcfstore.BcfStore.get_bcfxml() + if not bcfxml or props.active_topic_index >= len(props.topics): layout.label(text="No BCF project is loaded") return topic = props.active_topic - bcfxml = bcfstore.BcfStore.get_bcfxml() bcf_topic = bcfxml.topics[topic.name] layout.label(text="Header Files:") if bcf_topic.header: - for index, f in enumerate(bcf_topic.header.file): + for index, f in enumerate(tool.Bcf.get_topic_header_files(bcf_topic)): box = self.layout.box() row = box.row(align=True) row.label(text=f.filename, icon="FILE_BLANK") diff --git a/src/bonsai/bonsai/tool/bcf.py b/src/bonsai/bonsai/tool/bcf.py index e8f1163b68..6bf727bcf7 100644 --- a/src/bonsai/bonsai/tool/bcf.py +++ b/src/bonsai/bonsai/tool/bcf.py @@ -16,6 +16,8 @@ # 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 import bpy @@ -23,6 +25,7 @@ import bcf.v2.model import bcf.v2.topic import bcf.v3.model import bcf.v3.topic +import bcf.agnostic.topic from typing import Any, Union, Optional @@ -31,9 +34,11 @@ class Bcf(bonsai.core.tool.Bcf): def get_path(cls) -> str: return bpy.context.scene.BCFProperties.bcf_file + # BCF version agnostic API. + ## topic @classmethod def get_topic_document_references( - cls, topic: Union[bcf.v2.topic.TopicHandler, bcf.v3.topic.TopicHandler] + cls, topic: bcf.agnostic.topic.TopicHandler ) -> Union[list[bcf.v2.model.TopicDocumentReference], list[bcf.v3.model.DocumentReference]]: if isinstance(topic, bcf.v2.topic.TopicHandler): document_references = topic.topic.document_reference @@ -43,7 +48,21 @@ class Bcf(bonsai.core.tool.Bcf): return document_references @classmethod - def get_topic_labels(cls, topic: Union[bcf.v2.topic.TopicHandler, bcf.v3.topic.TopicHandler]) -> list[str]: + def get_topic_header_files( + cls, topic: bcf.agnostic.topic.TopicHandler + ) -> Union[list[bcf.v2.model.HeaderFile], list[bcf.v3.model.File]]: + header = topic.header + if not header: + return [] + if isinstance(header, bcf.v2.model.Header): + header_files = header.file + else: + header_files = header.files + header_files = header_files.file if header_files else [] + return header_files + + @classmethod + def get_topic_labels(cls, topic: bcf.agnostic.topic.TopicHandler) -> list[str]: if isinstance(topic, bcf.v2.topic.TopicHandler): labels = topic.topic.labels else: @@ -52,7 +71,21 @@ class Bcf(bonsai.core.tool.Bcf): return labels @classmethod - def get_topic_reference_links(cls, topic: Union[bcf.v2.topic.TopicHandler, bcf.v3.topic.TopicHandler]) -> list[str]: + def set_topic_labels(cls, topic: bcf.agnostic.topic.TopicHandler, labels: list[str]) -> None: + topic_ = topic.topic + if isinstance(topic_, bcf.v2.model.Topic): + topic_.labels = labels + else: + topic_labels = topic_.labels + if topic_labels is None: + if not labels: + return + topic_.labels = (topic_labels := bcf.v3.model.TopicLabels()) + return + topic_labels.label = labels + + @classmethod + def get_topic_reference_links(cls, topic: bcf.agnostic.topic.TopicHandler) -> list[str]: if isinstance(topic, bcf.v2.topic.TopicHandler): reference_links = topic.topic.reference_link else: @@ -62,7 +95,7 @@ class Bcf(bonsai.core.tool.Bcf): @classmethod def get_topic_related_topics( - cls, topic: Union[bcf.v2.topic.TopicHandler, bcf.v3.topic.TopicHandler] + cls, topic: bcf.agnostic.topic.TopicHandler ) -> Union[list[bcf.v2.model.TopicRelatedTopic], list[bcf.v3.model.TopicRelatedTopicsRelatedTopic]]: if isinstance(topic, bcf.v2.topic.TopicHandler): related_topics = topic.topic.related_topic @@ -70,3 +103,15 @@ class Bcf(bonsai.core.tool.Bcf): related_topics = topic.topic.related_topics related_topics = related_topics.related_topic if related_topics else [] return related_topics + + ## visinfo + @classmethod + def get_viewpoint_bitmaps( + cls, viewpoint: bcf.agnostic.visinfo.VisualizationInfoHandler + ) -> Union[list[bcf.v2.model.VisualizationInfoBitmap], list[bcf.v3.model.Bitmap]]: + if isinstance(viewpoint, bcf.v2.visinfo.VisualizationInfoHandler): + bitmaps = viewpoint.visualization_info.bitmap + else: + bitmaps = viewpoint.visualization_info.bitmaps + bitmaps = bitmaps.bitmap if bitmaps else [] + return bitmaps