def execute(self, operation, file_path, **kwargs):
        """
        Main hook entry point
        
        :operation: String
                    Scene operation to perform
        
        :file_path: String
                    File path to use if the operation
                    requires it (e.g. open)
                    
        :returns:   Depends on operation:
                    'current_path' - Return the current scene
                                     file path as a String
                    all others     - None
        """

        if operation == "current_path":
            # return the current scene path
            return FarmAPI.GetKatanaFileName()
        elif operation == "open":
            # do new scene as Maya doesn't like opening
            # the scene it currently has open!
            KatanaFile.Load(file_path)
        elif operation == "save":
            current_file = FarmAPI.GetKatanaFileName()
            # save the current scene:
            KatanaFile.Save(current_file)
예제 #2
0
def __tank_on_scene_event_callback(**kwargs):
    """
    Callback that fires every time a file is saved or loaded.

    Carefully manage exceptions here so that a bug in Tank never
    interrupts the normal workflows in Katana.
    """
    # get the new file name
    file_name = FarmAPI.GetKatanaFileName()

    if not file_name:  # New scene
        return

    try:
        # this file could be in another project altogether, so create a new Tank
        # API instance.
        try:
            tk = tank.tank_from_path(file_name)
        except tank.TankError, e:
            __create_tank_disabled_menu(e)
            return

        # try to get current ctx and inherit its values if possible
        curr_ctx = None
        if tank.platform.current_engine():
            curr_ctx = tank.platform.current_engine().context

        # and now extract a new context based on the file
        new_ctx = tk.context_from_path(file_name, curr_ctx)

        # now restart the engine with the new context
        __engine_refresh(tk, new_ctx)
    def kanana_rendernodes(self, task_json):

        katana_scene = FarmAPI.GetKatanaFileName()
        render_info_dict = {}
        render_node_info_dict = {}
        render_nodes = NodegraphAPI.GetAllNodesByType("Render")
        if len(render_nodes) != 0:
            for render_node in render_nodes:
                render_output_dict = {}
                render_frame_dict = {}
                render_names = render_node.getName()
                render_name = render_names
                scene_name = os.path.basename(os.path.basename(katana_scene))
                print ("the render node name is  %s" % render_name)
                num_re = re.compile(r"(\d+_\d+)[\D]*", re.I)

                try:
                    render_node.getParameter("lock").setValue(0, 0)
                    # render_node_info=Nodes3DAPI.RenderNodeUtil.GetRenderNodeInfo(render_node,graphState)
                    render_node_info = Nodes3DAPI.RenderNodeUtil.GetRenderNodeInfo(render_node)

                    for i in xrange(render_node_info.getNumberOfOutputs()):
                        outputInfo = render_node_info.getOutputInfoByIndex(i, forceLocal=False)

                        render_output_name = outputInfo['name']
                        render_output = outputInfo["outputFile"]
                        # print render_output_name,render_output
                        if render_output.find('Temp') > 0:

                            print ("the %s output is %s ,it is tmp ,dont copy" % (render_output_name, render_output))
                        else:
                            render_output_dict[render_output_name] = render_output

                    render_start = render_node.getParameter('farmSettings.activeFrameRange.start').getValue(0)
                    render_end = render_node.getParameter('farmSettings.activeFrameRange.end').getValue(0)

                    render_frame_dict["start"] = render_start
                    render_frame_dict["end"] = render_end
                    render_info_dict[render_name] = {}
                    render_info_dict[render_name]["aov"] = {}
                    render_info_dict[render_name]["aov"] = render_output_dict
                    try:
                        render_TimeRange = render_node.getParameter('farmSettings.TimeRange').getValue(0)
                        render_info_dict[render_name]["frames"] = "%s[%s]" % (render_TimeRange, 1)
                    except:
                        render_info_dict[render_name]["frames"] = "%s-%s[%s]" % (int(render_start), int(render_end), 1)
                    render_info_dict[render_name]["denoise"] = "0"
                    render_info_dict[render_name]["renderable"] = "1"

                except Exception as err:
                    print (err)
                    print ("the bad render node name is   %s" % render_name)
                    pass

            render_node_info_dict["rendernodes"] = render_info_dict
            self.write_json_info(task_json, "scene_info", render_node_info_dict)
예제 #4
0
def _session_path():
    """
    Return the path to the current session
    :return:
    """
    path = FarmAPI.GetKatanaFileName()

    if isinstance(path, unicode):
        path = path.encode("utf-8")

    return path
예제 #5
0
def _save_as():

    project_path = os.path.dirname(FarmAPI.GetKatanaFileName())
    path = UI4.Util.AssetId.BrowseForAsset(path, 'Select Katana File', False,
                                           {'fileTypes': 'katana'})
    # make sure not using unicode!
    if isinstance(path, unicode):
        path = path.encode("utf-8")

    if path:
        KatanaFile.Save(path)
예제 #6
0
    def execute(self, **kwargs):
        """
        Main hook entry point
        :returns:       A list of any items that were found to be published.  
                        Each item in the list should be a dictionary containing 
                        the following keys:
                        {
                            type:   String
                                    This should match a scene_item_type defined in
                                    one of the outputs in the configuration and is 
                                    used to determine the outputs that should be 
                                    published for the item
                                    
                            name:   String
                                    Name to use for the item in the UI
                            
                            description:    String
                                            Description of the item to use in the UI
                                            
                            selected:       Bool
                                            Initial selected state of item in the UI.  
                                            Items are selected by default.
                                            
                            required:       Bool
                                            Required state of item in the UI.  If True then
                                            item will not be deselectable.  Items are not
                                            required by default.
                                            
                            other_params:   Dictionary
                                            Optional dictionary that will be passed to the
                                            pre-publish and publish hooks
                        }
        """

        items = []

        # get the main scene:
        scene_name = FarmAPI.GetKatanaFileName()
        if not scene_name:
            raise TankError("Please Save your file before Publishing")

        scene_path = os.path.abspath(scene_name)
        name = os.path.basename(scene_path)

        # create the primary item - this will match the primary output 'scene_item_type':
        items.append({"type": "work_file", "name": name})

        #        # if there is any geometry in the scene (poly meshes or nurbs patches), then
        #        # add a geometry item to the list:
        #        if cmds.ls(geometry=True, noIntermediate=True):
        #            items.append({"type":"geometry", "name":"All Scene Geometry"})

        return items
