Ejemplo n.º 1
0
    def generateTasksData(self):
        '''
        Return a list of tasks data.  Each item in the list represents one
        task of work that will be created. Each task dictionary has the following
        keys:
            command: The command for the task to execute

            frames: [optional], helps to bind/display the relationship between a
                     task and the frames that the task is operating on.  Because
                     a task can be any arbitrary command, the notion of "frames"
                     may not be relevant and can be left empty.

        Example(two tasks):

            # Task 0
            [{"command": "nuke-render --view main -X AFWrite.write_exr -F 1-1x1 \"/tmp/my_nuke_file.nk\""
              "frames": "1"},
            # Task 1
             {"command": "nuke-render --view main -X AFWrite.write_exr -F 10-20x2 \"/tmp/my_nuke_file.nk\""
              "frames": "10-20x2"}]
        '''

        cmd_template = "nuke-render %s %s -F %s-%sx%s %s"

        write_nodes = self.extended_widget.getSelectedWriteNodes()
        write_nodes_args = " ".join(
            ["-X %s" % write_node for write_node in write_nodes])
        selected_views = self.extended_widget.getSelectedViews()
        view_args = "--view %s" % ",".join(selected_views)
        nuke_scriptpath = self.getSourceFilepath()

        # Strip the lettered drive from the filepath (if one exists).
        # This is a hack to allow a Windows filepath to be properly used
        # as an argument in a linux shell on the backend. Not pretty.
        nuke_filepath_nodrive = file_utils.strip_drive_letter(nuke_scriptpath)

        chunk_size = self.getChunkSize()
        frames_str = self.getFrameRangeString()
        frames = seqLister.expandSeq(frames_str.split(","), None)

        # Use the task frames generator to dispense the appropriate amount of
        # frames per task, generating a command for each task to execute
        tasks_data = []
        frames_generator = submitter.TaskFramesGenerator(
            frames, chunk_size=chunk_size, uniform_chunk_step=True)
        for start_frame, end_frame, step, task_frames in frames_generator:
            task_cmd = cmd_template % (
                view_args, write_nodes_args, start_frame, end_frame, step,
                file_utils.quote_path(nuke_filepath_nodrive))

            # generate tasks data
            # convert the list of frame ints into a single string expression
            # TODO:(lws) this is silly. We should keep this as a native int list.
            task_frames_str = ", ".join(seqLister.condenseSeq(task_frames))
            tasks_data.append({"command": task_cmd, "frames": task_frames_str})

        return tasks_data
Ejemplo n.º 2
0
    def generateTasksData(self):
        '''
        Return a list of tasks data.  Each item in the list represents one
        task of work that will be created.

        Each task dictionary has the following
        keys:
            command: The command for the task to execute

            frames: [optional], helps to bind/display the relationship between a
                     task and the frames that the task is operating on.  Because
                     a task can be any arbitrary command, the notion of "frames"
                     may not be relevant and can be left empty.

        Eventually we may want to populate this with *everything* a task needs
        (offloading it from the Job entity). This would allow more per-task flexiblity (such as differing environments,
        files, etc).  Just general containment in general.


        Example(two tasks):

            # Task 0
            [ {"command": "Render -s 1 -e 1 -rl renderlayer1 \"maya_filepath.ma\""
               "frames": "1"},
            # Task 1
            {"command": "Render -s 10 -e 20 -b 2 \"maya_filepath.ma\""
             "frames": "10-20x2"} ]
        '''

        # Create a template command that be be used for each task's command
        cmd_template = "Render %s -s %s -e %s -b %s %s -rd /tmp/render_output/ %s %s"

        # Retrieve the source maya file
        maya_filepath = self.getSourceFilepath()
        # Strip the lettered drive from the filepath (if one exists).
        # This is a hack to allow a Windows filepath to be properly used
        # as an argument in a linux shell on the backend. Not pretty.
        maya_filepath_nodrive = file_utils.strip_drive_letter(maya_filepath)

        # Get the user-selected render layers
        render_layers = self.extended_widget.getSelectedRenderLayers()

        active_renderer = maya_utils.get_active_renderer()
        # If the active renderer is rman/renderman, then we must explicitly declare it
        # as the renderer in the command.  Otherwise the output path is not respected.
        # I assume this is a renderman bug.
        # TODO:(lws). This is a super ugly exception case that we need to better manage/abstract
        if active_renderer == "renderManRIS":
            renderer_arg = "-r rman"
        # If the active renderer is renderman, then we must explicitly declare it (see comment above).
        # We must also clear out the specified render layers because renderman 22 doesn't accept the rl
        # flag anymore. By not specifying any render layers, *all* active render layers will be rendered
        # TODO:(lws). This is really nasty/dangerous. Hopefully pixar/renderman will re-add support
        # for specifying render layers ASAP!
        elif active_renderer == "renderman":
            renderer_arg = "-r renderman"
            render_layers = []

        # For any other renderers, we don't need to specify the renderer arg (the renderer indicated
        # in the maya scene will be used).
        else:
            renderer_arg = ""

        # construct -rl flag (omit it if no render layers specified)
        render_layer_args = ("-rl " + ",".join(render_layers)) if render_layers else ""

        # Workspace/Project arg. Only add flag if a workspace has been indicated in the submitter ui
        workspace = self.extended_advanced_widget.getWorkspaceDir()
        # Strip the lettered drive from the workspace (if one exists).
        # This is a hack to allow a Windows filepath to be properly used
        # as an argument in a linux shell on the backend. Not pretty.
        workspace_nodrive = file_utils.strip_drive_letter(workspace)
        project_arg = "-proj %s" % file_utils.quote_path(workspace_nodrive) if workspace_nodrive.strip() else ""

        chunk_size = self.getChunkSize()
        frames_str = self.getFrameRangeString()
        frames = seqLister.expandSeq(frames_str.split(","), None)

        # Use the task frames generator to dispense the appropriate amount of
        # frames per task, generating a command for each task to execute
        tasks_data = []
        frames_generator = submitter.TaskFramesGenerator(frames, chunk_size=chunk_size, uniform_chunk_step=True)
        for start_frame, end_frame, step, task_frames in frames_generator:
            task_cmd = cmd_template % (renderer_arg,
                                       start_frame,
                                       end_frame,
                                       step,
                                       render_layer_args,
                                       project_arg,
                                       file_utils.quote_path(maya_filepath_nodrive))

            # Generate tasks data
            # convert the list of frame ints into a single string expression
            # TODO:(lws) this is silly. We should keep this as a native int list.
            task_frames_str = ", ".join(seqLister.condenseSeq(task_frames))
            tasks_data.append({"command": task_cmd,
                               "frames": task_frames_str})
        return tasks_data
