Add option to make a job setting auto-evaluatable by the user

Add a new job setting option `autoevalLockable`. Setting this to `true` in
the job compiler's `JOB_TYPE` settings has the following effect:

- By default, the setting will not be editable in Blender's job submission
  interface. Instead, a toggle button with a 'car' icon will be shown.
- When the 'car' button is toggled off, the setting becomes editable again.

In its default, uneditable state, the setting will be auto-evaluated before
submission.

This makes it possible to 'lock in' auto-evaluation. The main use case is
for the frame range of the render job. By default this will be locked to
the scene frame range, but it can still be overridden if a different
range is wanted.
This commit is contained in:
Sybren A. Stüvel 2023-07-13 12:07:02 +02:00
parent 168305f785
commit 3a3e664ae2
4 changed files with 84 additions and 3 deletions

View File

@ -95,7 +95,11 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel):
return
row = layout.row(align=True)
if setting.get("editable", True):
if job_types.setting_can_autoeval(setting):
self.draw_setting_autoeval(row, propgroup, setting)
else:
self.draw_setting_editable(row, propgroup, setting)
else:
self.draw_setting_readonly(context, row, propgroup, setting)
@ -132,6 +136,30 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel):
) -> None:
layout.prop(propgroup, setting.key)
def draw_setting_autoeval(
self,
layout: bpy.types.UILayout,
propgroup: JobTypePropertyGroup,
setting: _AvailableJobSetting,
) -> None:
autoeval_enabled = job_types.setting_should_autoeval(propgroup, setting)
if autoeval_enabled:
label = propgroup.bl_rna.properties[setting.key].name
layout.prop(
propgroup,
job_types.setting_autoeval_propname(setting),
text=label,
icon="AUTO",
)
else:
self.draw_setting_editable(layout, propgroup, setting)
layout.prop(
propgroup,
job_types.setting_autoeval_propname(setting),
text="",
icon="AUTO",
)
def draw_flamenco_status(
self, context: bpy.types.Context, layout: bpy.types.UILayout
) -> None:

View File

@ -68,6 +68,30 @@ def setting_is_visible(setting: _AvailableJobSetting) -> bool:
return str(visibility) in {"visible", "submission"}
def setting_should_autoeval(
propgroup: job_types_propgroup.JobTypePropertyGroup,
setting: _AvailableJobSetting,
) -> bool:
if not setting_is_visible(setting):
# Invisible settings are there purely to be auto-evaluated.
return True
propname = setting_autoeval_propname(setting)
return getattr(propgroup, propname, False)
def setting_can_autoeval(setting: _AvailableJobSetting) -> bool:
# Note that this uses the Pythonified name; that's done by the OpenAPI code generator.
can: bool = setting.get("autoeval_lockable", False)
print(f"setting_can_autoeval({setting.key}: {can})")
return can
def setting_autoeval_propname(setting: _AvailableJobSetting) -> str:
"""Return the property name of the 'auto-eval' state for this setting."""
return f"autoeval_{setting.key}"
def _store_available_job_types(available_job_types: _AvailableJobTypes) -> None:
global _available_job_types
global _job_type_enum_items

View File

@ -131,8 +131,7 @@ class JobTypePropertyGroup:
setting value. Otherwise the default is used.
"""
for setting in self.job_type.settings:
if job_types.setting_is_visible(setting):
# Skip those settings that will be visible in the GUI.
if not job_types.setting_should_autoeval(self, setting):
continue
setting_eval = setting.get("eval", "")
@ -253,10 +252,16 @@ def generate(job_type: _AvailableJobType) -> type[JobTypePropertyGroup]:
)
pg_type.__annotations__ = {}
# Add RNA properties for the settings.
for setting in job_type.settings:
prop = _create_property(job_type, setting)
pg_type.__annotations__[setting.key] = prop
if job_types.setting_can_autoeval(setting):
# Add RNA property for the 'auto-eval' toggle.
propname, prop = _create_autoeval_property(setting)
pg_type.__annotations__[propname] = prop
assert issubclass(pg_type, JobTypePropertyGroup), "did not expect type %r" % type(
pg_type
)
@ -304,6 +309,29 @@ def _create_property(job_type: _AvailableJobType, setting: _AvailableJobSetting)
return prop
def _create_autoeval_property(
setting: _AvailableJobSetting,
) -> tuple[str, Any]:
from flamenco.manager.model.available_job_setting import AvailableJobSetting
assert isinstance(setting, AvailableJobSetting)
setting_name = _job_setting_key_to_label(setting.key)
prop_descr = (
"Automatically determine the value for %r when the job gets submitted"
% setting_name
)
prop = bpy.props.BoolProperty(
name="Auto Evaluate %s" % setting_name,
description=prop_descr,
default=True,
)
prop_name = job_types.setting_autoeval_propname(setting)
return prop_name, prop
def _find_prop_type(
job_type: _AvailableJobType, setting: _AvailableJobSetting
) -> tuple[Any, dict[str, Any]]:

View File

@ -5,6 +5,7 @@ const JOB_TYPE = {
settings: [
// Settings for artists to determine:
{ key: "frames", type: "string", required: true, eval: "f'{C.scene.frame_start}-{C.scene.frame_end}'",
autoevalLockable: true,
description: "Frame range to render. Examples: '47', '1-30', '3, 5-10, 47-327'" },
{ key: "chunk_size", type: "int32", default: 1, description: "Number of frames to render in one Blender render task",
visible: "submission" },