示例#1
0
def cur_work():
    """Get current workfile.

    Returns:
        (FrasierWork): current work
    """
    return FrasierWork(host.cur_scene())
示例#2
0
def build_shot_from_template(shot, template, force=False):
    """Build a scene from the given template.

    Args:
        shot (str): name of shot to update to (eg. rnd0080)
        template (str): path to template work file
        force (bool): force save new scene with no confirmation
    """
    _shot = tk2.find_shot(shot)
    _tmpl_work = tk2.get_work(template)
    if host.cur_scene() != _tmpl_work.path:
        _tmpl_work.load(force=force)

    # Make sure we're on default render layer
    cmds.editRenderLayerGlobals(currentRenderLayer='defaultRenderLayer')

    _update_assets()
    _update_abcs(shot=shot)

    # Update frame range
    _rng = _shot.get_frame_range()
    print 'RANGE', _rng
    if _rng and _rng != (None, None):
        host.set_range(*_rng)
    else:
        print 'FAILED TO UPDATE TIMELINE'

    # Save scene
    _shot_work = _tmpl_work.map_to(Shot=_shot.name,
                                   Sequence=_shot.sequence).find_next()
    print 'SHOT WORK', _shot_work
    if not force:
        qt.ok_cancel("Save new work file?\n\n" + _shot_work.path)
    _shot_work.save(comment='Scene built by shot_builder')
示例#3
0
def open_scene(file_, force=False, prompt=False, lazy=False, load_refs=True):
    """Open the given scene.

    Args:
        file_ (str): file to open
        force (bool): lose unsaved changes without confirmation
        prompt (bool): show missing reference dialogs
        lazy (bool): abandon load if scene is already open
        load_refs (bool): load references
    """
    from psyhive import host

    _file = get_path(file_)
    if lazy and host.cur_scene() == _file:
        return
    if not force:
        host.handle_unsaved_changes()
    if File(_file).extn == 'fbx':
        load_plugin('fbxmaya')

    _kwargs = {}
    if not load_refs:
        _kwargs['loadReferenceDepth'] = 'none'

    cmds.file(_file,
              open=True,
              force=True,
              prompt=prompt,
              ignoreVersion=True,
              **_kwargs)
示例#4
0
def export_hsl_fbx_from_cur_scene(fbx, force=False):
    """Export HSL format fbx from the current scene.

    This uses the MocapTools library.

    Args:
        fbx (str): path to export to
        force (bool): overwrite existing files without confirmation
    """
    cmds.loadPlugin('fbxmaya', quiet=True)
    install_mocap_tools()
    from MocapTools.Scripts import PsyopMocapTools

    _fbx = File(fbx)
    if _fbx.exists():
        _fbx.delete(wording='Overwrite', force=force)

    _tmp_fbx = File('{}/MocapTools/Anim/Export/{}_SK_Tier1_Male.fbx'.format(
        KEALEYE_TOOLS_ROOT,
        File(host.cur_scene()).basename))
    print ' - TMP FBX', _tmp_fbx.path

    _setup = PsyopMocapTools.mocapSetupTools()
    _tmp_fbx.delete(force=True)
    assert not _tmp_fbx.exists()
    _setup.exportAnim(PsyopMocapTools.config.animFBX)
    assert _tmp_fbx.exists()

    # Move from tmp dir
    _fbx.test_dir()
    shutil.move(_tmp_fbx.path, _fbx.path)
    print ' - SAVED FBX', nice_size(_fbx.path), _fbx.path