예제 #7
0
def add_new_cp_uv():
    node=cku.get_lgt_shot_maker_node()
    if cku.get_node_children_by_name(node,'CopyUv_\d*$') or \
        cku.get_node_children_by_name(node,'CopyUV_\d*$'):
        return

    old_cp=cku.get_node_children_by_name(node,'CopyUv_Ani_Srf_\d*',operation=lambda x:x.setBypassed(True))
    if old_cp:
        new_cp_op=cku.replace_me_with(old_cp[0], new_node='CopyUV_Lc', bypass_old_node=True)
        if new_cp_op:
            print '\n\nAdd new copy uv op node to fix srf v000 transfering uv bug.\n\n'
            new_cp_op.setName('CopyUV_')
            KatanaFile.Save(FarmAPI.GetKatanaFileName())
예제 #8
0
def checkFileNaming():
    # check file naming correctness
    file_path = FarmAPI.GetKatanaFileName()
    file_base, file_name = os.path.split(file_path)

    # LGT katana file
    lgt_naming_pattern = '([a-z][0-9]*)(\.[a-z]*)(\.[a-z]*)(\.v[0-9]*)\.katana'
    result = re.match(lgt_naming_pattern, file_name)
    if result == None:
        return -1
    elif file_name.split('.')[2] != 'lighting':
        return -1
    else:
        return 0
예제 #9
0
    def execute(self, work_template, primary_task, secondary_tasks, progress_cb, **kwargs):
        """
        Main hook entry point
        
        :param work_template:   template
                                This is the template defined in the config that
                                represents the current work file

        :param primary_task:    The primary task that was published by the primary publish hook.  Passed
                                in here for reference.

        :param secondary_tasks: The list of secondary tasks that were published by the secondary 
                                publish hook.  Passed in here for reference.
                        
        :param progress_cb:     Function
                                A progress callback to log progress during pre-publish.  Call:
                        
                                    progress_cb(percentage, msg)
                             
                                to report progress to the UI

        :returns:               None
        :raises:                Raise a TankError to notify the user of a problem
        """
        # get the engine name from the parent object (app/engine/etc.)
        engine_name = self.parent.engine.name
        
        progress_cb(0, "Versioning up the scene file")
        
        # get the current scene path:
        scene_path = os.path.abspath(FarmAPI.GetKatanaFileName())
        
        # increment version and construct new file name:
        progress_cb(25, "Finding next version number")
        fields = work_template.get_fields(scene_path)
        next_version = self._get_next_work_file_version(work_template, fields)
        fields["version"] = next_version 
        new_scene_path = work_template.apply_fields(fields)
        
        # log info
        self.parent.log_debug("Version up work file %s --> %s..." % (scene_path, new_scene_path))
        
        # rename and save the file
        progress_cb(50, "Saving the scene file")
        KatanaFile.Save(new_scene_path)
        
        progress_cb(100)
예제 #10
0
 def submit_to_farm(self):
     sg = Connection('get_project_info').get_sg()
     file_path = FarmAPI.GetKatanaFileName()
     file_name = os.path.basename(file_path)
     userdata = getUserFullFromDB()
     muster_connection = MusterSubmit(userdata)
     shot_name = file_name.split('.')[0]
     listOfJobsToSubmit = []
     #~ this map would write the render node which one need to render single frame with frame number dowm!
     aSingleFrameNodeMap = {}
     # copy tmp file
     base_dir = os.path.dirname(file_path).replace('/work/', '/projcache/')
     user_tmp = os.path.join(base_dir, getpass.getuser() + '_tmp')
     try:
         #katanafile='/mnt/work/home/wangbin/Wb2015/CodeWork/lgtsmp/test.katana'
         self.passedLgtShotSimplifyNode()
     except Exception, e:
         print e
예제 #11
0
    def _render(self):
        import os

        file_name = FarmAPI.GetKatanaFileName()

        #tmp_file = os.path.join("/tmp",file_name.split("/")[-1])
        #KatanaFile.Save(tmp_file)

        if os.environ['REZ_KATANA_VERSION'] == "3.1v2":
            command = [
                'mate-terminal', '-x', 'rez-env', 'katana-3.1v2',
                'renderman-22', 'usd-19.03', "yeti", '--', 'katana'
            ]
        else:
            command = [
                'mate-terminal', '-x', 'rez-env', 'katana-2.6v4',
                'renderman-21.8', 'usd-19.03', 'yeti-2.2.9', '--', 'katana'
            ]

        temp_file = self._get_temp_file(str(file_name))
        if not os.path.exists(os.path.dirname(temp_file)):
            os.makedirs(os.path.dirname(temp_file))
        status = shutil.copyfile(file_name, temp_file)

        for node in self.selected_nodes:

            command.append("--batch")
            command.append("--katana-file=%s" % temp_file)
            command.append("--render-node=%s" % node.getName())
            command.append(
                str('--t=%s-%s' %
                    (self.ui.start_frame.text(), self.ui.end_frame.text())))

            print command

            subprocess.Popen(command)
        self.close()
        return
예제 #12
0
def onCheckLgtShotStatus():
    from shotgun_connection import Connection
    file_path = FarmAPI.GetKatanaFileName()
    file_name = os.path.basename(file_path)
    shot = file_name.split(".")[0]
    job_filters = [
        ['project', 'name_is', 'cat'],
        ['entity', 'type_is', 'Shot'],
        ['entity.Shot.code', 'is', str(shot)],
        ['step', 'name_is', 'lgt']
    ]
    job_fields = [
        'entity.Shot.code',
        'step',
        'sg_status_list'
    ]
    sg = Connection('get_project_info').get_sg()
    task = sg.find_one("Task", job_filters, job_fields)
    Status = task['sg_status_list']
    if Status in ['ip','aaa','rtk']:
        return True
    else:
        return False
