Skip to content

create_saver

CreateSaver

Bases: GenericCreateSaver

Fusion Saver to generate image sequence of 'render' product type.

Original Saver creator targeted for 'render' product type. It uses original not to descriptive name because of values in Settings.

Source code in client/ayon_fusion/plugins/create/create_saver.py
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
class CreateSaver(GenericCreateSaver):
    """Fusion Saver to generate image sequence of 'render' product type.

     Original Saver creator targeted for 'render' product type. It uses
     original not to descriptive name because of values in Settings.
    """
    identifier = "io.openpype.creators.fusion.saver"
    label = "Render (saver)"
    name = "render"
    product_type = "render"
    description = "Fusion Saver to generate image sequence"

    default_frame_range_option = "current_context"

    def get_detail_description(self):
        return inspect.cleandoc(
            """Fusion Saver to generate image sequence.

            This creator is expected for publishing of image sequences for 
            'render' product type. (But can publish even single frame 
            'render'.)

            Select what should be source of render range:
            - "Current Folder context" - values set on folder on AYON server
            - "From render in/out" - from node itself
            - "From composition timeline" - from timeline

            Supports local and farm rendering.

            Supports selection from predefined set of output file extensions:
            - exr
            - tga
            - png
            - tif
            - jpg
            """
        )

    def register_callbacks(self):
        self.create_context.add_value_changed_callback(self.on_values_changed)

    def on_values_changed(self, event):
        """Update instance attribute definitions on attribute changes."""

        for instance_change in event["changes"]:
            # First check if there's a change we want to respond to
            instance = instance_change["instance"]
            if instance is None:
                # Change is on context
                continue

            if instance["creator_identifier"] != self.identifier:
                continue

            value_changes = instance_change["changes"]
            if (
                "frame_range_source"
                not in value_changes.get("creator_attributes", {})
            ):
                continue

            # Update the attribute definitions
            new_attrs = self.get_attr_defs_for_instance(instance)
            instance.set_create_attr_defs(new_attrs)

    def get_pre_create_attr_defs(self):
        """Settings for create page"""
        attr_defs = [
            self._get_render_target_enum(),
            self._get_reviewable_bool(),
            self._get_frame_range_enum(),
            self._get_image_format_enum(),
            *self._get_custom_frame_range_attribute_defs()
        ]
        return attr_defs

    def get_attr_defs_for_instance(self, instance):
        return [
            self._get_render_target_enum(),
            self._get_reviewable_bool(),
            self._get_frame_range_enum(),
            self._get_image_format_enum(),
            *self._get_custom_frame_range_attribute_defs(instance)
        ]

    def _get_frame_range_enum(self):
        frame_range_options = {
            "current_task": "Current context",
            "render_range": "From render in/out",
            "comp_range": "From composition timeline",
            "custom_range": "Custom frame range",
        }

        return EnumDef(
            "frame_range_source",
            items=frame_range_options,
            label="Frame range source",
            default=self.default_frame_range_option
        )

    @staticmethod
    def _get_custom_frame_range_attribute_defs(instance=None) -> list:

        # If an instance is provided and 'custom_range' is not the frame
        # range source, then we will disable the custom frame range attributes
        custom_enabled = True
        if instance is not None:
            frame_range_source = instance.get(
                "creator_attributes", {}).get("frame_range_source")
            custom_enabled = frame_range_source == "custom_range"

        # Define custom frame range defaults based on current comp
        # timeline settings (if a comp is currently open)
        comp = get_current_comp()
        if comp is not None:
            attrs = comp.GetAttrs()
            frame_defaults = {
                "frameStart": int(attrs["COMPN_GlobalStart"]),
                "frameEnd": int(attrs["COMPN_GlobalEnd"]),
                "handleStart": int(
                    attrs["COMPN_RenderStart"] - attrs["COMPN_GlobalStart"]
                ),
                "handleEnd": int(
                    attrs["COMPN_GlobalEnd"] - attrs["COMPN_RenderEnd"]
                ),
            }
        else:
            frame_defaults = {
                "frameStart": 1001,
                "frameEnd": 1100,
                "handleStart": 0,
                "handleEnd": 0
            }

        attr_defs = []
        if custom_enabled:
            # UILabelDef does not support `hidden` argument so we exclude it
            # manually
            attr_defs.append(
                UILabelDef(
                    label="<br><b>Custom Frame Range</b>",
                ),
            )

        attr_defs.extend([
            NumberDef(
                "custom_frameStart",
                label="Frame Start",
                default=frame_defaults["frameStart"],
                minimum=0,
                decimals=0,
                tooltip=(
                    "Set the start frame for the export.\n"
                    "Only used if frame range source is 'Custom frame range'."
                ),
                visible=custom_enabled
            ),
            NumberDef(
                "custom_frameEnd",
                label="Frame End",
                default=frame_defaults["frameEnd"],
                minimum=0,
                decimals=0,
                tooltip=(
                    "Set the end frame for the export.\n"
                    "Only used if frame range source is 'Custom frame range'."
                ),
                visible=custom_enabled
            ),
            NumberDef(
                "custom_handleStart",
                label="Handle Start",
                default=frame_defaults["handleStart"],
                minimum=0,
                decimals=0,
                tooltip=(
                    "Set the start handles for the export, this will be "
                    "added before the start frame.\n"
                    "Only used if frame range source is 'Custom frame range'."
                ),
                visible=custom_enabled
            ),
            NumberDef(
                "custom_handleEnd",
                label="Handle End",
                default=frame_defaults["handleEnd"],
                minimum=0,
                decimals=0,
                tooltip=(
                    "Set the end handles for the export, this will be added "
                    "after the end frame.\n"
                    "Only used if frame range source is 'Custom frame range'."
                ),
                visible=custom_enabled
            )
        ])
        return attr_defs

get_pre_create_attr_defs()

Settings for create page

Source code in client/ayon_fusion/plugins/create/create_saver.py
78
79
80
81
82
83
84
85
86
87
def get_pre_create_attr_defs(self):
    """Settings for create page"""
    attr_defs = [
        self._get_render_target_enum(),
        self._get_reviewable_bool(),
        self._get_frame_range_enum(),
        self._get_image_format_enum(),
        *self._get_custom_frame_range_attribute_defs()
    ]
    return attr_defs

on_values_changed(event)

Update instance attribute definitions on attribute changes.

Source code in client/ayon_fusion/plugins/create/create_saver.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
def on_values_changed(self, event):
    """Update instance attribute definitions on attribute changes."""

    for instance_change in event["changes"]:
        # First check if there's a change we want to respond to
        instance = instance_change["instance"]
        if instance is None:
            # Change is on context
            continue

        if instance["creator_identifier"] != self.identifier:
            continue

        value_changes = instance_change["changes"]
        if (
            "frame_range_source"
            not in value_changes.get("creator_attributes", {})
        ):
            continue

        # Update the attribute definitions
        new_attrs = self.get_attr_defs_for_instance(instance)
        instance.set_create_attr_defs(new_attrs)