示例#5
0
    def update_output_paths(self, catch=False):
        """Update current scene output paths to match this work file.

        Args:
            catch (bool): no error if update output file paths fails
        """
        from psyhive import tk
        if os.environ.get('PSYHIVE_DISABLE_UPDATE_OUTPUT_PATHS'):
            print 'UPDATE OUTPUT PATHS DISABLED'
            return

        # Make sure outputpaths app is loaded
        _engine = tank.platform.current_engine()
        _tk = tank.Sgtk(self.path)
        _ctx = _tk.context_from_path(self.path)
        try:
            _engine.change_context(_ctx)
        except tank.TankError as _exc:
            if not catch:
                raise _exc
            print 'FAILED TO APPLY CONTEXT', _ctx
            return

        # Apply output paths
        _outputpaths = tk.find_tank_app('outputpaths')
        _no_workspace = not host.cur_scene()
        try:
            _outputpaths.update_output_paths(scene_path=self.path,
                                             no_workspace=_no_workspace)
        except AttributeError as _exc:
            if not catch:
                raise _exc
            print 'FAILED TO UPDATE OUTPUT PATHS'
示例#6
0
    def init_ui(self):
        """Init ui elements."""
        self.ui.splitter.setSizes([314, 453])
        self._redraw__Character()

        _path = self._trg_path or host.cur_scene()
        if _path:
            self.jump_to(_path)
示例#7
0
def _get_scene_name():
    """Get current scene name hud text.

    Returns:
        (str): scene name hud text
    """
    _cur_scene = host.cur_scene()
    return 'file: {}'.format(File(_cur_scene).filename if _cur_scene else '')
示例#8
0
def _submit_render(file_=None,
                   layers=None,
                   range_=None,
                   size='Full',
                   force=False):
    """Submit render.

    This doesn't handle opening the scene and updating the assets.

    Args:
        file_ (str): path to scene to submit
        layers (list): layers to submit
        range_ (int tuple): start/end frames
        size (str): size name (eg. Full, 1/2)
        force (bool): submit with no confirmation
    """
    _file = file_ or host.cur_scene()
    _layers = layers or cmds.ls(type='renderLayer')
    _rng = range_ or host.t_range()
    print 'SUBMIT RENDER', _file

    # Build settings
    _start, _end = _rng
    _settings = render_settings.RenderSubmitSettings()
    _settings.render_layers = _layers
    _settings.render_layer_mode = render_job.RenderLayerMode.CUSTOM
    _settings.range_start = _start
    _settings.range_end = _end
    _settings.frame_source = render_job.FrameSource.FRAME_RANGE
    _settings.proxy = _map_size_to_pxy(size)
    print ' - PROXY', _settings.proxy

    # Build submittable
    _render_job = render_job.MayaRenderJob(settings=_settings,
                                           scene_path=_file)
    print ' - RENDER JOB', _render_job
    print ' - LAYERS', _render_job.render_layers
    print ' - SCENE PATH', _render_job.scene_path
    print ' - FRAMES', _render_job.frames
    _submittable = hooks.default_get_render_submittable_hook(_render_job)
    print ' - SUBMITTABLE', _submittable

    # Add publishes to make sure appears in output manager
    _maya_impl = tk2.find_tank_mod('hosts.maya_impl',
                                   app='psy_multi_psyqwrapper')
    _helper = _maya_impl.MayaPipelineRenderSubmitHelper(_submittable)
    _helper.ensure_can_register_publishes()
    _submittable.publishes = _helper.register_publishes()
    print ' - PUBLISHES', _submittable.publishes

    # Submit
    if not force:
        qt.ok_cancel('Submit?')
    _submitted = hooks.QubeSubmitter().submit(_submittable)
    if _submitted:
        print 'Successfully submitted {:d} job{} to the farm.'.format(
            len(_submitted), get_plural(_submitted))
示例#9
0
    def save_inc(self, comment, safe=True):
        """Save increment file.

        Args:
            comment (str): comment
            safe (bool): error if we are saving over an existing scene file
                without incrementing
        """
        _fileops = find_tank_app('psy-multi-fileops')

        if not host.cur_scene() == self.path:
            if safe:
                print 'CUR', host.cur_scene()
                print 'TRG', self.path
                raise ValueError
            host.save_as(self.path, revert_filename=False)
            _fileops.init_app()

        _fileops.save_increment_file(comment=comment)