예제 #13
0
def _GenerateFarmFile(nodeList, fileName):
    sortedDependencies = FarmAPI.GetSortedDependencies(nodeList)
    katanaFile = FarmAPI.GetKatanaFileName()

    # Generate XML
    _GenerateXML(fileName, sortedDependencies, katanaFile)
예제 #14
0
    def _get_version(self):

        file_name = FarmAPI.GetKatanaFileName()
        return int(filter(str.isdigit, re.search("v\d+", file_name).group()))
예제 #15
0
def _save_as():
    scene_path = FarmAPI.GetKatanaFileName()
    KatanaFile.Save( scene_path )
예제 #16
0
    def collect_current_katana_session(self, settings, parent_item):
        """
        Creates an item that represents the current maya session.

        :param parent_item: Parent Item instance

        :returns: Item of type maya.session
        """

        publisher = self.parent

        # get the path to the current file
        path = FarmAPI.GetKatanaFileName()

        # determine the display name for the item
        if path:
            file_info = publisher.util.get_file_path_components(path)
            display_name = file_info["filename"]
        else:
            display_name = "Current Katana Session"

        # create the session item for the publish hierarchy
        session_item = parent_item.create_item(
            "katana.session",
            "Katana Session",
            display_name
        )

        # get the icon path to display for this item
        icon_path = os.path.join(
            self.disk_location,
            os.pardir,
            "icons",
            "maya.png"
        )
        session_item.set_icon_from_path(icon_path)

        # discover the project root which helps in discovery of other
        # publishable items
        project_root = os.path.dirname(FarmAPI.GetKatanaFileName())
        session_item.properties["project_root"] = project_root

        # if a work template is defined, add it to the item properties so
        # that it can be used by attached publish plugins
        work_template_setting = settings.get("Work Template")
        if work_template_setting:

            work_template = publisher.engine.get_template_by_name(
                work_template_setting.value)

            # store the template on the item for use by publish plugins. we
            # can't evaluate the fields here because there's no guarantee the
            # current session path won't change once the item has been created.
            # the attached publish plugins will need to resolve the fields at
            # execution time.
            session_item.properties["work_template"] = work_template
            self.logger.debug("Work template defined for Maya collection.")

        self.logger.info("Collected current Maya scene")

        return session_item
    def execute(self, task, work_template, comment, thumbnail_path, sg_task,
                progress_cb, **kwargs):
        """
        Main hook entry point
        :param task:            Primary task to be published.  This is a
                                dictionary containing the following keys:
                                {   
                                    item:   Dictionary
                                            This is the item returned by the scan hook 
                                            {   
                                                name:           String
                                                description:    String
                                                type:           String
                                                other_params:   Dictionary
                                            }
                                           
                                    output: Dictionary
                                            This is the output as defined in the configuration - the 
                                            primary output will always be named 'primary' 
                                            {
                                                name:             String
                                                publish_template: template
                                                tank_type:        String
                                            }
                                }
                        
        :param work_template:   template
                                This is the template defined in the config that
                                represents the current work file
               
        :param comment:         String
                                The comment provided for the publish
                        
        :param thumbnail:       Path string
                                The default thumbnail provided for the publish
                        
        :param sg_task:         Dictionary (shotgun entity description)
                                The shotgun task to use for the publish    
                        
        :param progress_cb:     Function
                                A progress callback to log progress during pre-publish.  Call:
                                
                                    progress_cb(percentage, msg)
                                     
                                to report progress to the UI
        
        :returns:               Path String
                                Hook should return the path of the primary publish so that it
                                can be passed as a dependency to all secondary publishes
                
        :raises:                Hook should raise a TankError if publish of the 
                                primary task fails
        """
        # TODO: This may not be the best choice of function, as it returns an Asset ID.
        #       When using the default Asset manager (file path) it'll work, though.
        scene_path = FarmAPI.GetKatanaFileName()

        # Find dependendies (TODO)
        dependencies = []  # This should be a list of file paths, I think

        # use templates to convert to publish path:
        output = task["output"]
        fields = work_template.get_fields(scene_path)
        fields["TankType"] = output["tank_type"]
        publish_template = output["publish_template"]
        publish_path = publish_template.apply_fields(fields)

        if os.path.exists(publish_path):
            raise TankError("The published file named '%s' already exists!" %
                            publish_path)

        # save the scene:
        progress_cb(10.0, "Saving the scene")
        self.parent.log_debug("Saving the scene...")
        KatanaFile.Save(scene_path)

        # copy the file:
        progress_cb(50.0, "Copying the file")
        try:
            publish_folder = os.path.dirname(publish_path)
            self.parent.ensure_folder_exists(publish_folder)
            self.parent.log_debug("Copying %s --> %s..." %
                                  (scene_path, publish_path))
            self.parent.copy_file(scene_path, publish_path, task)
        except Exception, e:
            raise TankError("Failed to copy file from %s to %s - %s" %
                            (scene_path, publish_path, e))
