Allow relative render output root paths

Add a new `abspath(path)` function to the add-on, for use in job type
settings. With this, the "simple blender render" job can support relative
paths for the "render output root" setting, and still have an absolute
final "render output path".
This commit is contained in:
Sybren A. Stüvel 2022-08-25 13:06:44 +02:00
parent 945e3060f4
commit 22aa041ec1
3 changed files with 25 additions and 10 deletions

@ -85,6 +85,18 @@ class JobTypePropertyGroup:
label: str = self.bl_rna.properties[setting_key].name # type: ignore
return label
def locals(self, context: bpy.types.Context) -> dict[str, object]:
"""Return the local variables for job type evaluation."""
return {
"bpy": bpy,
"C": context,
"jobname": context.scene.flamenco_job_name,
"Path": Path,
"abspath": self.abspath,
"last_n_dir_parts": self.last_n_dir_parts,
"settings": self,
}
def eval_and_assign(
self,
context: bpy.types.Context,
@ -103,14 +115,7 @@ class JobTypePropertyGroup:
) -> Any:
"""Evaluate `setting_eval` and return the result."""
eval_locals = {
"bpy": bpy,
"C": context,
"jobname": context.scene.flamenco_job_name,
"Path": Path,
"last_n_dir_parts": self.last_n_dir_parts,
"settings": self,
}
eval_locals = self.locals(context)
try:
value = eval(setting_eval, {}, eval_locals)
except Exception as ex:
@ -200,6 +205,15 @@ class JobTypePropertyGroup:
subset = Path(*dirpath.parts[-n:])
return subset
@staticmethod
def abspath(filepath: Union[str, Path]) -> Path:
"""Return the filepath as absolute path."""
# This changes blendfile-relative paths to absolute.
# It does not resolve `..` entries, though.
abs_unclean = Path(bpy.path.abspath(str(filepath)))
return bpathlib.make_absolute(abs_unclean)
# Mapping from AvailableJobType.setting.type to a callable that converts a value
# to the appropriate type. This is necessary due to the ambiguity between floats

@ -15,7 +15,7 @@ const JOB_TYPE = {
{ key: "add_path_components", type: "int32", required: true, default: 0, propargs: {min: 0, max: 32}, visible: "submission",
description: "Number of path components of the current blend file to use in the render output path"},
{ key: "render_output_path", type: "string", subtype: "file_path", editable: false,
eval: "str(Path(bpy.path.abspath(settings.render_output_root), last_n_dir_parts(settings.add_path_components), jobname, '{timestamp}', '######'))",
eval: "str(Path(abspath(settings.render_output_root), last_n_dir_parts(settings.add_path_components), jobname, '{timestamp}', '######'))",
description: "Final file path of where render output will be saved"},
// Automatically evaluated settings:

@ -117,13 +117,14 @@ following names:
directory path manipulation. Note that this does *not* understand Blender's
`//` prefix for blendfile-relative paths. Use `bpy.path.abspath()` to turn
those into an absolute path if necessary.
- `abspath(path: str | Path) -> Path`: a function that returns the given path as
absolute path. Unlike `bpy.path.abspath()` this also resolves `..` entries.
- `last_n_dir_parts(n, Optional[file_path])`: a function that returns the last
`n` directory parts of some file's path. For example,
`last_n_dir_parts(2, '/complex/path/to/a/file.blend')` will return `to/a`, as
those are the last `2` components of the directory. If `file_path` is
ommitted, it uses the current blend file, i.e. `bpy.data.filepath`.
[bpy]: https://docs.blender.org/api/master/
[context]: https://docs.blender.org/api/master/bpy.context.html
[pathlib]: https://docs.python.org/3/library/pathlib.html