Skip to content

Commit

Permalink
feat: added DSS PATH export if the server supports it
Browse files Browse the repository at this point in the history
  • Loading branch information
ntamas committed Oct 5, 2023
1 parent 7951acf commit bed5048
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/addons/ui_skybrush_studio.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
DeselectFormationOperator,
DetachMaterialsFromDroneTemplateOperator,
DrotekExportOperator,
DSSPathExportOperator,
DuplicateLightEffectOperator,
FixConstraintOrderingOperator,
AddMarkersFromQRCodeOperator,
Expand Down Expand Up @@ -197,6 +198,7 @@
SkybrushPDFExportOperator,
DACExportOperator,
DrotekExportOperator,
DSSPathExportOperator,
UseSelectedVertexGroupForFormationOperator,
GetFormationStatisticsOperator,
TakeoffOperator,
Expand Down
2 changes: 2 additions & 0 deletions src/modules/sbstudio/plugin/operators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_dss import DSSPathExportOperator
from .export_to_drotek import DrotekExportOperator
from .export_to_skyc import SkybrushExportOperator
from .export_to_pdf import SkybrushPDFExportOperator
Expand Down Expand Up @@ -60,6 +61,7 @@
"DeselectFormationOperator",
"DetachMaterialsFromDroneTemplateOperator",
"DrotekExportOperator",
"DSSPathExportOperator",
"DuplicateLightEffectOperator",
"FixConstraintOrderingOperator",
"AddMarkersFromQRCodeOperator",
Expand Down
82 changes: 82 additions & 0 deletions src/modules/sbstudio/plugin/operators/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import bpy
import os

from typing import Any, Dict

from bpy.props import BoolProperty
from bpy.types import Collection, Operator
from bpy_extras.io_utils import ExportHelper

from sbstudio.model.file_formats import FileFormat
from sbstudio.plugin.errors import StoryboardValidationError
from sbstudio.plugin.props.frame_range import FrameRangeProperty
from sbstudio.plugin.selection import select_only


Expand Down Expand Up @@ -92,3 +101,76 @@ def poll(cls, context):
def execute(self, context):
entry = context.scene.skybrush.storyboard.active_entry
return self.execute_on_storyboard_entry(entry, context)


class ExportOperator(Operator, ExportHelper):
"""Operator mixin for operators that export the scene in some format using
the Skybrush Studio API.
"""

# whether to 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):
from sbstudio.plugin.api import call_api_from_blender_operator
from .utils import export_show_to_file_using_api

filepath = bpy.path.ensure_ext(self.filepath, self.filename_ext)

if os.path.basename(filepath).lower() == self.filename_ext.lower():
self.report({"ERROR_INVALID_INPUT"}, "Filename must not be empty")
return {"CANCELLED"}

settings = {
"export_selected": self.export_selected,
"frame_range": self.frame_range,
**self.get_settings(),
}

try:
with call_api_from_blender_operator(self, self.get_operator_name()) as api:
export_show_to_file_using_api(
api, context, settings, filepath, self.get_format()
)
except Exception:
return {"CANCELLED"}

self.report({"INFO"}, "Export successful")
return {"FINISHED"}

def get_format(self) -> FileFormat:
"""Returns the file format that the operator uses. Must be overridden
in subclasses.
"""
raise NotImplementedError

def get_operator_name(self) -> str:
"""Returns the name of the operator to be used in error messages when
the operation fails.
"""
return "exporter"

def get_settings(self) -> Dict[str, Any]:
"""Returns operator-specific renderer settings that should be passed to
the Skybrush Studio API.
"""
return {}

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"}
35 changes: 35 additions & 0 deletions src/modules/sbstudio/plugin/operators/export_to_dss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from typing import Any, Dict

from bpy.props import StringProperty

from sbstudio.model.file_formats import FileFormat

from .base import ExportOperator

__all__ = ("DSSPathExportOperator",)


#############################################################################
# Operator that allows the user to invoke the .dac export operation
#############################################################################


class DSSPathExportOperator(ExportOperator):
"""Export object trajectories and light animation into DSS PATH format."""

bl_idname = "export_scene.dss_path"
bl_label = "Export DSS"
bl_options = {"REGISTER"}

# List of file extensions that correspond to DSS PATH files
filter_glob = StringProperty(default="*.zip", options={"HIDDEN"})
filename_ext = ".zip"

def get_format(self) -> FileFormat:
return FileFormat.DSS

def get_operator_name(self) -> str:
return "DSS PATH exporter"

def get_settings(self) -> Dict[str, Any]:
return {}
5 changes: 5 additions & 0 deletions src/modules/sbstudio/plugin/panels/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from sbstudio.plugin.operators import (
DACExportOperator,
DrotekExportOperator,
DSSPathExportOperator,
RefreshFileFormatsOperator,
SkybrushExportOperator,
SkybrushCSVExportOperator,
Expand Down Expand Up @@ -53,6 +54,10 @@ def draw(self, context):
layout.operator(
DrotekExportOperator.bl_idname, text="Export to Drotek format"
)
elif format is FileFormat.DSS:
layout.operator(
DSSPathExportOperator.bl_idname, text="Export to DSS PATH format"
)
elif format is FileFormat.PDF:
layout.operator(
SkybrushPDFExportOperator.bl_idname, text="Export validation report"
Expand Down
28 changes: 21 additions & 7 deletions src/modules/sbstudio/plugin/plugin_helpers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Helper functions that can be used in most of our Blender addons."""

from contextlib import contextmanager
from typing import ContextManager
from typing import ContextManager, Set, Type

import bpy
import re
Expand All @@ -15,6 +15,9 @@ def _get_menu_by_name(menu):
return getattr(bpy.types, "INFO_MT_" + menu)


_already_processed_with_make_annotations: Set[Type] = set()


def _make_annotations(cls):
"""Converts class fields to annotations.
Expand All @@ -28,13 +31,24 @@ class is registered as an operator.
# tuples so we look for that. Blender 2.93 changed this to
# bpy.props._PropertyDeferred
try:
from bpy.props import _PropertyDeferred
from bpy.props import _PropertyDeferred as PropertyType
except ImportError:
_PropertyDeferred = tuple

bl_props = {
k: v for k, v in cls.__dict__.items() if isinstance(v, _PropertyDeferred)
}
PropertyType = tuple

classes = list(reversed(cls.__mro__))
bl_props = {}
while classes:
current_class = classes.pop()
if (
current_class != cls
and current_class not in _already_processed_with_make_annotations
):
_make_annotations(current_class)

_already_processed_with_make_annotations.add(current_class)
bl_props.update(
{k: v for k, v in cls.__dict__.items() if isinstance(v, PropertyType)}
)

if bl_props:
if "__annotations__" not in cls.__dict__:
Expand Down

0 comments on commit bed5048

Please sign in to comment.