示例#10
0
 def _revert_scene_fn(*args, **kwargs):
     _cur_file = host.cur_scene()
     _tmp_file = abs_path('{}/_psyhive_tmp.mb'.format(
         tempfile.gettempdir()))
     host.save_as(_tmp_file, force=True)
     _result = func(*args, **kwargs)
     host.open_scene(_tmp_file, force=True)
     if _cur_file:
         cmds.file(rename=_cur_file)
     return _result
示例#11
0
def obtain_cur_work():
    """Get cacheable version of the current work file.

    Returns:
        (_CTTWorkFileBase): work file
    """
    _scene = host.cur_scene()
    if not _scene:
        return None
    return obtain_work(_scene)
示例#12
0
    def load(self, force=True, lazy=False):
        """Load this work file.

        Args:
            force (bool): open with no scene modified warning
            lazy (bool): abandon load if file is already open
        """
        if lazy and host.cur_scene() == self.path:
            print "SCENE ALREADY OPEN", self.path
            return
        _fileops = find_tank_app('psy-multi-fileops')
        _fileops.open_file(self.path, force=force)
示例#13
0
    def generate(self):
        """Generate mov in current nuke session."""
        if not host.cur_scene() == _REVIEW_MOV_EXPORT_NK:
            host.open_scene(_REVIEW_MOV_EXPORT_NK, force=True)

        for _idx, _mov in enumerate(self.input_movs):
            _node = nuke.toNode('Read{:d}'.format(_idx+1))
            _node['file'].fromUserText(_mov.path)

        _last = _node['last'].value()
        print 'LAST', _last
        nuke.toNode('Write1')['file'].setValue(self.path)
        nuke.render('Write1', 1, _last)
示例#14
0
def cur_work(class_=None):
    """Get work file object associated with the current file.

    Args:
        class_ (type): force workfile type

    Returns:
        (TTWorkFileBase): work file
    """
    _cur_scene = host.cur_scene()
    if not _cur_scene:
        return None
    return get_work(_cur_scene, class_=class_, catch=True)
示例#15
0
    def __init__(self, path=None):
        """Constructor.

        Args:
            path (str): jump interface to path
        """
        self._asset_roots = tk2.obtain_assets()
        self._work_files = []

        super(_HiveBro, self).__init__(ui_file=UI_FILE)

        _path = path or host.cur_scene()
        if _path:
            self.jump_to(_path)
示例#16
0
def load_vendor_ma(path, fix_hik_issues=False, force=False, lazy=False):
    """Load vendor ma file.

    The file is loaded and then the bad rig reference is updated.

    Args:
        path (str): vendor ma file
        fix_hik_issues (bool): check if hik is still driving the motion
            burner skeleton and disable it if it is
        force (bool): lose unsaved changes with no warning
        lazy (bool): don't open scene if it's already open
    """

    # Load scene
    if not lazy or host.cur_scene() != path:

        if not force:
            host.handle_unsaved_changes()

        # Load the scene
        try:
            pause_viewports_on_exec(cmds.file)(path,
                                               open=True,
                                               prompt=False,
                                               force=True)
        except RuntimeError as _exc:
            if "has no '.ai_translator' attribute" in _exc.message:
                pass
            else:
                print '######################'
                print _exc.message
                print '######################'
                raise RuntimeError('Error on loading scene ' + path)

        assert host.get_fps() == 30

    _fix_cr_namespaces()

    # Update rig
    _ref = ref.find_ref(filter_='-camera -cemera')
    if not _ref.path == MOBURN_RIG:
        _ref.swap_to(MOBURN_RIG)
    _ref = _fix_nested_namespace(_ref)
    if not _ref.namespace == 'SK_Tier1_Male_CR':
        _ref.rename('SK_Tier1_Male_CR')

    # Test for hik issues
    if fix_hik_issues:
        _test_for_hik_issues(_ref)
