Skip to content

Allow a profile to create multiple render passes - #104

Open
tweak-wtf wants to merge 7 commits into
ynput:developfrom
bEpic-studio:contrib/multi-representation-render-from-single-profile
Open

Allow a profile to create multiple render passes#104
tweak-wtf wants to merge 7 commits into
ynput:developfrom
bEpic-studio:contrib/multi-representation-render-from-single-profile

Conversation

@tweak-wtf

@tweak-wtf tweak-wtf commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Changelog Description

This draft shall make it possible to render more than 1 representation per instance.
Also it aims at making source clip integration optional.

General goal of this is to make use of resolve rendering engine as much as possible to not needing to go through extract_review as this comes with performance penalties compared to resolve.

Additional review information

  • changes profile structure to allow multiple representations to be rendered
  • adds Upload as reviewable tag (really just webreview under the hood)

I tested this for plate and editorial_pkg products on windows only.

Testing notes:

  • build & upload the addon
  • configure more than 1 representation pass
  • publish and check for your expected output

@jakubjezek001 jakubjezek001 added type: enhancement Improvement of existing functionality or minor addition community Issues and PRs coming from the community members labels Jun 23, 2026
@jakubjezek001 jakubjezek001 self-assigned this Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Resolve publish settings/schema and extraction logic to support rendering multiple representations (“render passes”) per instance, and introduces an additional representation tag intended for a “reviewable upload” workflow.

Changes:

  • Extends publish profile settings to define multiple render-pass entries per product base type (plate/editorial_pkg), with shared representation attributes.
  • Updates ExtractProductResources to iterate over multiple output settings and optionally disable “clip source” representation integration.
  • Adds a new representation tag option: webreview (“Upload as reviewable”).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
server/settings.py Adds new settings models/structure to support multiple render-pass entries and introduces the webreview tag; defaults block was commented out.
client/ayon_resolve/plugins/publish/extract_product_resources.py Updates extraction to handle multiple passes, adds optional clip source integration behavior, and normalizes new nested settings structure.
Comments suppressed due to low confidence (1)

client/ayon_resolve/plugins/publish/extract_product_resources.py:157

  • get_default_settings doesn't include required keys like name/tags/custom_tags (and with_handles for plates). When defaults are used, later code accesses settings['name'] and will raise a KeyError.
    def get_default_settings(self, product_base_type="editorial_pkg"):
        """Return hard-coded defaults when no matching preset is found."""
        if product_base_type == "plate":
            return {
                "file_format": "EXR",
                "codec":       "RGB half (DWAA)",
                "preset_path": (
                    "{ayon_render_presets}/clip/EXR_RGB_half_(DWAA).xml"
                ),
            }
        return {
            "file_format":   "QuickTime",
            "codec":         "H.264",
            "preset_path":   (
                "{ayon_render_presets}/timeline/QuickTime_H264.xml"
            ),
            "export_otio": True,
            "otio_rootless": True,
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread client/ayon_resolve/plugins/publish/extract_product_resources.py Outdated
Comment on lines +113 to +116
result = []
for preset in profile.get(product_base_type, []):
normalized = self._normalize_preset(preset)
result.append(normalized)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adressed in e988bfb

settings now validate for unique representation names per repre of each profile

Comment on lines 125 to 135
normalized = {
"name": preset["name"],
"name": preset["shared"]["repre_name"],
"file_format": fmt.get("format"),
"codec": fmt.get("codec"),
"preset_path": fmt.get("preset_path"),
"with_handles": sub.get("with_handles"),
"tags": preset["tags"],
"custom_tags": preset["custom_tags"],
"with_handles": preset["settings"].get("with_handles"),
"tags": preset["shared"]["tags"],
"custom_tags": preset["shared"]["custom_tags"],
"export_otio": preset["settings"].get("export_otio", None),
"otio_rootless": preset["settings"].get("otio_rootless", None),
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm i wouldn't add colorspace here.
i think handling colorspaces and their conversion here ends up being convoluted and not flexible.

i'm running an approach where i give artists a toggle to enable/disable "Post ColorGroup" in resolve directly before render triggers.
that way the artist can use vanilla resolve to do linearization.
but that's not in this PR. can open it up if there is interest tho

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having said that we might completely remove colorspace from server settings.
not sure what the original intent behind this is

Comment thread client/ayon_resolve/plugins/publish/extract_product_resources.py
Comment thread server/settings.py Outdated

return (profile["integrate_clip_source"], result)

def _normalize_preset(self, preset):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make more sense for this to return a dataclass? So that the process methods also take these dataclasses? Would probably make the code way more sane?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh i only used what was already there trying to be minimally invasive.

but sure. refactor everything preset related into 1 dataclass. can do that ✌️

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to do so in separate PR though @jakubjezek001 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alrighty, then i'll continue to adress the notes where possible and eventually set this to be ready for review.
on that note thanks for checking this out already

Comment on lines +54 to +57
# todo: find the source of this, i think it's some otio extractor
# maybe skip adding the repre there? but settings would be in a different extractor... doesn't make sense
if not integrate_clip_source:
instance.data["representations"] = [] # disables clip source integration

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this just a matter of tagging the repres with a delete tag? 🤔

@tweak-wtf tweak-wtf Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tried it just now but unfortunately no :/
the main issue here is this

  • i have a r3d file as source that i'm trying to publish as exr
  • Collect OTIO Subset Resources picks up the r3d and adds it as representation
  • Extract OTIO trim longer video kicks in failing with ffprobe error Invalid data found when processing input
  • since the r3d is still a representation it will be integrated
    • doesn't really make sense as u don't want to integrate the cam source, only the plates thatw ere rendered from it before

since i haven't found any settings in ayon-core for those 2 otio related plugins i made this admittedly ugly af workaround.
should i add server settings for the otio plugins in ayon-core to e.g. remove resolve from the hosts?
if the collector never runs it will also never add the cam source as representation right 🤷

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should i add server settings for the otio plugins in ayon-core to e.g. remove resolve from the hosts? if the > collector never runs it will also never add the cam source as representation right 🤷

You may want to check out #109

I think it overlaps?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried with the changes in #109 but to no avail :/

the main issue is that Collect OTIO Subset Resources will always run and will always add the source media to this instance's representations.

i kinda see 3 options here:

  1. make Collect OTIO Subset Resources optional in ayon-core
  2. add e.g. skip_otio bool to instance.data during creation and respect this in the otio subset collector
  3. keep it as is in this PR

kinda leaning towards option 1 tbh but would require a new PR.

thoughts on this @BigRoy ?

"ExtractProductResources: unhandled product base type '%s', skipping.", product_base_type
)
# set rendering logger to inherit from publisher's logger
rendering.log = self.log

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this isn't new - but this changes the module-level log variable and will keep it changed after this has run. If easy to fix, would be good to clean that up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just tested without the module-level log override.
it causes the logs from ayon_resolve.api functions to not be visible in the publisher's details pane. however, the resolve console still prints them.

imho we can remove it completely. afaik other addons' api functions also don't propagate to the publisher.

does this open up the general logging can of worms?

@tweak-wtf
tweak-wtf marked this pull request as ready for review July 27, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Issues and PRs coming from the community members type: enhancement Improvement of existing functionality or minor addition

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants