diff --git a/src/addons/ui_skybrush_studio.py b/src/addons/ui_skybrush_studio.py index 6515ea04..6f777247 100644 --- a/src/addons/ui_skybrush_studio.py +++ b/src/addons/ui_skybrush_studio.py @@ -70,6 +70,7 @@ CreateNewStoryboardEntryOperator, CreateLightEffectOperator, CreateTakeoffGridOperator, + DACExportOperator, DeselectFormationOperator, DetachMaterialsFromDroneTemplateOperator, DuplicateLightEffectOperator, @@ -193,6 +194,7 @@ SkybrushExportOperator, SkybrushCSVExportOperator, SkybrushPDFExportOperator, + DACExportOperator, UseSelectedVertexGroupForFormationOperator, GetFormationStatisticsOperator, TakeoffOperator, diff --git a/src/modules/sbstudio/plugin/operators/__init__.py b/src/modules/sbstudio/plugin/operators/__init__.py index 44fbfc99..a4da9c69 100644 --- a/src/modules/sbstudio/plugin/operators/__init__.py +++ b/src/modules/sbstudio/plugin/operators/__init__.py @@ -13,6 +13,7 @@ from .detach_materials_from_template import DetachMaterialsFromDroneTemplateOperator from .duplicate_light_effect import DuplicateLightEffectOperator from .export_to_csv import SkybrushCSVExportOperator +from .export_to_dac import DACExportOperator from .export_to_skyc import SkybrushExportOperator from .export_to_pdf import SkybrushPDFExportOperator from .fix_constraint_ordering import FixConstraintOrderingOperator @@ -54,6 +55,7 @@ "CreateNewScheduleOverrideEntryOperator", "CreateNewStoryboardEntryOperator", "CreateTakeoffGridOperator", + "DACExportOperator", "DeselectFormationOperator", "DetachMaterialsFromDroneTemplateOperator", "DuplicateLightEffectOperator", diff --git a/src/modules/sbstudio/plugin/operators/export_to_dac.py b/src/modules/sbstudio/plugin/operators/export_to_dac.py new file mode 100644 index 00000000..12672b6b --- /dev/null +++ b/src/modules/sbstudio/plugin/operators/export_to_dac.py @@ -0,0 +1,73 @@ +import bpy +import os + +from bpy.props import BoolProperty, StringProperty +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__ = ("DACExportOperator",) + + +############################################################################# +# Operator that allows the user to invoke the .dac export operation +############################################################################# + + +class DACExportOperator(Operator, ExportHelper): + """Export object trajectories and light animation into .dac format.""" + + bl_idname = "export_scene.dac" + bl_label = "Export DAC" + bl_options = {"REGISTER"} + + # List of file extensions that correspond to .dac files + filter_glob = StringProperty(default="*.zip", options={"HIDDEN"}) + filename_ext = ".zip" + + # 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." + ), + ) + + # 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, + "output_fps": 30, + "light_output_fps": 30, + } + + try: + with call_api_from_blender_operator(self, ".dac exporter") as api: + export_show_to_file_using_api( + api, context, settings, filepath, FileFormat.DAC + ) + 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 a4a4384d..a67c01ee 100644 --- a/src/modules/sbstudio/plugin/operators/utils.py +++ b/src/modules/sbstudio/plugin/operators/utils.py @@ -252,6 +252,20 @@ def export_show_to_file_using_api( log.info("Exporting show to CSV") renderer = "csv" renderer_params = {**renderer_params, "fps": settings["output_fps"]} + elif format is FileFormat.DAC: + log.info("Exporting show to .dac format") + renderer = "dac" + renderer_params = { + **renderer_params, + "show_id": 1555, + "title": "Skybrush show", + } + elif format is FileFormat.DROTEK: + log.info("Exporting show to Drotek format") + renderer = "drotek" + elif format is FileFormat.DSS: + log.info("Exporting show to DSS PATH format") + renderer = "dss" else: raise RuntimeError(f"Unhandled format: {format!r}") diff --git a/src/modules/sbstudio/plugin/panels/export.py b/src/modules/sbstudio/plugin/panels/export.py index 87d836a0..64719fe0 100644 --- a/src/modules/sbstudio/plugin/panels/export.py +++ b/src/modules/sbstudio/plugin/panels/export.py @@ -2,6 +2,7 @@ from sbstudio.model.file_formats import FileFormat, get_supported_file_formats from sbstudio.plugin.operators import ( + DACExportOperator, RefreshFileFormatsOperator, SkybrushExportOperator, SkybrushCSVExportOperator, @@ -45,6 +46,8 @@ def draw(self, context): layout.operator( SkybrushCSVExportOperator.bl_idname, text="Export to .csv" ) + elif format is FileFormat.DAC: + layout.operator(DACExportOperator.bl_idname, text="Export to .dac") elif format is FileFormat.PDF: layout.operator( SkybrushPDFExportOperator.bl_idname, text="Export validation report"