예제 #18
0
def PopulateSubmitter(gui):
    """
    This function populates an instance of DeadlineTab with the UI controls that make up the submission dialog.
    This tab is instantiated by Katana every time the user selects "Tabs -> Thinkbox -> Submit to Deadline" from the
    menu bar in Katana.

    Essentially, this function serves as a deferred __init__ implementation for the tab class that can be easily updated
    via the Deadline repository.

    :param gui: An instance of DeadlineTab from the Client folder. The instance gets created upon selecting the
                "Deadline" tab option in Katana. The tab class itself is defined in the Client file (deployed to
                localappdata/.../katanasubmitter/tabs directory) and is a skeleton class that invokes this
                function to populate the tab with UI controls and assign them to attributes of the tab instance.
    """
    global submissionInfo
    print("Grabbing submitter info...")
    try:
        stringSubInfo = CallDeadlineCommand([
            "-prettyJSON",
            "-GetSubmissionInfo",
            "Pools",
            "Groups",
            "MaxPriority",
            "UserHomeDir",
            "RepoDir:submission/Katana/Main",
            "RepoDir:submission/Integration/Main",
        ],
                                            useDeadlineBg=True)
        output = json.loads(stringSubInfo, encoding="utf-8")
    except:
        print("Unable to get submitter info from Deadline:\n\n" +
              traceback.format_exc())
        raise
    if output["ok"]:
        submissionInfo = output["result"]
    else:
        print(
            "DeadlineCommand returned a bad result and was unable to grab the submitter info.\n\n"
            + output["result"])
        raise ValueError(output["result"])
    # Create a widget with a vertical box layout as a container for widgets to include in the tab
    scrollWidget = QWidget()
    scrollLayout = QGridLayout(scrollWidget)
    scrollLayout.setSpacing(4)
    scrollLayout.setContentsMargins(4, 4, 4, 4)

    buttonLayout = QHBoxLayout()

    # First layout: General options
    scrollLayout.addWidget(CreateSeparator("Job Description"), 0, 0, 1, 3)

    jobNameLabel = QLabel("Job Name")
    jobNameLabel.setToolTip(
        "The name of your job. This is optional, and if left blank, it will default to 'Untitled'."
    )
    scrollLayout.addWidget(jobNameLabel, 1, 0)
    gui.jobNameWidget = QLineEdit(
        os.path.basename(FarmAPI.GetKatanaFileName()).split('.')[0])
    scrollLayout.addWidget(gui.jobNameWidget, 1, 1, 1, 1)

    commentLabel = QLabel("Comment")
    commentLabel.setToolTip(
        "A simple description of your job. This is optional and can be left blank."
    )
    scrollLayout.addWidget(commentLabel, 2, 0)
    gui.commentWidget = QLineEdit("")
    scrollLayout.addWidget(gui.commentWidget, 2, 1, 1, 1)

    departmentLabel = QLabel("Department")
    departmentLabel.setToolTip(
        "The department you belong to. This is optional and can be left blank."
    )
    scrollLayout.addWidget(departmentLabel, 3, 0)
    gui.departmentWidget = QLineEdit("")
    scrollLayout.addWidget(gui.departmentWidget, 3, 1, 1, 1)

    # Second layout: Job options
    scrollLayout.addWidget(CreateSeparator("Job Options"), 4, 0, 1, 3)

    pools = submissionInfo["Pools"]
    poolLabel = QLabel("Pool")
    poolLabel.setToolTip("The pool that your job will be submitted to.")
    scrollLayout.addWidget(poolLabel, 5, 0)

    gui.poolsWidget = QComboBox()
    gui.poolsWidget.addItems(pools)
    scrollLayout.addWidget(gui.poolsWidget, 5, 1)

    secondPoolLabel = QLabel("Secondary Pool")
    secondPoolLabel.setToolTip(
        "The secondary pool lets you specify a pool to use if the primary pool does not have any available Slaves."
    )
    scrollLayout.addWidget(secondPoolLabel, 6, 0)

    gui.secondPoolsWidget = QComboBox()
    gui.secondPoolsWidget.addItems(pools)
    scrollLayout.addWidget(gui.secondPoolsWidget, 6, 1)

    groups = submissionInfo["Groups"]
    groupLabel = QLabel("Group")
    groupLabel.setToolTip("The group that your job will be submitted to.")
    scrollLayout.addWidget(groupLabel, 7, 0)

    gui.groupWidget = QComboBox()
    gui.groupWidget.addItems(groups)
    scrollLayout.addWidget(gui.groupWidget, 7, 1)

    priorityLabel = QLabel("Priority")
    priorityLabel.setToolTip(
        "A job can have a numeric priority from 0 to 100, where 0 is the lowest priority and 100 is the highest."
    )
    scrollLayout.addWidget(priorityLabel, 8, 0)

    maxPriority = submissionInfo["MaxPriority"]

    gui.priorityBox = QSpinBox()
    gui.priorityBox.setMinimum(0)
    gui.priorityBox.setMaximum(maxPriority)
    scrollLayout.addWidget(gui.priorityBox, 8, 1)

    taskTimeoutLabel = QLabel("Task Timeout")
    taskTimeoutLabel.setToolTip(
        "The number of minutes a Slave has to render a task for this job before it requeues it. Specify 0 for no limit."
    )
    scrollLayout.addWidget(taskTimeoutLabel, 9, 0)

    gui.taskTimeoutBox = QSpinBox()
    gui.taskTimeoutBox.setMinimum(0)
    gui.taskTimeoutBox.setMaximum(10000)
    scrollLayout.addWidget(gui.taskTimeoutBox, 9, 1)

    concurrentTasksLabel = QLabel("Concurrent Tasks")
    concurrentTasksLabel.setToolTip(
        "The number of tasks that can render concurrently on a single Slave. This is useful if the rendering application only uses one thread to render and your Slaves have multiple CPUs."
    )
    scrollLayout.addWidget(concurrentTasksLabel, 10, 0)
    gui.concurrentTasksWidget = QSpinBox()
    scrollLayout.addWidget(gui.concurrentTasksWidget, 10, 1)
    gui.concurrentTasksWidget.setMinimum(1)
    gui.concurrentTasksWidget.setMaximum(16)
    gui.limitTasksSlaveLimit = QCheckBox("Limit Tasks To Slave's Task Limit")
    gui.limitTasksSlaveLimit.setToolTip(
        "If you limit the tasks to a Slave's task limit, then by default, the Slave won't dequeue more tasks then it has CPUs. This task limit can be overridden for individual Slaves by an administrator."
    )
    scrollLayout.addWidget(gui.limitTasksSlaveLimit, 10, 2)

    machineLimitLabel = QLabel("Machine Limit")
    machineLimitLabel.setToolTip(
        "Use the Machine Limit to specify the maximum number of machines that can render your job at one time. Specify 0 for no limit."
    )
    scrollLayout.addWidget(machineLimitLabel, 11, 0)

    gui.machineLimitWidget = QSpinBox()
    scrollLayout.addWidget(gui.machineLimitWidget, 11, 1)
    gui.isBlackListWidget = QCheckBox("Machine List Is Blacklist")
    gui.isBlackListWidget.setToolTip(
        "You can force the job to render on specific machines by using a whitelist, or you can avoid specific machines by using a blacklist."
    )
    scrollLayout.addWidget(gui.isBlackListWidget, 11, 2)

    machineListLabel = QLabel("Machine List")
    machineListLabel.setToolTip(
        "The whitelisted or blacklisted list of machines.")
    scrollLayout.addWidget(machineListLabel, 12, 0)

    machineListLayout = QHBoxLayout()
    gui.machineListWidget = QLineEdit("")
    machineListLayout.addWidget(gui.machineListWidget)
    getMachineListWidget = QPushButton("...")
    getMachineListWidget.pressed.connect(
        lambda: BrowseMachineList(gui.machineListWidget))
    machineListLayout.addWidget(getMachineListWidget)
    scrollLayout.addLayout(machineListLayout, 12, 1, 1, 2)

    limitsLabel = QLabel("Limits")
    limitsLabel.setToolTip("The Limits that your job requires.")
    scrollLayout.addWidget(limitsLabel, 13, 0)
    limitsLayout = QHBoxLayout()
    gui.limitsWidget = QLineEdit("")
    limitsLayout.addWidget(gui.limitsWidget)
    getLimitsWidget = QPushButton("...")
    getLimitsWidget.pressed.connect(lambda: BrowseLimitList(gui.limitsWidget))
    limitsLayout.addWidget(getLimitsWidget)
    scrollLayout.addLayout(limitsLayout, 13, 1, 1, 2)

    dependenciesLabel = QLabel("Dependencies")
    dependenciesLabel.setToolTip(
        "Specify existing jobs that this job will be dependent on. This job will not start until the specified dependencies finish rendering."
    )
    scrollLayout.addWidget(dependenciesLabel, 14, 0)
    dependenciesLayout = QHBoxLayout()
    gui.dependenciesWidget = QLineEdit("")
    dependenciesLayout.addWidget(gui.dependenciesWidget)
    getDependenciesWidget = QPushButton("...")
    getDependenciesWidget.pressed.connect(
        lambda: BrowseDependencyList(gui.dependenciesWidget))
    dependenciesLayout.addWidget(getDependenciesWidget)
    scrollLayout.addLayout(dependenciesLayout, 14, 1, 1, 2)

    onJobCompleteLabel = QLabel("On Job Complete")
    onJobCompleteLabel.setToolTip(
        "If desired, you can automatically archive or delete the job when it completes."
    )
    scrollLayout.addWidget(onJobCompleteLabel, 15, 0)
    gui.onJobCompleteWidget = QComboBox()
    gui.onJobCompleteWidget.addItems(["Nothing", "Archive", "Delete"])
    scrollLayout.addWidget(gui.onJobCompleteWidget, 15, 1)
    gui.submitSuspendedWidget = QCheckBox("Submit Job as Suspended")
    gui.submitSuspendedWidget.setToolTip(
        "If enabled, the job will submit in the suspended state. This is useful if you don't want the job to start rendering right away. Just resume it from the Monitor when you want it to render."
    )
    scrollLayout.addWidget(gui.submitSuspendedWidget, 15, 2)

    # Third layout: Katana options
    scrollLayout.addWidget(CreateSeparator("Katana Options"), 16, 0, 1, 3)

    frameRangeLabel = QLabel("Frame Range")
    frameRangeLabel.setToolTip("The list of frames to render.")
    scrollLayout.addWidget(frameRangeLabel, 17, 0)
    gui.frameRangeWidget = QLineEdit("")  # Populate based on frame range
    scrollLayout.addWidget(gui.frameRangeWidget, 17, 1, 1, 1)

    frameRange = FarmAPI.GetSceneFrameRange()
    gui.frameRangeWidget.setText(
        str(frameRange['start']) + "-" + str(frameRange['end']))

    gui.submitSceneBox = QCheckBox("Submit Katana Scene File")
    gui.submitSceneBox.setToolTip(
        "If this option is enabled, the scene file will be submitted with the job, and then copied locally to the Slave machine during rendering."
    )
    scrollLayout.addWidget(gui.submitSceneBox, 17, 2)

    framesPerTaskLabel = QLabel("Frames Per Task")
    framesPerTaskLabel.setToolTip(
        "This is the number of frames that will be rendered at a time for each job task."
    )
    scrollLayout.addWidget(framesPerTaskLabel, 18, 0)
    gui.framesPerTaskWidget = QSpinBox()
    gui.framesPerTaskWidget.setMinimum(1)
    scrollLayout.addWidget(gui.framesPerTaskWidget, 18, 1, 1, 1)

    gui.useWorkingDirectory = QCheckBox("Use Working Directory")
    gui.useWorkingDirectory.setToolTip(
        "If enabled, the current working directory will be used during rendering. This is required if your Katana project file contains relative paths."
    )
    gui.useWorkingDirectory.setChecked(True)
    scrollLayout.addWidget(gui.useWorkingDirectory, 18, 2)

    renderNodeSelectLabel = QLabel("Render Node Submission")
    renderNodeSelectLabel.setToolTip(
        "Choose to render the whole scene, render all nodes as separate jobs, or render separate nodes"
    )
    scrollLayout.addWidget(renderNodeSelectLabel, 19, 0)

    gui.renderSelectBox = QComboBox()
    gui.renderSelectBox.addItems(
        ["Submit All Render Nodes As Separate Jobs", "Select Render Node"])
    scrollLayout.addWidget(gui.renderSelectBox, 19, 1)

    gui.includeImageWrite = QCheckBox("Include ImageWrite Nodes")
    gui.includeImageWrite.setToolTip(
        "If enabled, ImageWrite nodes will be included for submission.")
    scrollLayout.addWidget(gui.includeImageWrite, 19, 2)

    renderNodeLabel = QLabel("Render Node")
    renderNodeLabel.setToolTip(
        "Set the render node to render with, or leave blank to use the node already set."
    )
    scrollLayout.addWidget(renderNodeLabel, 20, 0)

    gui.frameDependent = QCheckBox("Submit Jobs As Frame Dependent")
    gui.frameDependent.setToolTip(
        "If enabled, the Katana Job(s) will have Frame Dependencies. If your scene contains static content, do not use!"
    )
    scrollLayout.addWidget(gui.frameDependent, 20, 2)

    gui.renderNodeBox = QComboBox()
    gui.renderSelectBox.currentIndexChanged.connect(
        lambda: RenderSelectionChanged(gui.renderSelectBox, gui.renderNodeBox))
    scrollLayout.addWidget(gui.renderNodeBox, 20, 1)
    gui.renderNodeBox.setDisabled(True)
    # Submit button
    buttonLayoutSpacer = QSpacerItem(0, 0, QSizePolicy.MinimumExpanding,
                                     QSizePolicy.Minimum)
    buttonLayout.addItem(buttonLayoutSpacer)

    gui.pipelineToolStatusLabel = QLabel("No Pipeline Tools Set")
    gui.pipelineToolStatusLabel.setAlignment(QtCore.Qt.AlignCenter)
    buttonLayout.addWidget(gui.pipelineToolStatusLabel)
    pipelineToolsButton = QPushButton("Pipeline Tools")
    pipelineToolsButton.pressed.connect(lambda: PipelineToolsClicked(gui))
    buttonLayout.addWidget(pipelineToolsButton)

    submitButton = QPushButton("Submit")
    submitButton.pressed.connect(lambda: SubmitPressed(gui))
    buttonLayout.addWidget(submitButton)

    scrollLayout.addLayout(buttonLayout, 21, 0, 1, 3)

    verticalStretchLayout = QVBoxLayout()
    verticalStretchLayout.addStretch()
    scrollLayout.addLayout(verticalStretchLayout, 22, 0)

    scrollArea = QScrollArea()
    scrollArea.setWidget(scrollWidget)
    scrollArea.setWidgetResizable(True)
    scrollArea.setFrameStyle(QFrame.NoFrame + QFrame.Plain)

    vLayout = QVBoxLayout()
    vLayout.setObjectName('vLayout')
    vLayout.addWidget(scrollArea)

    gui.setLayout(vLayout)

    LoadStickySettings(gui)
    try:
        pipelineToolStatusMessage = RetrievePipelineToolStatus(
            raiseOnExitCode=True)
    except subprocess.CalledProcessError as e:
        pipelineToolStatusMessage = HandlePipelineToolsCalledProcessError(e)
    UpdatePipelineToolStatusLabel(gui, pipelineToolStatusMessage)

    # Populate the render node drop down based on the effective check state
    # of the "Include ImageWrite Nodes" checkbox after sticky settings are applied
    PopulateRenderNodeDropDown(gui.includeImageWrite.isChecked(),
                               gui.renderNodeBox)
    # We delay wiring up this signal handler until after the sticky settings are applied to avoid
    # rebuilding the drop-down list multiple times unnecessarily
    gui.includeImageWrite.stateChanged.connect(
        lambda checked: PopulateRenderNodeDropDown(checked, gui.renderNodeBox))

    # Check if this tab is part of a pane in the main window, or if it is contained in a floating pane
    if gui.window() != UI4.App.MainWindow.CurrentMainWindow():
        # Resize the floating pane's window to accommodate the tab's widgets
        requiredSize = scrollWidget.sizeHint()
        gui.window().resize(max(requiredSize.width() + 20, 200),
                            min(requiredSize.height() + 40, 1000))
