Ejemplo n.º 1
0
def on_pyblish_instance_toggled(instance, new_value, old_value):
    """Toggle saver tool passthrough states on instance toggles."""

    from avalon.fusion import comp_lock_and_undo_chunk

    comp = instance.context.data.get("currentComp")
    if not comp:
        return

    savers = [
        tool for tool in instance if getattr(tool, "ID", None) == "Saver"
    ]
    if not savers:
        return

    # Whether instances should be passthrough based on new value
    passthrough = not new_value
    with comp_lock_and_undo_chunk(comp,
                                  undo_queue_name="Change instance "
                                  "active state"):
        for tool in savers:
            attrs = tool.GetAttrs()
            current = attrs["TOOLB_PassThrough"]
            if current != passthrough:
                tool.SetAttrs({"TOOLB_PassThrough": passthrough})
Ejemplo n.º 2
0
    def load(self, context, name, namespace, data):

        from avalon.fusion import (imprint_container, get_current_comp,
                                   comp_lock_and_undo_chunk)

        # Fallback to asset name when namespace is None
        if namespace is None:
            namespace = context['asset']['name']

        # Use the first file for now
        path = self._get_first_image(self.fname)

        # Create the Loader with the filename path set
        comp = get_current_comp()
        with comp_lock_and_undo_chunk(comp, "Create Loader"):

            args = (-32768, -32768)
            tool = comp.AddTool("Loader", *args)
            tool["Clip"] = path

            # Set global in point to start frame (if in version.data)
            start = context["version"]["data"].get("startFrame", None)
            if start is not None:
                loader_shift(tool, start, relative=False)

            imprint_container(tool,
                              name=name,
                              namespace=namespace,
                              context=context,
                              loader=self.__class__.__name__)
Ejemplo n.º 3
0
def duplicate_with_input_connections():
    """Duplicate selected tools with incoming connections."""

    original_tools = comp.GetToolList(True).values()
    if not original_tools:
        return  # nothing selected

    with comp_lock_and_undo_chunk(comp, "Duplicate With Input Connections"):

        # Generate duplicates
        comp.Copy()
        comp.SetActiveTool()
        comp.Paste()
        duplicate_tools = comp.GetToolList(True).values()

        # Copy connections
        for original, new in zip(original_tools, duplicate_tools):

            original_inputs = original.GetInputList().values()
            new_inputs = new.GetInputList().values()
            assert len(original_inputs) == len(new_inputs)

            for original_input, new_input in zip(original_inputs, new_inputs):

                if is_connected(original_input):

                    if is_connected(new_input):
                        # Already connected if it is between the copied tools
                        continue

                    new_input.ConnectTo(original_input.GetConnectedOutput())
                    assert is_connected(new_input), "Must be connected now"
    def process(self):

        file_format = "TiffFormat"

        comp = fusion.get_current_comp()

        # todo: improve method of getting current environment
        # todo: pref avalon.Session over os.environ

        workdir = os.path.normpath(os.environ["AVALON_WORKDIR"])

        filename = "{}..tiff".format(self.name)
        filepath = os.path.join(workdir, "render", "preview", filename)

        with fusion.comp_lock_and_undo_chunk(comp):
            args = (-32768, -32768)  # Magical position numbers
            saver = comp.AddTool("Saver", *args)
            saver.SetAttrs({"TOOLS_Name": self.name})

            # Setting input attributes is different from basic attributes
            # Not confused with "MainInputAttributes" which
            saver["Clip"] = filepath
            saver["OutputFormat"] = file_format

            # # # Set standard TIFF settings
            if saver[file_format] is None:
                raise RuntimeError("File format is not set to TiffFormat, "
                                   "this is a bug")

            # Set file format attributes
            saver[file_format]["Depth"] = 1  # int8 | int16 | float32 | other
            saver[file_format]["SaveAlpha"] = 0
