Example #1
0
def create_ref(file_, namespace, class_=None, force=False):
    """Create a reference.

    Args:
        file_ (str): path to reference
        namespace (str): reference namespace
        class_ (type): override FileRef class
        force (bool): force replace any existing ref

    Returns:
        (FileRef): reference
    """
    from psyhive import qt
    from psyhive import host

    _file = File(abs_path(file_))
    if not _file.exists():
        raise OSError("File does not exist: " + _file.path)
    _class = class_ or FileRef
    _rng = host.t_range()

    if _file.extn == 'abc':
        cmds.loadPlugin('AbcImport', quiet=True)
    elif _file.extn.lower() == 'fbx':
        cmds.loadPlugin('fbxmaya', quiet=True)

    # Test for existing
    cmds.namespace(set=":")
    if cmds.namespace(exists=namespace):
        _ref = find_ref(namespace, catch=True)
        if _ref:
            if not force:
                qt.ok_cancel(
                    'Replace existing {} reference?'.format(namespace))
            _ref.remove(force=True)
        else:
            del_namespace(namespace, force=force)

    # Create the reference
    _cur_refs = set(cmds.ls(type='reference'))
    _kwargs = {
        'reference': True,
        'namespace': namespace,
        'options': "v=0;p=17",
        'ignoreVersion': True
    }
    cmds.file(_file.abs_path(), **_kwargs)

    # Find new reference node
    _ref = get_single(set(cmds.ls(type='reference')).difference(_cur_refs))

    # Fbx ref seems to update timeline (?)
    if host.t_range() != _rng:
        host.set_range(*_rng)

    return _class(_ref)
Example #2
0
def _update_xml_start_frames(n_cloths=None, force=True):
    """Update start frames in cache xml file.

    As the cache is run on individual frames, the xml file is regenrated
    on each frame as a one frame cache. This means the start frame needs
    to be updated but also the sample rate which is written as zero for
    one frame caches. Loading a cache with zero sample rate and a frame
    range will make maya seg fault.

    Args:
        n_cloths (NCloth list): nCloth caches to update
        force (bool): update without confirmation
    """
    _start, _end = host.t_range()
    _start_tick, _end_tick = int(_start * 240), int(_end * 240)
    _n_cloths = n_cloths or [
        _NCloth(_n_cloth) for _n_cloth in cmds.ls(type='nCloth')
    ]
    for _n_cloth in _n_cloths:
        _xml = _n_cloth.get_cache_xml()
        print _n_cloth, _xml.path
        assert _xml.exists()
        _body = _xml.read()
        for _str in [
                'Range="{start}-{end}"',
                'StartTime="{start}"',
                'SamplingRate="{rate}"',
        ]:
            _find = _str.format(start=_end_tick, end=_end_tick, rate=0)
            _replace = _str.format(start=_start_tick, end=_end_tick, rate=240)
            assert _body.count(_find) == 1
            _body = _body.replace(_find, _replace)
        _xml.write_text(_body, force=force)
Example #3
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))
Example #4
0
def set_start(frame):
    """Set timeline start frame.

    Args:
        frame (int): frame to apply
    """
    from psyhive import host
    _, _end = host.t_range()
    hou.playbar.setFrameRange(frame, _end)
Example #5
0
def set_end(frame):
    """Set timeline end frame.

    Args:
        frame (int): frame to apply
    """
    from psyhive import host
    _start, _ = host.t_range()
    hou.playbar.setFrameRange(_start, frame)
Example #6
0
def bake_results(chans, simulation=False, range_=None):
    """Bake anim on the given list of channels.

    Args:
        chans (str list): list of channels to bake
        simulation (bool): bake as simulation (scrub timeline)
        range_ (tuple): override bake range
    """
    from psyhive import host
    _range = range_ or host.t_range()
    cmds.bakeResults(chans, time=_range, simulation=simulation)
Example #7
0
    def exec_switch_and_key_over_range(
            self, switch_mode, switch_key=False, selection=True):
        """Exec switch and key over range.

        Args:
            switch_mode (str): fk/ik switch mode
            switch_key (bool): add keys on switch
            selection (bool): use timeline selection
                (otherwise use whole timeline)
        """

        # Read range
        if selection:
            _timeline = mel.eval('$tmpVar=$gPlayBackSlider')
            _start, _end = [
                int(_val) for _val in cmds.timeControl(
                    _timeline, query=True, rangeArray=True)]
        else:
            _start, _end = host.t_range()
        print 'TIMELINE RANGE', _start, _end

        # Get list of keyed frames
        _frames = {_start, _end}
        for _attr in self.get_key_attrs():
            _crv = get_single(
                cmds.listConnections(_attr, type='animCurve'), catch=True)
            if not _crv:
                continue
            _ktvs = cmds.getAttr(_crv+'.ktv[*]') or []
            _frames = _frames.union([
                _frame for _frame, _ in _ktvs
                if _frame > _start and _frame < _end])
        _frames = sorted(_frames)
        print 'FRAMES', _frames

        # Key current state
        _orig_frames = _frames
        if switch_key:
            _orig_frames = [_start-1] + _frames + [_end+1]
        print 'KEYING CURRENT STATE', _orig_frames
        for _frame in _orig_frames:
            cmds.currentTime(_frame)
            cmds.setKeyframe(self.get_key_attrs())

        # Key switch
        print 'KEYING SWITCH', _frames
        for _frame in _frames:
            cmds.currentTime(_frame)
            cmds.refresh()
            self.exec_switch_and_key(
                switch_mode=switch_mode, key_mode='Frame',
                switch_key=False, verbose=0)