예제 #19
0
def initExport(option):
    dependencyList = FarmAPI.GetSortedDependencyList()[0]
    filepath = FarmAPI.GetKatanaFileName()

    # TODO - validity check
    saved = FarmAPI.IsSceneValid(FarmAPI.NODES_ALL)
    if not saved:
        # errormsg = FarmAPI.GetErrorMessages()
        result = UI4.Widgets.MessageBox.Warning('Unsaved Changes',
                                                'Save your file',
                                                acceptText='Save',
                                                cancelText='Cancel')
        if result == 0:  # Save
            KatanaFile.Save(filepath)
        else:  # cancel
            return

    # TODO - Get Katana version
    katanaVersion = "2.54"
    rendererVersion = "21.4"

    # get renderservice
    renderer = dependencyList['service']

    requ_lics = ''
    if renderer == 'arnold':
        rendererVersion = RenderingAPI.RendererInfo.GetPlugin(
            'ArnoldRendererInfo').getRegisteredRendererVersion()
        extension = '.ass'
        requ_lics += 'Arnold;'
    elif renderer == 'prman':
        rendererVersion = RenderingAPI.RendererInfo.GetPlugin(
            'PRManRendererInfo').getRegisteredRendererVersion()
        renderer = 'RenderMan'
        extension = '.rib'
        requ_lics += 'RenderMan;'
    else:
        UI4.Widgets.MessageBox.Warning('Unsupported Renderer',
                                       'Unknown Renderer')
        return

    use_yeti = dependencyList['useYetiLic']
    if use_yeti:
        requ_lics += "Yeti"

    software = 'Katana'
    software = 'Katana'
    if option == 'local':
        software = renderer

    #  print 'dependency list ', dependencyList
    fileDir = dependencyList['outputFolder']
    #  print 'FILEDDIR ', fileDir
    fileName = dependencyList['fileName']
    if fileName == '':
        UI4.Widgets.MessageBox.Warning('Warning', 'Add a name parameter')
        return

    # tmp name for xml and katana farm file
    xmlFileName = getNewTempFileName(fileDir, fileName)
    tmpFile = open(xmlFileName, 'w')
    dst = tmpFile.name[:-4] + '.katana'
    comment_file = tmpFile.name[:-4] + '_comment.txt'

    comment = ''
    use_comment = dependencyList['useComment']
    if use_comment:
        comment = dependencyList['comment']
        with open(comment_file, 'w') as f:
            f.write(comment)

    if (option == 'local'):
        # check file/dir
        if not os.path.isdir(fileDir):
            if UI4.Widgets.MessageBox.Warning('Warning',
                                              'Directory does not exist.\n' +
                                              fileDir + '\n\nCreate it?',
                                              acceptText='Yes',
                                              cancelText='No'):
                return
            else:
                os.mkdir(fileDir)
        sceneName = os.path.join(fileDir, fileName) + '_<FN4>' + extension
    else:
        sceneName = dst
        #  sceneName = FarmAPI.GetKatanaFileName()

    # check framerange
    framerange = dependencyList['range']
    if framerange is None:
        UI4.Widgets.MessageBox.Warning('Warning', 'Add a valid framerange')
        return
    startframe = int(framerange[0])
    endframe = int(framerange[1])
    if endframe <= startframe:
        UI4.Widgets.MessageBox.Warning('Warning', 'Add a valid framerange')
        return

    # distribution check
    threadCount = int(dependencyList['useThreads'])
    if threadCount <= 0:
        UI4.Widgets.MessageBox.Warning('Warning',
                                       'You must use at least one thread')
        return
    availableThreads = multiprocessing.cpu_count()
    if (threadCount > availableThreads) and (option == 'local'):
        UI4.Widgets.MessageBox.Warning(
            'Warning',
            'Your machine is restricted to max.' + str(availableThreads))
        return
    packageSize = int(dependencyList['packageSize'])
    if packageSize <= 0:
        UI4.Widgets.MessageBox.Warning('Warning', 'Add a valid packageSize')
        return

    # denoiser post script flags
    if int(dependencyList['useRendermanDenoiserPostScript']) == 1:
        filter = dependencyList['denoiseFilter']
        filter_cmd = 'denoise -v variance -f {}'.format(filter)
        if dependencyList['useFilterOverride']:
            filter_override = dependencyList['denoiseFilterOverride']
            for override in filter_override:
                filter_cmd += '+{}'.format(override)

    # create job
    newJob = rrJob()

    if (option == 'local'):
        newJob.version = rendererVersion
    else:
        newJob.version = katanaVersion
    newJob.rendererVersionName = renderer
    newJob.rendererVersion = rendererVersion
    newJob.software = software
    newJob.renderer = renderer
    newJob.RequiredLicenses = requ_lics  #"Yeti"  # TODO
    newJob.sceneName = sceneName
    newJob.sceneDatabaseDir = ""
    newJob.seqStart = startframe
    newJob.seqEnd = endframe
    newJob.seqStep = dependencyList['stepSize']  # TODO - get dynamic
    newJob.seqFileOffset = 0
    newJob.seqFrameSet = ""
    newJob.imageWidth = 99  # TODO - get dynamic
    newJob.imageHeight = 99
    newJob.imageDir = fileDir
    newJob.imageFileName = fileName + '_####_variance.exr'
    newJob.imageFramePadding = 4  # TODO - get dynamic
    newJob.imageExtension = ""  # ".exr"  # TODO get dynamic
    newJob.imagePreNumberLetter = ""
    newJob.imageSingleOutput = False
    newJob.imageStereoR = ""
    newJob.imageStereoL = ""
    newJob.sceneOS = getOSString()  # TODO - get dynamic
    newJob.camera = ""
    newJob.layer = dependencyList['name']
    newJob.channel = ""
    newJob.maxChannels = 0
    newJob.channelFileName = []
    newJob.channelExtension = []
    newJob.isActive = False
    newJob.sendAppBit = ""
    newJob.preID = ""
    newJob.waitForPreID = ""
    if dependencyList['useRendermanDenoiserPostScript']:
        newJob.CustomA = filter_cmd
    else:
        newJob.CustomA = ""
    newJob.CustomB = "comment: {}".format(comment)
    newJob.CustomC = ""
    newJob.LocalTexturesFile = ""
    newJob.rrSubmitVersion = "%rrVersion%"
    newJob.packageSize = packageSize
    newJob.threadCount = threadCount
    newJob.renderNode = dependencyList['name']

    # write xml file
    root = newJob.writeToXMLstart(None)
    job = newJob.writeToXMLJob(root)
    newJob.writeToXMLEnd(tmpFile, root)

    # copy katanna recipie
    shutil.copy(filepath, dst)

    # submit job
    if option == 'local':
        # start control session for local conversion
        scriptDir = os.path.dirname(os.path.realpath(__file__))
        sessionScript = os.path.join(scriptDir, 'session/ControlSessions.py')
        subp = subprocess.Popen(['python', sessionScript, tmpFile.name, dst],
                                close_fds=True,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)

    elif option == 'farm':
        os.system(getRRSubmitterPath() + "  \"" + xmlFileName + "\"")