Ejemplo n.º 5
0
    def remove(self, container):

        from avalon.fusion import comp_lock_and_undo_chunk

        tool = container["_tool"]
        assert tool.ID == "Loader", "Must be Loader"
        comp = tool.Comp()

        with comp_lock_and_undo_chunk(comp, "Remove Loader"):
            tool.Delete()
Ejemplo n.º 6
0
    def process(self, instance):

        context = instance.context
        key = "__hasRun{}".format(self.__class__.__name__)
        if context.data.get(key, False):
            return
        else:
            context.data[key] = True

        current_comp = context.data["currentComp"]
        frame_start = current_comp.GetAttrs("COMPN_RenderStart")
        frame_end = current_comp.GetAttrs("COMPN_RenderEnd")
        path = instance.data["path"]
        output_dir = instance.data["outputDir"]

        ext = os.path.splitext(os.path.basename(path))[-1]

        self.log.info("Starting render")
        self.log.info("Start frame: {}".format(frame_start))
        self.log.info("End frame: {}".format(frame_end))

        with fusion.comp_lock_and_undo_chunk(current_comp):
            result = current_comp.Render()

        if "representations" not in instance.data:
            instance.data["representations"] = []

        collected_frames = os.listdir(output_dir)
        repre = {
            'name': ext[1:],
            'ext': ext[1:],
            'frameStart': "%0{}d".format(len(str(frame_end))) % frame_start,
            'files': collected_frames,
            "stagingDir": output_dir,
        }
        instance.data["representations"].append(repre)

        # review representation
        repre_preview = repre.copy()
        repre_preview["name"] = repre_preview["ext"] = "mp4"
        repre_preview["tags"] = ["review", "preview", "ftrackreview", "delete"]
        instance.data["representations"].append(repre_preview)

        self.log.debug(f"_ instance.data: {pformat(instance.data)}")

        if not result:
            raise RuntimeError("Comp render failed")
Ejemplo n.º 7
0
def update_loader_ranges():
    comp = fusion.get_current_comp()
    with fusion.comp_lock_and_undo_chunk(comp, "Reload clip time ranges"):
        tools = comp.GetToolList(True, "Loader").values()
        for tool in tools:

            # Get tool attributes
            tool_a = tool.GetAttrs()
            clipTable = tool_a['TOOLST_Clip_Name']
            altclipTable = tool_a['TOOLST_AltClip_Name']
            startTime = tool_a['TOOLNT_Clip_Start']
            old_global_in = tool.GlobalIn[comp.CurrentTime]

            # Reapply
            for index, _ in clipTable.items():
                time = startTime[index]
                tool.Clip[time] = tool.Clip[time]

            for index, _ in altclipTable.items():
                time = startTime[index]
                tool.ProxyFilename[time] = tool.ProxyFilename[time]

            tool.GlobalIn[comp.CurrentTime] = old_global_in
Ejemplo n.º 8
0
    def process(self, instance):

        # This should be a ContextPlugin, but this is a workaround
        # for a bug in pyblish to run once for a family: issue #250
        context = instance.context
        key = "__hasRun{}".format(self.__class__.__name__)
        if context.data.get(key, False):
            return
        else:
            context.data[key] = True

        current_comp = context.data["currentComp"]
        start_frame = current_comp.GetAttrs("COMPN_RenderStart")
        end_frame = current_comp.GetAttrs("COMPN_RenderEnd")

        self.log.info("Starting render")
        self.log.info("Start frame: {}".format(start_frame))
        self.log.info("End frame: {}".format(end_frame))

        with fusion.comp_lock_and_undo_chunk(current_comp):
            result = current_comp.Render()

        if not result:
            raise RuntimeError("Comp render failed")