Ejemplo n.º 3
0
    def generateTasksData(self):
        '''
        Return a list of tasks data.  Each item in the list represents one
        task of work that will be created.

        Each task dictionary has the following
        keys:
            command: The command for the task to execute

            frames: [optional], helps to bind/display the relationship between a
                     task and the frames that the task is operating on.  Because
                     a task can be any arbitrary command, the notion of "frames"
                     may not be relevant and can be left empty.

        Eventually we may want to populate this with *everything* a task needs
        (offloading it from the Job entity). This would allow more per-task flexiblity (such as differing environments,
        files, etc).  Just general containment in general.


        Example(two tasks):

            # Task 0
            [ {"command": "Render -s 1 -e 1 -rl renderlayer1 \"maya_filepath.ma\""
               "frames": "1"},
            # Task 1
            {"command": "Render -s 10 -e 20 -b 2 \"maya_filepath.ma\""
             "frames": "10-20x2"} ]
        '''

        # Create a template command that be be used for each task's command
        cmd_template = "Render %s -s %s -e %s -b %s %s -rd /tmp/render_output/ %s"

        # Retrieve the source maya file
        maya_filepath = self.getSourceFilepath()
        # Strip the lettered drive from the filepath (if one exists).
        # This is a hack to allow a Windows filepath to be properly used
        # as an argument in a linux shell on the backend. Not pretty.
        maya_filepath_nodrive = file_utils.strip_drive_letter(maya_filepath)

        # If the active renderer is renderman, then we must explictly declare it
        # as the renderer in the command.  Otherwise the output path is not respected.
        # I assume this is a renderman bug.
        # TODO:(lws). This is a super ugly exception case that we need to better manage/abstract
        renderer_arg = "-r rman" if maya_utils.get_active_renderer() in [
            "renderManRIS"
        ] else ""

        # Get the user-selected render layers
        render_layers = self.extended_widget.getSelectedRenderLayers()
        render_layer_args = "-rl " + ",".join(render_layers)

        chunk_size = self.getChunkSize()
        frames_str = self.getFrameRangeString()
        frames = seqLister.expandSeq(frames_str.split(","), None)

        # Use the task frames generator to dispense the appropriate amount of
        # frames per task, generating a command for each task to execute
        tasks_data = []
        frames_generator = submitter.TaskFramesGenerator(
            frames, chunk_size=chunk_size, uniform_chunk_step=True)
        for start_frame, end_frame, step, task_frames in frames_generator:
            task_cmd = cmd_template % (
                renderer_arg, start_frame, end_frame, step, render_layer_args,
                file_utils.quote_path(maya_filepath_nodrive))

            # Generate tasks data
            # convert the list of frame ints into a single string expression
            # TODO:(lws) this is silly. We should keep this as a native int list.
            task_frames_str = ", ".join(seqLister.condenseSeq(task_frames))
            tasks_data.append({"command": task_cmd, "frames": task_frames_str})
        return tasks_data