示例#17
0
    def summary(self):
        """Get error summary for email/ticket.

        Returns:
            (str): error summary
        """
        return '\n'.join([
            'HOST: {}'.format(host.NAME),
            'PROJECT: {}'.format(pipe.cur_project().name),
            'SCENE: {}'.format(host.cur_scene()),
            'PWD: {}'.format(abs_path(os.getcwd())),
            'PLATFORM: {}'.format(sys.platform),
            '',
            'TRACEBACK:',
            '```',
            self.traceback.clean_text,
            '```'])
示例#18
0
def _generate_fbx(work, load_scene=True, lazy=True, force=False):
    """Generate fbx for a work file.

    Args:
        work (FrasierWork): work file to generate for
        load_scene (bool): load scene before export (for debugging)
        lazy (bool): don't load file if it's already open
        force (bool): overwrite existing files without confirmation
    """
    print 'EXPORT FBX'

    if load_scene:
        if not lazy or host.cur_scene() != work.path:
            print ' - LOADING SCENE FOR FBX EXPORT'
            host.open_scene(work.path, force=True)

    work.export_fbx(force=force)
示例#19
0
def cur_work(class_=None):
    """Get work file object associated with the current file.

    Args:
        class_ (type): force workfile type

    Returns:
        (TTWork): work file
    """
    _cur_scene = host.cur_scene()
    if not _cur_scene:
        return None
    _class = class_ or TTWork
    try:
        return _class(_cur_scene)
    except ValueError:
        return None
示例#20
0
def _find_ref_issues(ref_):
    """Find any issues with the given reference.

    Args:
        ref_ (FileRef): reference to check

    Returns:
        (str list): issues with reference
    """
    _file = File(host.cur_scene())

    _issues = []

    # Check namespace
    _issues += _find_ref_namespace_issues(ref_)
    if not ref_.namespace:
        return _issues

    # Check top node
    _top_node_issues, _junk = _find_ref_top_node_issues(ref_)
    _issues += _top_node_issues
    if _junk:
        return _issues

    # Check ref file path
    _ref_file = File(ref_.path)
    print '   - FILE', _ref_file.path
    _local_file = File('{}/{}'.format(_file.dir, _ref_file.filename))
    if ingest.is_vendor_file(_ref_file):
        _vendor_file = ingest.VendorFile(_ref_file)
        print '   - VENDOR FILE'
        if _vendor_file.step != 'rig':
            _issues.append("Reference {} is not a rig".format(ref_.namespace))
    elif ingest.is_psy_asset(_ref_file):
        _psy_file = ingest.PsyAsset(_ref_file)
        print '   - PSYOP FILE'
        if _psy_file.step != 'rig':
            _issues.append("Psyop reference {} is not a rig".format(
                ref_.namespace))
    elif not _local_file.exists():
        print '   - OFF-PIPELINE FILE'
        _issues.append("Reference {} has an off-pipline file {} which isn't "
                       "provided in the current directory {}".format(
                           ref_.namespace, _ref_file.filename, _file.dir))

    return _issues
示例#21
0
    def has_ik_legs(self, force=False, verbose=0):
        """Test if this work file ik legs.

        Args:
            force (bool): force reread data
            verbose (int): print process data

        Returns:
            (bool): whether legs have been update to ik
        """
        if not host.cur_scene() == self.path:
            raise CacheMissing
        for _ctrl in ['SK_Tier1_Male:FKIKLeg_R', 'SK_Tier1_Male:FKIKLeg_L']:
            _attr = _ctrl + '.FKIKBlend'
            lprint("CHECKING", _attr, cmds.getAttr(_attr), verbose=verbose)
            if not cmds.getAttr(_attr) == 10:
                return False
        return True