Example #8
0
 def scene_get_frame_range(self):
     """Check if this scene's meshes match the model meshes."""
     host.open_scene(self.path, lazy=True, force=True)
     return host.t_range(int)
Example #9
0
def _cache_yetis(yetis, apply_on_complete=False, samples=3, verbose=0):
    """Cache a list of yeti nodes.

    Args:
        yetis (HFnDependencyNode list): nodes to cache
        apply_on_complete (bool): apply cache on completion
        samples (int): samples per frame
        verbose (int): print process data
    """
    from . import yeti_ui

    print 'CACHE YETIS', yetis
    _work = tk2.cur_work()
    _yetis, _outs, _namespaces = _prepare_yetis_and_outputs(
        yetis=yetis, work=_work)

    # Get cache path - if multiple namespace need to cache to tmp
    _tmp_fmt = abs_path('{}/yetiTmp/<NAME>.%04d.cache'.format(
        tempfile.gettempdir()))
    if len(_yetis) > 1:
        _cache_path = _tmp_fmt
        _tmp_dir = Dir(os.path.dirname(_tmp_fmt))
        _tmp_dir.delete(force=True)
        _tmp_dir.test_path()
    else:
        assert len(_outs) == 1
        _cache_path = _outs[0].path
    print "CACHE PATH", _cache_path

    # Generate caches
    dprint('GENERATING CACHES', _cache_path)
    print ' - SAMPLES', samples
    for _yeti in _yetis:
        _yeti.plug('cacheFileName').set_val('')
        _yeti.plug('fileMode').set_val(0)
        _yeti.plug('overrideCacheWithInputs').set_val(False)
    cmds.select(_yetis)
    cmds.pgYetiCommand(
        writeCache=_cache_path, range=host.t_range(), samples=samples)
    dprint('GENERATED CACHES', _cache_path)

    # Move tmp caches to outputs
    if len(_yetis) > 1:
        dprint('MOVING CACHES FROM TMP')
        for _yeti, _out in safe_zip(_yetis, _outs):
            print ' - MOVING', _out.path
            _name = str(_yeti).replace(":", "_")
            _tmp_seq = Seq(_tmp_fmt.replace('<NAME>', _name))
            for _frame, _tmp_path in safe_zip(
                    _tmp_seq.get_frames(), _tmp_seq.get_paths()):
                lprint('   -', _frame, _tmp_path, verbose=verbose)
                shutil.move(_tmp_path, _out[_frame])

    # Apply cache to yeti nodes
    if apply_on_complete:
        dprint('APPLYING CACHES TO YETIS')
        for _yeti, _cache in safe_zip(_yetis, _outs):
            apply_cache(cache=_cache, yeti=_yeti)

    qt.notify(
        'Cached {:d} yeti node{}.\n\nSee script editor for details.'.format(
            len(_yetis), get_plural(_yetis)),
        title='Cache complete', icon=yeti_ui.ICON, parent=yeti_ui.DIALOG)

    return _outs
Example #10
0
def blast(seq,
          range_=None,
          res=None,
          force=False,
          cam=None,
          view=False,
          verbose=0):
    """Execute a playblast.

    Args:
        seq (Seq): output sequence
        range_ (tuple): start/end frame
        res (tuple): override image resolution
        force (bool): overwrite existing images without confirmation
        cam (str): override camera
        view (bool): view blast on complete
        verbose (int): print process data
    """
    from psyhive import host
    from maya_psyhive import ui

    # Get res
    if res:
        _width, _height = res
        cmds.setAttr('defaultResolution.width', _width)
        cmds.setAttr('defaultResolution.height', _height)
    else:
        _width = cmds.getAttr('defaultResolution.width')
        _height = cmds.getAttr('defaultResolution.height')
    lprint('RES', _width, _height, verbose=verbose)

    # Get range
    _rng = range_ or host.t_range()
    _start, _end = _rng

    if cam:
        _panel = ui.get_active_model_panel()
        cmds.modelEditor(_panel, edit=True, camera=cam)

    seq.delete(wording='Replace', force=force)
    seq.test_dir()

    # Set image format
    _fmt_mgr = createImageFormats.ImageFormats()
    _fmt_mgr.pushRenderGlobalsForDesc({
        'jpg': "JPEG",
        'exr': "EXR",
    }[seq.extn])

    _filename = '{}/{}'.format(seq.dir, seq.basename)
    lprint('BLAST FILENAME', _filename, verbose=verbose)
    cmds.playblast(startTime=_start,
                   endTime=_end,
                   format='image',
                   filename=_filename,
                   viewer=False,
                   width=_width,
                   height=_height,
                   offScreen=True,
                   percent=100)
    assert seq.get_frames(force=True)

    _fmt_mgr.popRenderGlobals()

    if view:
        seq.view()