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 label: str = self.bl_rna.properties[setting_key].name # type: ignore
return label 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( def eval_and_assign(
self, self,
context: bpy.types.Context, context: bpy.types.Context,
@ -103,14 +115,7 @@ class JobTypePropertyGroup:
) -> Any: ) -> Any:
"""Evaluate `setting_eval` and return the result.""" """Evaluate `setting_eval` and return the result."""
eval_locals = { eval_locals = self.locals(context)
"bpy": bpy,
"C": context,
"jobname": context.scene.flamenco_job_name,
"Path": Path,
"last_n_dir_parts": self.last_n_dir_parts,
"settings": self,
}
try: try:
value = eval(setting_eval, {}, eval_locals) value = eval(setting_eval, {}, eval_locals)
except Exception as ex: except Exception as ex:
@ -200,6 +205,15 @@ class JobTypePropertyGroup:
subset = Path(*dirpath.parts[-n:]) subset = Path(*dirpath.parts[-n:])
return subset 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 # 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 # 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", { 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"}, 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, { 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"}, description: "Final file path of where render output will be saved"},
// Automatically evaluated settings: // Automatically evaluated settings:

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