Fixing effect loader for macos resources #245
Conversation
Add new imports for StringTemplate and Anatomy to enhance file path processing in LoadEffects class.
There was a problem hiding this comment.
Pull request overview
Fixes Nuke effect loading on macOS by resolving effect resource file paths through AYON Anatomy root templates, aiming to produce correct platform-specific absolute paths at load time.
Changes:
- Add AYON Anatomy + StringTemplate-based path resolution for
fileknob values when recreating effect nodes. - Convert resource paths via
find_root_template_from_path+ template formatting using Anatomy roots.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| self.log.warning(e) | ||
| continue | ||
|
|
||
| # check if `file` in knob name |
There was a problem hiding this comment.
The comment says “check if file in knob name” but the condition is k == "file". Either update the comment or broaden the condition (if the intent is to catch other file-like knobs) to avoid confusion for future maintainers.
| # check if `file` in knob name | |
| # check if the knob name is exactly `file` |
| success, rootless_path = \ | ||
| anatomy.find_root_template_from_path(file_path) |
There was a problem hiding this comment.
Avoid using a backslash line continuation here; wrap the call in parentheses instead. This is easier to edit and less error-prone if trailing whitespace changes.
| success, rootless_path = \ | |
| anatomy.find_root_template_from_path(file_path) | |
| success, rootless_path = ( | |
| anatomy.find_root_template_from_path(file_path) | |
| ) |
| continue | ||
|
|
||
| # check if `file` in knob name | ||
| print(f"{k}: {v}") |
There was a problem hiding this comment.
Remove the direct print debug output (or switch it to self.log.debug). Printing every knob/value during load will spam Nuke’s Script Editor/stdout and is hard to control via log levels.
| print(f"{k}: {v}") | |
| self.log.debug(f"{k}: {v}") |
| file_path = v | ||
| project_name = get_current_project_name() | ||
| anatomy = Anatomy(project_name=project_name) | ||
| _template_data = { |
There was a problem hiding this comment.
get_current_project_name() inside the knob loop can resolve roots for the currently active project rather than the project being loaded from context. Since _load_effects_to_group already has context, consider passing context["project"]["name"] (or a prebuilt Anatomy) down into _create_nodes_order to avoid mismatches.
| project_name = get_current_project_name() | ||
| anatomy = Anatomy(project_name=project_name) | ||
| _template_data = { | ||
| "root": anatomy.roots, | ||
| } |
There was a problem hiding this comment.
Anatomy(...) is created inside the per-node/per-knob loop. If this hits settings/API each time, it can become a noticeable load-time cost. Create anatomy (and the template data dict) once before iterating nodes/knobs and reuse it.
| self.log.info(f"rootless_path: {rootless_path}") | ||
| if success: | ||
| abs_resources_path = StringTemplate.format_strict_template( | ||
| rootless_path, _template_data | ||
| ) | ||
| v = abs_resources_path | ||
| self.log.info(f"File path: {abs_resources_path}") |
There was a problem hiding this comment.
These info logs will run for every file knob and will emit resolved absolute paths, which can be very noisy in normal usage. Consider lowering to debug (and/or logging only on failure) so routine loads don’t flood logs.
| self.log.info(f"rootless_path: {rootless_path}") | |
| if success: | |
| abs_resources_path = StringTemplate.format_strict_template( | |
| rootless_path, _template_data | |
| ) | |
| v = abs_resources_path | |
| self.log.info(f"File path: {abs_resources_path}") | |
| self.log.debug(f"rootless_path: {rootless_path}") | |
| if success: | |
| abs_resources_path = StringTemplate.format_strict_template( | |
| rootless_path, _template_data | |
| ) | |
| v = abs_resources_path | |
| self.log.debug(f"File path: {abs_resources_path}") |
|
|
||
| file = self.filepath_from_context(context).replace("\\", "/") | ||
| with open(file, "r") as f: | ||
| with open(file) as f: |
There was a problem hiding this comment.
| with open(file) as f: | |
| with open(file, "r") as f: |
| project_name = get_current_project_name() | ||
| anatomy = Anatomy(project_name=project_name) |
There was a problem hiding this comment.
I think this should use the project from which we're loading. Mostly would be current project, but you can also load from library project. The project entity is stored in context, so you could just do
project_entity = context["project"]
anatomy = Anatomy(project_entity["name"], project_entity=project_entity)Also could happen only once for the whole load logic in case the anatomy would be created multiple times.
There was a problem hiding this comment.
Side note: Why is this actually happening? The loaded "files" can have loaded other files? That might be a mess. Imagine having file that is e.g. ocio file defined with environment variables instead of anatomy roots, it would just collapse.
| rootless_path, _template_data | ||
| ) | ||
| v = abs_resources_path | ||
| self.log.info(f"File path: {abs_resources_path}") |
There was a problem hiding this comment.
| self.log.info(f"File path: {abs_resources_path}") |
| # so it is multiplatform compatible | ||
| if k == "file": | ||
| file_path = v | ||
| project_name = get_current_project_name() |
There was a problem hiding this comment.
2 things:
- it is possible to load from other projects
- the Anatomy creation can be very heavy operation
Rather prepare the anatomy ahead in _load_effects_to_group and use project entity from context.
project_entity = context["project"]
anatomy = Anatomy(
project_entity["name"], project_entity=project_entity
)
Changelog Description
Fixes effect loader on macOS by properly resolving resource file paths using AYON Anatomy templates. This ensures effects reference resources with correct platform-specific paths, resolving issues with effect loading on macOS systems.
Additional info
The loader now uses the Anatomy system to convert absolute paths into platform-agnostic template paths. When setting node attributes with file references, the code:
This approach ensures effects work correctly across different OS environments and project configurations.
Testing notes: