def write_cache_from_sel_assets(apply_on_complete=False, samples=3): """Cache selected asset. All yeti nodes in the selected asset are cached. The asset can be selected by selecting any node in the reference. Args: apply_on_complete (bool): apply cache on completion samples (int): samples per frame Returns: (TTOutputFileSeq list): caches generated """ _refs = ref.get_selected(multi=True) if not _refs: qt.notify_warning("No assets selected.\n\nPlease select the assets " "you want to cache.") return None print 'REFS', _refs # Get yeti nodes _yetis = sum([_ref.find_nodes(type_='pgYetiMaya') for _ref in _refs], []) if not _yetis: qt.notify_warning( "No yeti nodes in assets:\n\n {}\n\nNone of these assets can " "be cached.".format('\n '.join([ _ref.namespace for _ref in _refs]))) return None return _cache_yetis(_yetis, apply_on_complete=apply_on_complete, samples=samples)
def create_standin_from_sel_shade( archive=('P:/projects/clashroyale2019_34814P/sequences/' 'crowdCycles25Fps/cid00Aid001/animation/output/animcache/' 'animation_archer/v014/' 'alembic/cid00Aid001_animation_archer_v014.abc'), verbose=0): """Create aiStandIn from selected shade asset. The shader is read from all mesh nodes in the shade asset, and then this is used to create an aiSetParameter node on the standin for each shader. If all the meshes using the shader has matching values for ai attrs, these values are applied as overrides on the aiSetParameter node. Args: archive (str): path to archive to apply to standin verbose (int): print process data """ _shade = ref.get_selected(catch=True) if not _shade: qt.notify_warning('No shade asset selected.\n\nPlease select a shade ' 'asset to read shaders from.') return tank_support.build_aistandin_from_shade(shade=_shade, verbose=verbose, archive=archive)
def _assign_shader_to_sel(shd_mb, shd_name, parent): """Assign the given shader to selected geometry and shape nodes. Args: shd_mb (TTOutputFile): published shaders mb file shd_name (str): name of shader to import parent (QWidget): parent widget """ print 'APPLY SHADER', shd_name, shd_mb.path # Get shape nodes of selections _shps = set(cmds.ls(selection=True, shapes=True)) for _sel in cmds.ls(selection=True, type='transform'): _shps |= set(get_shps(_sel)) _shps = sorted(_shps) if not _shps: qt.notify_warning('No selected geometry or shapes found', parent=parent) return # Get shader _se = _import_shader(shd_mb=shd_mb, shd_name=shd_name) # Assign to shapes for _shp in _shps: cmds.sets(_shp, edit=True, forceElement=_se)
def switch_selected_rig(rig): """Switch selected rig reference. Args: rig (str): rig name to switch to """ _sel = ref.get_selected(catch=True) if not _sel: qt.notify_warning('No rig selected') return print 'SELECTED', _sel _trg = get_single([_rig for _rig in _find_rigs() if _rig.name == rig]) print 'TARGET', _trg.path qt.ok_cancel('Update "{}" rig to "{}"?'.format(_sel.namespace, _trg.name)) _sel.swap_to(_trg.path)
def launch_cache_tools(): """Launch yeti cache tools interface.""" global DIALOG # Make sure we are in a shot _work = tk2.cur_work() if not _work: qt.notify_warning( 'No current work file found.\n\nPlease save your scene.') return None # Launch interface from maya_psyhive.tools import yeti DIALOG = _YetiCacheToolsUi() yeti.DIALOG = DIALOG return yeti.DIALOG
def write_cache_from_all_yetis(apply_on_complete=False, samples=3): """Write a yeti cache from all yeti nodes in the scene. Args: apply_on_complete (bool): apply cache on completion samples (int): samples per frame Returns: (TTOutputFileSeq list): caches generated """ from . import yeti_ui _yetis = hom.CMDS.ls(type='pgYetiMaya') if not _yetis: qt.notify_warning("No yeti nodes in the scene.\n\nUnable to cache.", parent=yeti_ui.DIALOG) return None return _cache_yetis(_yetis, apply_on_complete=apply_on_complete, samples=samples)
def _handle_exception(exc, verbose=0): """Handle the given exception. Args: exc (Exception): exception that was raised verbose (int): print process data """ # Handle special exceptions if ( # In case of FileError, jump to file not os.environ.get('EXC_DISABLE_FILE_ERROR') and isinstance(exc, FileError)): print '[FileError]' print ' - MESSAGE:', exc.message print ' - FILE:', exc.file_ File(exc.file_).edit(line_n=exc.line_n) return elif isinstance(exc, qt.DialogCancelled): print '[DialogCancelled]' return elif isinstance(exc, SystemExit) or exc is SystemExit: print '[SystemExit]' return elif isinstance(exc, HandledError): qt.notify_warning(msg=exc.message, icon=exc.icon, title=exc.title) return if not dev_mode(): _pass_exception_to_sentry(exc) # Raise error dialog lprint('HANDLING EXCEPTION', exc, verbose=verbose) lprint('MSG', exc.message, verbose=verbose) lprint('TYPE', type(exc), verbose=verbose) _traceback = Traceback() _traceback.pprint() _app = qt.get_application() _dialog = _ErrDialog( traceback_=_traceback, message=exc.message, type_=type(exc).__name__) if not host.NAME: _app.exec_()
def apply_caches_to_sel_asset(caches): """Apply yeti caches to the selected asset. The asset can be selected by selecting any node in the reference. If the asset doesn't have a matching yeti node, it will be created. Args: caches (TTOutputFileSeq list): caches to apply """ print 'APPLY CACHES', caches # Get asset _ref = ref.get_selected(catch=True) if not _ref: qt.notify_warning( "No asset selected.\n\nPlease select the asset you apply the " "cache to.") return print 'REF', _ref # Apply caches to yeti nodes for _cache in caches: apply_cache(_cache, ref_=_ref)
def write_cache_from_sel_yetis(apply_on_complete=False, samples=3): """Write a yeti cache from selected yeti nodes. All selected pgYetiMaya nodes are cached. NOTE: pgYetiGroom nodes cannot be cached individually - you need to find the corresponding pgYetiMaya node to cache a groom. Args: apply_on_complete (bool): apply cache on completion samples (int): samples per frame Returns: (TTOutputFileSeq list): caches generated """ from . import yeti_ui _yetis = hom.get_selected(type_='pgYetiMaya', multi=True) if not _yetis: qt.notify_warning("No yeti nodes selected.\n\nPlease select one or " "more yeti nodes.", parent=yeti_ui.DIALOG) return None return _cache_yetis(_yetis, apply_on_complete=apply_on_complete, samples=samples)
def ingest_seqs(dir_, vendor, filter_=None, force=False, resubmit_transgens=False): """Ingest images sequences from the given directory. Args: dir_ (str): directory to search vendor (str): name of vendor filter_ (str): apply path filter force (bool): ingest without confirmation resubmit_transgens (bool): resubmit any submitted transgens """ _dir = Dir(abs_path(dir_)) print 'READING', _dir.path assert _dir.exists() _seqs = _dir.find_seqs(filter_=filter_) print ' - FOUND {:d} SEQS'.format(len(_seqs)) # Set vendor _vendor = vendor or vendor_from_path(_dir.path) assert _vendor print ' - VENDOR', _vendor print # Check images _statuses = {} _to_ingest = [] for _idx, _seq in qt.progress_bar( enumerate(_seqs), 'Checking {:d} seq{}'): print '[{:d}/{:d}] PATH {}'.format(_idx+1, len(_seqs), _seq.path) # Check ingestion status _status = _ingestable = None try: _seq = VendorSeq(_seq) except ValueError: _status, _ingestable = 'Fails naming convention', _seq.basename else: assert isinstance(_seq, VendorSeq) _status, _ingestable = _seq.get_ingest_status( resubmit_transgens=resubmit_transgens) print ' - STATUS', _status assert _status assert _ingestable is not None if _ingestable: _to_ingest.append(_seq) _statuses[_seq] = _status # Print summary print '\nSUMMARY:' print '\n'.join([ ' {} - {:d}'.format(_status, _statuses.values().count(_status)) for _status in sorted(set(_statuses.values()))]) print 'FOUND {:d} SEQ{} TO INGEST'.format( len(_to_ingest), get_plural(_to_ingest).upper()) # Show different source warning _diff_src = [ _ for _, _status in _statuses.items() if _status == 'Already ingested from a different source'] if _diff_src: qt.notify_warning( '{:d} of the sequences could not be ingested because they have ' 'already been ingested from a different delivery. This happens ' 'when a vendor provides an update without versioning up.\n\n' 'See the terminal for details.'.format(len(_diff_src))) # Execute ingestion if not _to_ingest: return if not force: qt.ok_cancel( 'Ingest {:d} seq{}?'.format( len(_to_ingest), get_plural(_to_ingest)), verbose=0) for _idx, _seq in qt.progress_bar( enumerate(_to_ingest), 'Ingesting {:d} seq{}', stack_key='IngestSeqs'): print '({:d}/{:d}) [INGESTING] {}'.format( _idx+1, len(_to_ingest), _seq.path) _seq.ingest(vendor=vendor)
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