예제 #20
0
 def after_call(self):
     from Katana import FarmAPI
     import production.functiming as functiming
     self.func_file = FarmAPI.GetKatanaFileName()
     functiming.ShotgunTimerEnv.after_call(self)
예제 #21
0
    def kanana_rendernodes(self, task_json):

        katana_scene = FarmAPI.GetKatanaFileName()
        render_info_dict = {}
        render_node_info_dict = {}
        render_nodes = NodegraphAPI.GetAllNodesByType("Render")
        #graphState = NodegraphAPI.GetCurrentGraphState()
        #render_node = NodegraphAPI.GetNode("825_100_r1_envir_Din_Apt_Curtain_BTY")
        if len(render_nodes) != 0:
            for render_node in render_nodes:
                render_output_dict = {}
                render_frame_dict = {}
                render_names = render_node.getName()
                render_name = render_names
                #print render_node.getParameters().getXML()
                scene_name = os.path.basename(os.path.basename(katana_scene))
                print("the render node name is  %s" % render_name)
                num_re = re.compile(r"(\d+_\d+)[\D]*", re.I)
                if num_re.findall(scene_name):
                    scene_num = num_re.findall(scene_name)[0]

                    if scene_num in render_name and not render_node.isBypassed(
                    ) and not render_name.endswith(
                            "_pass") and not render_name.endswith("1"):
                        try:
                            render_node.getParameter("lock").setValue(0, 0)
                            #render_node_info=Nodes3DAPI.RenderNodeUtil.GetRenderNodeInfo(render_node,graphState)
                            render_node_info = Nodes3DAPI.RenderNodeUtil.GetRenderNodeInfo(
                                render_node)

                            for i in xrange(
                                    render_node_info.getNumberOfOutputs()):
                                outputInfo = render_node_info.getOutputInfoByIndex(
                                    i, forceLocal=False)

                                render_output_name = outputInfo['name']
                                render_output = outputInfo["outputFile"]
                                #print render_output_name,render_output
                                if render_output.find('Temp') > 0:

                                    print(
                                        "the %s output is %s ,it is tmp ,dont copy"
                                        % (render_output_name, render_output))
                                else:
                                    render_output_dict[
                                        render_output_name] = render_output
                            #print render_output_dict

                            #if render_node.getParameter('farmSettings.setActiveFrameRange').getValue(0)=="Yes":
                            render_start = render_node.getParameter(
                                'farmSettings.activeFrameRange.start'
                            ).getValue(0)
                            render_end = render_node.getParameter(
                                'farmSettings.activeFrameRange.end').getValue(
                                    0)

                            #print range(0,Nodes3DAPI.RenderNodeUtil.GetNumRenderOutputs(render_node))
                            #print Nodes3DAPI.RenderNodeUtil.GetDefaultIncludedOutputs(render_node).keys()
                            render_frame_dict["start"] = render_start
                            render_frame_dict["end"] = render_end
                            #print render_start,render_end
                            #print render_frame_dict
                            render_info_dict[render_name] = {}
                            render_info_dict[render_name]["aov"] = {}
                            render_info_dict[render_name][
                                "aov"] = render_output_dict
                            try:
                                render_TimeRange = render_node.getParameter(
                                    'farmSettings.TimeRange').getValue(0)
                                render_info_dict[render_name][
                                    "frames"] = "%s[%s]" % (render_TimeRange,
                                                            1)
                            except:
                                render_info_dict[render_name][
                                    "frames"] = "%s-%s[%s]" % (
                                        int(render_start), int(render_end), 1)
                            render_info_dict[render_name]["denoise"] = "0"
                            render_info_dict[render_name]["renderable"] = "1"

                            #render_info_dict[render_name]["frames"]=render_frame_dict
                        except Exception as err:
                            print(err)
                            print("the bad render node name is   %s" %
                                  render_name)
                            pass

            render_node_info_dict["rendernodes"] = render_info_dict
            self.write_json_info(task_json, "scene_info",
                                 render_node_info_dict)