示例#22
0
def rerender_work_file(work_file, passes, range_):
    """Rerender a work file.

    Assets are updated to the latest version and then the workfile is
    versioned up.

    Args:
        work_file (TTWorkFileBase): work file to rerender
        passes (str list): list of passes to rerender
        range_ (int tuple): start/end frames

    Returns:
        (tuple): layers which were missing from the scene
    """
    _work = work_file.find_latest()
    _layers = [_layer_from_pass(_pass) for _pass in passes]
    print 'RERENDERING', _work
    if not host.cur_scene() == _work.path:
        _work.load(force=True)
    print ' - SCENE IS LOADED'

    # Check for missing layers
    _missing_layers = []
    for _layer in copy.copy(_layers):
        if not cmds.objExists(_layer):
            _missing_layers.append(_layer)
            _layers.remove(_layer)
    if _missing_layers:
        print 'MISSING LAYERS', _missing_layers
    if not _layers:
        raise RuntimeError("No layers were found to render")
    print ' - FOUND LAYERS TO RENDER', _layers

    _update_outputs_to_latest()

    _next_work = _work.find_next()
    _next_work.save(comment="Version up for batch rerender")

    _submit_render(file_=_next_work.path,
                   layers=_layers,
                   force=True,
                   range_=range_)

    return _missing_layers
示例#23
0
    def _callback__Work(self):
        """Update work elements."""

        _work = get_single(self.ui.Work.selected_data(), catch=True)
        _c_work = self.c_works.get(_work)
        _cur_scene = host.cur_scene()
        _cur_work = tk2.cur_work()

        if _work:
            _cur_work_selected = (_cur_work.ver_fmt == _work.ver_fmt
                                  if _cur_work else False)
            _work_orig = _work.map_to(version=1)

            self.ui.WorkPath.setText(_work.path)
            self.ui.VendorMa.setText(_work_orig.get_vendor_file())

            # Set label
            _rng = _work_orig.get_range()
            if _rng:
                _start, _end = [int(round(_val)) for _val in _rng]
                _label = 'Range: {:d} - {:d}'.format(_start, _end)
            else:
                _label = 'Cache missing'
            self.ui.WorkLabel.setText(_label)

            self.ui.Load.setEnabled(True)
            self.ui.VersionUp.setEnabled(_cur_work_selected)
            self.ui.ExportFbx.setEnabled(_cur_work_selected)
            self.ui.WorkBrowser.setEnabled(True)
            self.ui.PlaySeq.setEnabled(bool(_c_work.find_outputs()))

        else:
            self.ui.WorkPath.setText('')
            self.ui.VendorMa.setText('')

            self.ui.Load.setEnabled(False)
            self.ui.VersionUp.setEnabled(False)
            self.ui.ExportFbx.setEnabled(False)
            self.ui.WorkBrowser.setEnabled(False)
            self.ui.PlaySeq.setEnabled(False)
示例#24
0
 def _callback__WorkJumpTo(self):
     _file = host.cur_scene()
     self.jump_to(_file)
