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 -V 2 %s %s -F %s-%sx%s %s" write_nodes = self.extended_widget.getSelectedWriteNodes() write_nodes_args = "-X %s" % (",".join(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
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
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
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
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() project_arg = "-proj %s" % file_utils.quote_path(workspace) if workspace.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