From 22aa041ec10e1e8bc0ec04f10b6cac4aa100b2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 25 Aug 2022 13:06:44 +0200 Subject: [PATCH] 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". --- addon/flamenco/job_types_propgroup.py | 30 ++++++++++++++----- .../scripts/simple_blender_render.js | 2 +- .../content/usage/job-types/_index.md | 3 +- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/addon/flamenco/job_types_propgroup.py b/addon/flamenco/job_types_propgroup.py index f3370e36..56732462 100644 --- a/addon/flamenco/job_types_propgroup.py +++ b/addon/flamenco/job_types_propgroup.py @@ -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 diff --git a/internal/manager/job_compilers/scripts/simple_blender_render.js b/internal/manager/job_compilers/scripts/simple_blender_render.js index 42aa3418..08259437 100644 --- a/internal/manager/job_compilers/scripts/simple_blender_render.js +++ b/internal/manager/job_compilers/scripts/simple_blender_render.js @@ -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: diff --git a/web/project-website/content/usage/job-types/_index.md b/web/project-website/content/usage/job-types/_index.md index 52eea156..92cbcab2 100644 --- a/web/project-website/content/usage/job-types/_index.md +++ b/web/project-website/content/usage/job-types/_index.md @@ -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