Ejemplo n.º 9
0
    def update(self, container, representation):
        """Update the Loader's path

        Fusion automatically tries to reset some variables when changing
        the loader's path to a new file. These automatic changes are to its
        inputs:
            - ClipTimeStart: Fusion reset to 0 if duration changes
              - We keep the trim in as close as possible to the previous value.
                When there are less frames then the amount of trim we reduce
                it accordingly.

            - ClipTimeEnd: Fusion reset to 0 if duration changes
              - We keep the trim out as close as possible to the previous value
                within new amount of frames after trim in (ClipTimeStart) has
                been set.

            - GlobalIn: Fusion reset to comp's global in if duration changes
              - We change it to the "startFrame"

            - GlobalEnd: Fusion resets to globalIn + length if duration changes
              - We do the same like Fusion - allow fusion to take control.

            - HoldFirstFrame: Fusion resets this to 0
              - We preverse the value.

            - HoldLastFrame: Fusion resets this to 0
              - We preverse the value.

            - Reverse: Fusion resets to disabled if "Loop" is not enabled.
              - We preserve the value.

            - Depth: Fusion resets to "Format"
              - We preverse the value.

            - KeyCode: Fusion resets to ""
              - We preverse the value.

            - TimeCodeOffset: Fusion resets to 0
              - We preverse the value.

        """

        from avalon.fusion import comp_lock_and_undo_chunk

        tool = container["_tool"]
        assert tool.ID == "Loader", "Must be Loader"
        comp = tool.Comp()

        root = api.get_representation_path(representation)
        path = self._get_first_image(root)

        # Get start frame from version data
        version = io.find_one({
            "type": "version",
            "_id": representation["parent"]
        })
        start = version["data"].get("startFrame")
        if start is None:
            self.log.warning("Missing start frame for updated version"
                             "assuming starts at frame 0 for: "
                             "{} ({})".format(tool.Name, representation))
            start = 0

        with comp_lock_and_undo_chunk(comp, "Update Loader"):

            # Update the loader's path whilst preserving some values
            with preserve_trim(tool, log=self.log):
                with preserve_inputs(tool,
                                     inputs=("HoldFirstFrame", "HoldLastFrame",
                                             "Reverse", "Depth", "KeyCode",
                                             "TimeCodeOffset")):
                    tool["Clip"] = path

            # Set the global in to the start frame of the sequence
            global_in_changed = loader_shift(tool, start, relative=False)
            if global_in_changed:
                # Log this change to the user
                self.log.debug("Changed '%s' global in: %d" %
                               (tool.Name, start))

            # Update the imprinted representation
            tool.SetData("avalon.representation", str(representation["_id"]))
Ejemplo n.º 10
0
def main():
    """Set all loaders to 32 bit"""
    with comp_lock_and_undo_chunk(comp, 'Loaders to 32bit'):
        tools = comp.GetToolList(False, "Loader").values()
        for tool in tools:
            tool.Depth = 5
Ejemplo n.º 11
0
def main():
    """Set all backgrounds to 32 bit"""
    with comp_lock_and_undo_chunk(comp, 'Backgrounds to 32bit'):
        tools = comp.GetToolList(False, "Background").values()
        for tool in tools:
            tool.Depth = 5
Ejemplo n.º 12
0
"""Forces Fusion to 'retrigger' the Loader to update.

Warning:
    This might change settings like 'Reverse', 'Loop', trims and other
    settings of the Loader. So use this at your own risk.

"""

from avalon.fusion import comp_lock_and_undo_chunk

with comp_lock_and_undo_chunk(comp, "Reload clip time ranges"):
    tools = comp.GetToolList(True, "Loader").values()
    for tool in tools:

        # Get tool attributes
        tool_a = tool.GetAttrs()
        clipTable = tool_a['TOOLST_Clip_Name']
        altclipTable = tool_a['TOOLST_AltClip_Name']
        startTime = tool_a['TOOLNT_Clip_Start']
        old_global_in = tool.GlobalIn[comp.CurrentTime]

        # Reapply
        for index, _ in clipTable.items():
            time = startTime[index]
            tool.Clip[time] = tool.Clip[time]

        for index, _ in altclipTable.items():
            time = startTime[index]
            tool.ProxyFilename[time] = tool.ProxyFilename[time]

        tool.GlobalIn[comp.CurrentTime] = old_global_in