示例#25
0
def _blast_work(work,
                seq=None,
                build_cam_func=None,
                view=False,
                force=False,
                blast_=True,
                verbose=0):
    """Blast the given work file.

    Args:
        work (FrasierWork): work file to blast
        seq (TTOutputFileSeq): output image sequence
        build_cam_func (fn): function to build blast cam
        view (bool): view images on blast
        force (bool): force overwrite existing images
        blast_ (bool): execute blast
        verbose (int): print process data
    """
    _seq = seq or work.blast

    if cmds.ogs(query=True, pause=True):
        cmds.ogs(pause=True)
    assert not cmds.ogs(query=True, pause=True)

    print 'BLAST', _seq
    print ' - FRAMES', _seq.find_range()
    if not force and _seq.exists(verbose=1):
        print ' - ALREADY EXISTS'
        return

    if not host.cur_scene() == work.path:
        cmds.file(work.path, open=True, prompt=False, force=force)

    _build_cam_func = build_cam_func or _build_blast_cam
    _cam = _build_cam_func()
    print ' - CAM', _cam, type(_cam)

    # Look through cam
    _panel = ui.get_active_model_panel()
    _editor = ui.get_active_model_panel(as_editor=True)
    cmds.modelPanel(_panel, edit=True, camera=_cam)
    cmds.refresh()
    _cur_cam = cmds.modelPanel(_panel, query=True, camera=True)
    print ' - CUR CAM', _cur_cam
    assert _cur_cam == _cam

    # Apply blast settings
    cmds.modelEditor(_editor,
                     edit=True,
                     grid=False,
                     locators=False,
                     cameras=False,
                     nurbsCurves=False,
                     dimensions=False,
                     joints=False)
    cmds.camera(_cam,
                edit=True,
                displayFilmGate=False,
                displayResolution=False,
                overscan=1)
    pm.PyNode("hardwareRenderingGlobals").multiSampleEnable.set(True)
    cmds.setAttr(_cam.shp + '.nearClipPlane', 0.5)

    # Execute blast
    if not blast_:
        return
    blast(seq=_seq, res=(1280, 720), verbose=verbose)
    if view:
        _seq.view()
    print ' - BLASTED', _seq
示例#26
0
def check_current_scene(show_dialog=True, verbose=1):
    """Check current scene for ingestion issues.

    Args:
        show_dialog (bool): show status dialog on completion
        verbose (int): print process data

    Returns:
        (str list): list of issues with current file
    """
    _file = File(host.cur_scene())
    _issues = []
    lprint('FILE', _file, verbose=verbose)
    lprint(' - BASENAME', _file.basename, verbose=verbose)

    # Check current scene filename
    _issues += _find_scene_name_issues(_file)

    # Check maya version
    _ver = int(cmds.about(version=True))
    if _ver != 2018:
        _issues.append('Bad maya version {:d}'.format(_ver))

    # Check for unwanted node types
    for _type in ['displayLayer', 'renderLayer']:
        _lyrs = [
            _lyr for _lyr in cmds.ls(type=_type) if _lyr not in DEFAULT_NODES
            if not cmds.referenceQuery(_lyr, isNodeReferenced=True)
        ]
        if _lyrs:
            _issues.append('Scene has {} layers: {}'.format(
                _type.replace("Layer", ""), ', '.join(_lyrs)))
    for _type in ['unknown']:
        _nodes = [
            _node for _node in cmds.ls(type=_type)
            if _node not in DEFAULT_NODES
            if not cmds.referenceQuery(_node, isNodeReferenced=True)
        ]
        if _nodes:
            _issues.append('Scene has {} nodes: {}'.format(
                _type, ', '.join(_nodes)))

    # Check references
    _refs = ref.find_refs(unloaded=False)
    lprint('CHECKING {:d} REFS'.format(len(_refs)), verbose=verbose)
    for _ref in _refs:
        lprint(' - CHECKING', _ref, verbose=verbose)
        _issues += _find_ref_issues(_ref)

    # Print summary
    if verbose:
        print '\nSUMMARY: FOUND {:d} ISSUE{}'.format(
            len(_issues),
            get_plural(_issues).upper())
        for _idx, _issue in enumerate(_issues):
            print ' {:5} {}'.format('[{:d}]'.format(_idx + 1), _issue)
        print
    if not show_dialog:
        pass
    elif not _issues:
        qt.notify('No issues found.\n\nFile is read to send to psyop.',
                  verbose=0)
    else:
        qt.notify_warning(
            'This file has {:d} issue{}.\n\nCheck the script editor for '
            'details.'.format(len(_issues), get_plural(_issues)),
            verbose=0)

    return _issues
示例#27
0
 def _callback__Magnet(self):
     _cur_scene = host.cur_scene()
     self.jump_to(_cur_scene)