예제 #22
0
    def _render_to_farm(self):

        import tractor.api.author as author

        start_frame = int(self.ui.start_frame.text())
        end_frame = int(self.ui.end_frame.text())
        file_name = FarmAPI.GetKatanaFileName()

        temp_file = self._get_temp_file(str(file_name))
        if not os.path.exists(os.path.dirname(temp_file)):
            os.makedirs(os.path.dirname(temp_file))
        status = shutil.copyfile(file_name, temp_file)

        for node in self.selected_nodes:
            job = author.Job()
            #job.title = '[Katana]' + file_name.split(".")[0].split("/")
            job.service = "Linux64"
            job.priority = 50

            file_title = file_name.split(".")[0].split("/")[-1]
            project_name = self._app.context.project['name']
            user_name = self._app.context.user['name']
            user_id = os.environ['USER']
            select_node = str(node.getName())

            temp = "] ["
            title = []
            title.append(user_name)
            title.append(project_name)
            title.append(file_title)
            title.append(select_node)
            title.append("%d - %d" % (start_frame, end_frame))
            title = temp.join(title)
            title = "[" + title + "]"
            job.title = str(title)

            for frame in range(start_frame, end_frame + 1):
                task = author.Task(title=str(frame))

                if os.environ['REZ_KATANA_VERSION'] == "3.1v2":
                    command = [
                        'rez-env', 'katana-3.1v2', 'renderman-22', 'usd-19.03',
                        'yeti', '--', 'katana'
                    ]
                else:
                    command = [
                        'rez-env', 'katana-2.6v4', 'renderman-21.8',
                        'usd-19.03', 'yeti-2.2.9', '--', 'katana'
                    ]
                command.append("--batch")
                command.append("--katana-file=%s" % temp_file)
                command.append("--render-node=%s" % node.getName())
                command.append(str("--t=%d-%d" % (frame, frame)))
                command = author.Command(argv=command)
                task.addCommand(command)
                job.addChild(task)

            job.spool(hostname="10.0.20.82", owner=user_id)

        self.close()
        return
예제 #23
0
 def passedLgtShotSimplifyNode(self):
     lgtsimplifynode=NodegraphAPI.GetNode('LgtShotSimplify_')
     if lgtsimplifynode:
         lgtsimplifynode.setBypassed(True)
         KatanaFile.Save(FarmAPI.GetKatanaFileName())
         print "setBypassed ok"