From 7951acf07073b05bdc881beb639d686b30eff25f Mon Sep 17 00:00:00 2001 From: Tamas Nepusz Date: Tue, 3 Oct 2023 01:03:42 +0200 Subject: [PATCH] feat: more file formats, updated changelog --- CHANGELOG.md | 7 ++ src/addons/ui_skybrush_studio.py | 2 + .../sbstudio/plugin/operators/__init__.py | 2 + .../plugin/operators/export_to_drotek.py | 93 +++++++++++++++++++ .../sbstudio/plugin/operators/utils.py | 5 + src/modules/sbstudio/plugin/panels/export.py | 5 + 6 files changed, 114 insertions(+) create mode 100644 src/modules/sbstudio/plugin/operators/export_to_drotek.py diff --git a/CHANGELOG.md b/CHANGELOG.md index f082ab21..f17bbd06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 during a staggered transition manually, or to manually create more complex transition patterns. +- The Export panel now has a button that can be used to query the server about + any additional supported file formats besides .skyc and CSV. Additional + export operators will appear for third-party file formats if the server + supports them. Note that the community server still supports .skyc and CSV only. + Contact us for local deployments of the server with support for third-party + file formats if you are interested. + ### Fixed - View scaling setting from the Blender preferences is now taken into account diff --git a/src/addons/ui_skybrush_studio.py b/src/addons/ui_skybrush_studio.py index 6f777247..74d2ce7a 100644 --- a/src/addons/ui_skybrush_studio.py +++ b/src/addons/ui_skybrush_studio.py @@ -73,6 +73,7 @@ DACExportOperator, DeselectFormationOperator, DetachMaterialsFromDroneTemplateOperator, + DrotekExportOperator, DuplicateLightEffectOperator, FixConstraintOrderingOperator, AddMarkersFromQRCodeOperator, @@ -195,6 +196,7 @@ SkybrushCSVExportOperator, SkybrushPDFExportOperator, DACExportOperator, + DrotekExportOperator, UseSelectedVertexGroupForFormationOperator, GetFormationStatisticsOperator, TakeoffOperator, diff --git a/src/modules/sbstudio/plugin/operators/__init__.py b/src/modules/sbstudio/plugin/operators/__init__.py index a4da9c69..2d44233b 100644 --- a/src/modules/sbstudio/plugin/operators/__init__.py +++ b/src/modules/sbstudio/plugin/operators/__init__.py @@ -14,6 +14,7 @@ from .duplicate_light_effect import DuplicateLightEffectOperator from .export_to_csv import SkybrushCSVExportOperator from .export_to_dac import DACExportOperator +from .export_to_drotek import DrotekExportOperator from .export_to_skyc import SkybrushExportOperator from .export_to_pdf import SkybrushPDFExportOperator from .fix_constraint_ordering import FixConstraintOrderingOperator @@ -58,6 +59,7 @@ "DACExportOperator", "DeselectFormationOperator", "DetachMaterialsFromDroneTemplateOperator", + "DrotekExportOperator", "DuplicateLightEffectOperator", "FixConstraintOrderingOperator", "AddMarkersFromQRCodeOperator", diff --git a/src/modules/sbstudio/plugin/operators/export_to_drotek.py b/src/modules/sbstudio/plugin/operators/export_to_drotek.py new file mode 100644 index 00000000..4680741b --- /dev/null +++ b/src/modules/sbstudio/plugin/operators/export_to_drotek.py @@ -0,0 +1,93 @@ +import bpy +import os + +from bpy.props import BoolProperty, StringProperty, FloatProperty +from bpy.types import Operator +from bpy_extras.io_utils import ExportHelper + +from sbstudio.model.file_formats import FileFormat +from sbstudio.plugin.api import call_api_from_blender_operator +from sbstudio.plugin.props.frame_range import FrameRangeProperty + +from .utils import export_show_to_file_using_api + +__all__ = ("DrotekExportOperator",) + + +############################################################################# +# Operator that allows the user to invoke the Drotek export operation +############################################################################# + + +class DrotekExportOperator(Operator, ExportHelper): + """Export object trajectories and light animation into Drotek's JSON-based format""" + + bl_idname = "export_scene.drotek" + bl_label = "Export Drotek format" + bl_options = {"REGISTER"} + + # List of file extensions that correspond to Drotek files + filter_glob = StringProperty(default="*.json", options={"HIDDEN"}) + filename_ext = ".json" + + # output all objects or only selected ones + export_selected = BoolProperty( + name="Export selected drones only", + default=False, + description=( + "Export only the selected drones. " + "Uncheck to export all drones, irrespectively of the selection." + ), + ) + + # whether to convert RGB colors to RGBW during export + use_rgbw = BoolProperty( + name="Use RGBW colors", + default=True, + description="Whether to convert colors to RGBW automatically during export", + ) + + # spacing between drones in the takeoff grid + spacing = FloatProperty( + name="Takeoff grid spacing", + default=2, + description="Distance between slots in the takeoff grid.", + ) + + # frame range + frame_range = FrameRangeProperty(default="RENDER") + + def execute(self, context): + filepath = bpy.path.ensure_ext(self.filepath, self.filename_ext) + settings = { + "export_selected": self.export_selected, + "frame_range": self.frame_range, + "spacing": self.spacing, + "output_fps": 5, + "light_fps": 5, + "use_rgbw": self.use_rgbw, + } + + try: + with call_api_from_blender_operator(self, "Drotek exporter") as api: + export_show_to_file_using_api( + api, + context, + settings, + filepath, + FileFormat.DROTEK, + ) + except Exception: + return {"CANCELLED"} + + self.report({"INFO"}, "Export successful") + return {"FINISHED"} + + def invoke(self, context, event): + if not self.filepath: + filepath = bpy.data.filepath or "Untitled" + filepath, _ = os.path.splitext(filepath) + self.filepath = f"{filepath}.zip" + + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} diff --git a/src/modules/sbstudio/plugin/operators/utils.py b/src/modules/sbstudio/plugin/operators/utils.py index a67c01ee..a3d86a33 100644 --- a/src/modules/sbstudio/plugin/operators/utils.py +++ b/src/modules/sbstudio/plugin/operators/utils.py @@ -263,6 +263,11 @@ def export_show_to_file_using_api( elif format is FileFormat.DROTEK: log.info("Exporting show to Drotek format") renderer = "drotek" + renderer_params = { + **renderer_params, + "fps": settings["output_fps"], + # TODO(ntamas): takeoff_angle? + } elif format is FileFormat.DSS: log.info("Exporting show to DSS PATH format") renderer = "dss" diff --git a/src/modules/sbstudio/plugin/panels/export.py b/src/modules/sbstudio/plugin/panels/export.py index 64719fe0..016ed0d0 100644 --- a/src/modules/sbstudio/plugin/panels/export.py +++ b/src/modules/sbstudio/plugin/panels/export.py @@ -3,6 +3,7 @@ from sbstudio.model.file_formats import FileFormat, get_supported_file_formats from sbstudio.plugin.operators import ( DACExportOperator, + DrotekExportOperator, RefreshFileFormatsOperator, SkybrushExportOperator, SkybrushCSVExportOperator, @@ -48,6 +49,10 @@ def draw(self, context): ) elif format is FileFormat.DAC: layout.operator(DACExportOperator.bl_idname, text="Export to .dac") + elif format is FileFormat.DROTEK: + layout.operator( + DrotekExportOperator.bl_idname, text="Export to Drotek format" + ) elif format is FileFormat.PDF: layout.operator( SkybrushPDFExportOperator.bl_idname, text="Export validation report"