diff --git a/src/modules/sbstudio/plugin/api.py b/src/modules/sbstudio/plugin/api.py index 13e10d8d..975207e2 100644 --- a/src/modules/sbstudio/plugin/api.py +++ b/src/modules/sbstudio/plugin/api.py @@ -47,19 +47,14 @@ def _get_api_from_url_and_key(url: str, key: str): def get_api() -> SkybrushStudioAPI: """Returns the singleton instance of the Skybrush Studio API object.""" - from sbstudio.plugin.model.global_settings import DroneShowAddonGlobalSettings + from sbstudio.plugin.model.global_settings import get_preferences api_key: str server_url: str - prefs = bpy.context.preferences - try: - prefs = prefs.addons[DroneShowAddonGlobalSettings.bl_idname].preferences - api_key = str(getattr(prefs, "api_key", "")).strip() - server_url = str(getattr(prefs, "server_url", "")).strip() - except KeyError: - api_key = "" - server_url = "" + prefs = get_preferences() + api_key = str(prefs.api_key).strip() + server_url = str(prefs.server_url).strip() return _get_api_from_url_and_key(server_url, api_key) diff --git a/src/modules/sbstudio/plugin/model/global_settings.py b/src/modules/sbstudio/plugin/model/global_settings.py index a8c31064..e1ba6e41 100644 --- a/src/modules/sbstudio/plugin/model/global_settings.py +++ b/src/modules/sbstudio/plugin/model/global_settings.py @@ -1,7 +1,9 @@ -from bpy.props import StringProperty -from bpy.types import AddonPreferences +from bpy.props import BoolProperty, StringProperty +from bpy.types import AddonPreferences, Context +from typing import Optional from sbstudio.plugin.operators.set_server_url import SetServerURLOperator +from sbstudio.plugin.utils import with_context __all__ = ("DroneShowAddonGlobalSettings",) @@ -29,6 +31,16 @@ class DroneShowAddonGlobalSettings(AddonPreferences): ), ) + enable_experimental_features = BoolProperty( + name="Enable experimental features", + description=( + "Whether to enable experimental features in the add-on. Experimental " + "features are currently in a testing phase and may be changed, " + "disabled or removed in future versions without notice" + ), + default=False, + ) + def draw(self, context): layout = self.layout @@ -41,3 +53,15 @@ def draw(self, context): op = row.operator(SetServerURLOperator.bl_idname, text="Use community server") op.url = "" + + layout.prop(self, "enable_experimental_features") + + +@with_context +def get_preferences(context: Optional[Context] = None) -> DroneShowAddonGlobalSettings: + """Helper function to retrieve the preferences of the add-on from the + given context object. + """ + assert context is not None + prefs = context.preferences + return prefs.addons[DroneShowAddonGlobalSettings.bl_idname].preferences diff --git a/src/modules/sbstudio/plugin/operators/return_to_home.py b/src/modules/sbstudio/plugin/operators/return_to_home.py index 56d5f986..2a252e7d 100644 --- a/src/modules/sbstudio/plugin/operators/return_to_home.py +++ b/src/modules/sbstudio/plugin/operators/return_to_home.py @@ -12,7 +12,6 @@ find_f_curve_for_data_path_and_index, ) from sbstudio.plugin.model.formation import create_formation, get_markers_from_formation - from sbstudio.plugin.model.safety_check import get_proximity_warning_threshold from sbstudio.plugin.utils.evaluator import create_position_evaluator @@ -22,6 +21,12 @@ __all__ = ("ReturnToHomeOperator",) +def is_smart_rth_enabled_globally() -> bool: + from sbstudio.plugin.model.global_settings import get_preferences + + return bool(get_preferences().enable_experimental_features) + + class ReturnToHomeOperator(StoryboardOperator): """Blender operator that adds a return-to-home transition to the show.""" @@ -100,8 +105,10 @@ def draw(self, context): layout = self.layout layout.use_property_split = True + use_smart_rth = self._should_use_smart_rth() + layout.prop(self, "start_frame") - if self.use_smart_rth: + if use_smart_rth: # TODO: labels XY and Z consume too much space... row = layout.row() row.prop(self, "velocity") @@ -114,9 +121,11 @@ def draw(self, context): else: layout.prop(self, "velocity") layout.prop(self, "altitude") - if not self.use_smart_rth: + if not use_smart_rth: layout.prop(self, "altitude_shift") - layout.prop(self, "use_smart_rth") + + if is_smart_rth_enabled_globally(): + layout.prop(self, "use_smart_rth") def invoke(self, context, event): storyboard = context.scene.skybrush.storyboard @@ -126,6 +135,9 @@ def invoke(self, context, event): def execute_on_storyboard(self, storyboard, entries, context): return {"FINISHED"} if self._run(storyboard, context=context) else {"CANCELLED"} + def _should_use_smart_rth(self) -> bool: + return self.use_smart_rth and is_smart_rth_enabled_globally() + def _run(self, storyboard, *, context) -> bool: bpy.ops.skybrush.prepare() @@ -139,17 +151,18 @@ def _run(self, storyboard, *, context) -> bool: with create_position_evaluator() as get_positions_of: source = get_positions_of(drones, frame=self.start_frame) + use_smart_rth = self._should_use_smart_rth() first_frame = storyboard.frame_start _, target, _ = create_helper_formation_for_takeoff_and_landing( drones, frame=first_frame, base_altitude=self.altitude, - layer_height=self.altitude_shift if self.use_smart_rth is False else 0, + layer_height=self.altitude_shift if not use_smart_rth else 0, min_distance=get_proximity_warning_threshold(context), ) fps = context.scene.render.fps - if self.use_smart_rth: + if use_smart_rth: # Set up non-trivial parameters # TODO: get them as explicit parameter if needed settings = getattr(context.scene.skybrush, "settings", None) diff --git a/src/modules/sbstudio/plugin/operators/set_server_url.py b/src/modules/sbstudio/plugin/operators/set_server_url.py index 70df994f..13a05c43 100644 --- a/src/modules/sbstudio/plugin/operators/set_server_url.py +++ b/src/modules/sbstudio/plugin/operators/set_server_url.py @@ -16,10 +16,9 @@ class SetServerURLOperator(Operator): url = StringProperty(default="") def execute(self, context): - from sbstudio.plugin.model.global_settings import DroneShowAddonGlobalSettings + from sbstudio.plugin.model.global_settings import get_preferences - prefs = context.preferences - prefs = prefs.addons[DroneShowAddonGlobalSettings.bl_idname].preferences + prefs = get_preferences() prefs.server_url = self.url bpy.ops.wm.save_userpref()