def _reload(self, children): parent_revision = tank.find(self.path) # go through each revision in the bundle # find matching connected reference with same container # update for child_revision in self._bundle.revisions: if os.path.splitext(child_revision.system.filesystem_location)[1] in (".ma", ".mb"): for ref_node in self.node.members(): ref = pm.FileReference(ref_node) r2 = tank.find(ref.path) if str(r2) == str(child_revision): # same reference, done with this revision break elif str(r2.container) == str(child_revision.container): # same container, different revision # replace the revision with this one ref.replaceWith(child_revision.system.vfs_full_paths[0]) break # now go through connected reference nodes # if one is connected, but doesn't belong, unlink it # NOTE: we don't remove it -- leave it up to the user to do that for ref_node in self.node.members(): ref = pm.FileReference(ref_node) revision = tank.find(ref.path) if not revision in self._bundle.revisions: self.node.remove(ref_node)
def load_all_geocaches(node): # Get the shot from the scene container shot = node.scene.container.labels['Shot'] print "\nLoading all geocaches for", shot # get all latest geocaches for that shot geocaches = tank.get_children(tank.find("GeoCache"), ["container has_label %s" % shot]) for geocache in geocaches: # if geocache == geocache.container.latest_revisions['GeoCache']: # is it the latest? if geocache == tank.find('GeoCache(LATEST, %s)' % geocache.container): # is it the latest? # We only load the latest geocaches revisions load_one_geocache(node, geocache)
def valid_revision_types(self): """ Returns the list of valid revision types. Types are filtered against the extension_hint and restrict_resource_type properties of the revision type and the valid_revision_types property of the container. The first entry is always None. :rtype: list of strings """ # check for valid revision types # TODO: simplify when list_* returns types instead of strings valid_rts = [tank.find(rt) for rt in tank.list_revision_types()] # check for matching extension if isinstance(self._data.path, basestring): ext = os.path.splitext(self._data.path)[1].lstrip('.') valid_rts = [rt for rt in valid_rts \ if rt.properties.extension_hint is not None and \ ext in rt.properties.extension_hint.split(',')] # check for matching sequence vs. single file if hasattr(self._data, "frame_range") and self._data.frame_range is not None: resource_type = tank.constants.ResourceType.SEQUENCE else: if os.path.exists(self._data.path) and os.path.isdir(self._data.path): resource_type = tank.constants.ResourceType.FOLDER else: resource_type = tank.constants.ResourceType.SINGLE_FILE valid_rts = [rt for rt in valid_rts if rt.properties.restrict_resource_type in (resource_type, None)] return [None] + sorted(valid_rts, key=lambda rt: rt.system.name) else: return [None]
def get_latest_master_audio(self, revision_type="Audio", return_tank_object=False): """ Return the latest audio for a shot. By default it returns the file path to the audio. If return_tank_object=True, it will return the Tank revision object. """ import traceback if self._cache_latest_tank_audio == "_search_but_not_found": return None audio_container = projectAwareness.get_tank_audio_container( self.project.name, self.scene.name, self.name, audio_name="master") try: audio_address = "%(revision_type)s(latest, %(audio_container)s)" % vars( ) rev = tank.find(audio_address) except tank.common.errors.TankNotFound, e: self._cache_latest_tank_audio = "_search_but_not_found" print "Tank Not Found: can not find audio under %s" % audio_address return None
def collectReviews(self, tank_obj): # extract the tank information for the reviews rev_type = tank_obj.get_entity_type() container = tank_obj.get_container() container_address = str(container) # replace the review type for the container if ('ReviewType(creative)' in container_address): container_address = container_address.replace( 'ReviewType(creative)', 'ReviewType(technical)') elif ('ReviewType(technical)' in container_address): container_address = container_address.replace( 'ReviewType(technical)', 'ReviewType(creative)') else: return [] # create the mapping try: matching = tank.find(container_address).get_object() except TankNotFound: return [] # make sure our revisions are of the same type, and come from the same root maya scene mscene = self.findAncestor('MayaScene', tank_obj) revisions = [ rev for rev in matching.get_revisions() if rev.get_entity_type() == rev_type and self.findAncestor('MayaScene', rev) == mscene ] revisions.reverse() return revisions
def determine_aux_data_from_tank_address(tank_rev, include_shotgun_data=False): import tank if type(tank_rev) in (str, unicode): tank_rev = tank.find(tank_rev) return determine_aux_data_from_vfs_path( tank_rev=tank_rev, include_shotgun_data=include_shotgun_data)
def collectFrameData(address): frames_address = address.replace('Movie(','Frames(') try: tank_frames = tank.find(frames_address) except: tank_frames = None core.warn( 'Could not find tank address: %s...' % address ) imageSource = '' sourceStart = 0 sourceEnd = 0 stereo_pair = [] if ( tank_frames ): filepath = tank_frames.system.filesystem_location # extract the stereo pair information from the tank frames object stereo_pair = tank_frames.properties['stereo_pair'] if ( not stereo_pair ): stereo_pair = ['left'] spath, sname, smin, smax = get_frame_sequence_source(filepath) if ( not (spath and sname) ): core.warn( 'Could not extract frame data from %s' % filepath ) else: imageSource = os.path.join(spath,sname) sourceStart = smin sourceEnd = smax return (imageSource,sourceStart,sourceEnd,stereo_pair)
def collectReviews( self, tank_obj ): # extract the tank information for the reviews rev_type = tank_obj.get_entity_type() container = tank_obj.get_container() container_address = str(container) # replace the review type for the container if ( 'ReviewType(creative)' in container_address ): container_address = container_address.replace('ReviewType(creative)','ReviewType(technical)') elif ( 'ReviewType(technical)' in container_address ): container_address = container_address.replace('ReviewType(technical)','ReviewType(creative)') else: return [] # create the mapping try: matching = tank.find(container_address).get_object() except TankNotFound: return [] # make sure our revisions are of the same type, and come from the same root maya scene mscene = self.findAncestor( 'MayaScene', tank_obj ) revisions = [ rev for rev in matching.get_revisions() if rev.get_entity_type() == rev_type and self.findAncestor( 'MayaScene', rev ) == mscene ] revisions.reverse() return revisions
def syncSceneShotVersionBar(self): ''' update the tank version combo by looking at the path populate the tank versions combo box if the source comes from tank ''' if not self.cboSourceVersion.isVisible(): return self.stateTankVersionChanging = True QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) # get the source data sourceData = self.tableView.getShotData(self.tableView.getSelectedRow()[0]) if isEditSourceMovie(sourceData["Source Name"]): path = os.path.join(sourceData["Source Path"], sourceData["Source Name"]) else: path = sourceData["Source Path"] # check if it specify a tank version rev = None try: rev = tank.find(path) except tank.common.errors.TankNotFound, e: pass
def get_revision_type(parent_container, path, frame_range): # start with all revision types valid_rts = [tank.find(rt) for rt in tank.list_revision_types()] if parent_container and len(parent_container.system.type.properties.valid_revision_types) > 0: valid_rts = [rt for rt in valid_rts if rt in parent_container.system.type.properties.valid_revision_types] # filter by extension ext = os.path.splitext(path)[1].lstrip(".") valid_rts = [rt for rt in valid_rts \ if rt.properties.extension_hint is not None and \ ext in rt.properties.extension_hint.split(',')] # filter by resource type if frame_range is None: if os.path.exists(path) and os.path.isdir(path): resource_type = tank.common.constants.ResourceType.FOLDER else: resource_type = tank.common.constants.ResourceType.SINGLE_FILE else: resource_type = tank.common.constants.ResourceType.SEQUENCE valid_rts = [rt for rt in valid_rts if rt.properties.restrict_resource_type in (resource_type, None)] if len(valid_rts) > 0: return valid_rts[0] else: return None
def get_latest_master_audio(self, revision_type="Audio", return_tank_object=False): """ Return the latest audio for a shot. By default it returns the file path to the audio. If return_tank_object=True, it will return the Tank revision object. """ import traceback if self._cache_latest_tank_audio == "_search_but_not_found": return None audio_container = projectAwareness.get_tank_audio_container(self.project.name, self.scene.name, self.name, audio_name="master") try: audio_address = "%(revision_type)s(latest, %(audio_container)s)" % vars() rev = tank.find(audio_address) except tank.common.errors.TankNotFound, e: self._cache_latest_tank_audio = "_search_but_not_found" print "Tank Not Found: can not find audio under %s" % audio_address return None
def last_revision(self): """ Returns the last revision stored by the delegate """ if self.is_revision(): return self.revision elif hasattr(self._data, "last_revision_id"): return tank.find(self._data.last_revision_id) if self._data.last_revision_id is not None else None else: return None
def get(work_path): """Returns container, revision_type associated with the work path.""" # if it's a revision, it's definitely not a working path # TODO: get from tank config if work_path[0:5] == "/tank": raise NotWorkingPathError("%s is not a working path." % work_path) dir = None filename = None ext = None resource_type = None if os.path.isdir(work_path): dir = work_path elif os.path.isfile(work_path): dir, filename = os.path.split(work_path) filename, ext = os.path.splitext(filename) resource_type = tank.common.constants.ResourceType.SINGLE_FILE else: # strip off names until we find a directory that exists ext = os.path.splitext(work_path)[1] partial_path = work_path while partial_path not in ("/", ""): if os.path.isdir(partial_path): dir = partial_path break partial_path = os.path.split(partial_path)[0] # bail, can't parse if dir is None: raise NotWorkingPathError("%s is not a working path." % work_path) # TODO: more hard-coded values partial_path = dir.replace("/dfs1/net", "").replace("/prod/" + os.environ["TANK_PROJECT"].lower() + "/work", "") partial_path = re.sub(r"(.*?)([.][^/]*)(.*)", r"\1\3", partial_path) # iterate over the path, stripping the final directory off each time until we find a match container = None while partial_path != "/": try: container = tank.find(partial_path) break except: pass partial_path = os.path.split(partial_path)[0] if container is not None or ext is not None or resource_type is not None: # identify the revision type revision_type = _get_revision_type(container, ext, resource_type) else: revision_type = None return container, revision_type
def filterAcceptsRow(self, sourceRow, sourceParent): index = self.sourceModel().index(sourceRow, 0, sourceParent) if not index.isValid(): return False else: obj = index.data(Qt.UserRole).toPyObject() # workaround until get_latest_versions is implemented in the server api obj = tank.find(str(obj)) return (self._filter == RevisionResultsProxyModel.FilterAll) or \ (self._filter == RevisionResultsProxyModel.FilterRecommended and obj.system.recommended) or \ (self._filter == RevisionResultsProxyModel.FilterLatest and obj in obj.container.latest_revisions.values())
def collectMovieData(address): movie_address = address.replace('Frames(','Movie(') try: tank_movie = tank.find(movie_address) except: tank_movie = None core.warn( 'Could not find tank address: %s...' % address ) # load data from the tank movie videoSource = '' if ( tank_movie ): videoSource = tank_movie.system.filesystem_location return videoSource
def valid_container_types(self): """ Returns a list of valid container types. If this node's revision type is not None, only containers whose valid_revision_type property contains the revision type are returned. The first entry is always None. :rtype: list of EntityType or None """ valid_cts = [tank.find(ct) for ct in tank.list_container_types()] if self._revision_type is not None: # filter by valid revision type valid_cts = [ct for ct in valid_cts if self._revision_type in ct.properties.valid_revision_types or ct.properties.valid_revision_types is None] return [None] + sorted(valid_cts, key=lambda ct: ct.system.name)
def sinfoFilepath( self ): if ( self._sinfoFilepath != None ): return self._sinfoFilepath # extract the sinfo address sinfo_address = self.tankAddress().replace('Frames','SInfoFile').replace('Movie','SInfoFile') if ( not sinfo_address ): self._sinfoFilepath = '' return self._sinfoFilepath try: self._sinfoFilepath = tank.find(sinfo_address).system.filesystem_location except: self._sinfoFilepath = '' return self._sinfoFilepath
def add_dependency(self, path, subset=(), name=None, delegate=None): """ Explicitly adds a dependency to the scene. :param path: The path to the dependency. Dependencies are resolved using delegates in Node.__init__. :type path: string :param subset: subset of child revisions that will be added. this must be a subset of new_dependency.data.children """ try: revision = None container, revision_type = sandbox.get(path) ext = os.path.splitext(path)[1] frame_range = None except: revision = tank.find(path) container = revision.container revision_type = revision.system.type ext = os.path.splitext(revision.resource_path)[1] if revision.resource_type == tank.constants.ResourceType.SEQUENCE: frame_range = revision.frame_range path = os.path.join(revision.system.vfs_full_paths[0], os.path.split(revision.resource_path)[1]) else: frame_range = None # find matching delegate if delegate is None: delegate = plugins.get_one_delegate(ext=ext, attrs=("add_dependency",)) # consult the namer plugin if name is None: name = plugins.get_one_namer().get_node_name(self.container, container, revision_type, path) data = delegate.add_dependency(name, path, frame_range, self._data) dependency = Dependency(delegate, data, self) # # add any children first # for r in data.children: # if r in subset: # dependency.add_dependency(r.system.vfs_full_paths[0]) self.dependencies.append(dependency) if hasattr(data, "update"): #children = [d.data for d in dependency.dependencies] dependency._pending_action = Action("update", func=data.update, kwargs={"reload": True}) return dependency
def _get_label_types(container_type): """ Returns the label types associated with a container type. :param container_type: The container type. :type limit: tank.local.EntityType :rtype: list of tank.local.EntityTypes (label types) """ assert isinstance(container_type, tank.TankType), container_type assert container_type.properties.container_type == tank.constants.ContainerType.CONTAINER, container_type.properties.container_type # TODO: find the constants for "label" and "Entity Type" label_types = [tank.find(field.properties.validation["address"]) \ for field in container_type.fields.values() \ if field.properties.type == "label" and \ field.properties.validation["type"] == "Entity Type"] return sorted(label_types, key=lambda lt: lt.system.name)
def sinfoFilepath(self): if (self._sinfoFilepath != None): return self._sinfoFilepath # extract the sinfo address sinfo_address = self.tankAddress().replace('Frames', 'SInfoFile').replace( 'Movie', 'SInfoFile') if (not sinfo_address): self._sinfoFilepath = '' return self._sinfoFilepath try: self._sinfoFilepath = tank.find( sinfo_address).system.filesystem_location except: self._sinfoFilepath = '' return self._sinfoFilepath
def get_node_name(parent_container, container, revision_type, path): # attempt to come up with a useful node name name = None # 1. if all of the new container's labels are contained in our container's labels, # use the new container type's name (sans _vXX) # example: referencing a model in a texture should call the namespace "model" if parent_container is not None and container is not None \ and all(l in container.labels.values() for l in parent_container.labels.values()): name = re.sub(r"_v[0-9]+", "", container.system.type_name) # 1a. if the container has a name, append that with an underscore, e.g. "model_arm" if tank.find(container.system.type_name).properties.use_name: name += "_" + container.system.name # 2. if the container has an Asset label that is not ANY, use that with 01 appended elif container.labels.has_key("Asset") and container.labels["Asset"].system.name != "ANY": name = container.labels["Asset"].system.name + "01" # 3. if the container has a name, use that with 01 appended elif container is not None and container.system.type.properties.use_name: name = container.system.name + "01" # 4. use the first label's value that doesn't start with a number, with 01 appended elif container is not None and len(container.labels.values()) > 0: for label in container.labels.values(): if label.system.name[0].isalpha(): name = label.system.name break if name is not None: name += "01" # 5. fall back on using the filename minus extensions if name is None: name = os.path.split(path)[1] while name.find('.') != -1: name = os.path.splitext(name)[0] # camelCaps, not CapitalCaps name = name[0].lower() + name[1:] return name
def collectAudioData(address): try: tank_audio = tank.find(address) except: tank_audio = None core.warn( 'Could not find tank address: %s...' % address ) audioSource = '' audioStart = 0 audioOffset = 0 # load data from the tank audio if ( tank_audio ): pipeline_data = tank_audio.properties.get('pipeline_data',{}) audioSource = tank_audio.system.filesystem_location audioStart = pipeline_data.get('start_frame',-1) audioOffset = pipeline_data.get('start_offset',0) return (audioSource,audioStart,audioOffset)
def _get_revision_type(container, ext, resource_type): # check for valid revision types if container is not None: # TODO: container.system.type_object returns a local API object valid_rts = container.system.type.properties.valid_revision_types if container is None or len(valid_rts) == 0: valid_rts = [tank.find(t) for t in tank.list_revision_types()] # check for matching extension if ext is not None: valid_rts = [rt for rt in valid_rts if rt.properties.has_key("extension_hint") and rt.properties.extension_hint is not None and ext.lstrip('.') in rt.properties.extension_hint.split(',')] # check for matching resource type if resource_type is not None: valid_rts = [rt for rt in valid_rts if rt.properties.restrict_resource_type in (resource_type, None)] # return the first match or None try: return valid_rts[0] except IndexError: return None
def status(self): """ Returns the status (StatusType) """ if self._version is not None and self._revision_type is not None: if len(self._container.properties.recommended) > 0: # in the case that we have recommended versions if len(self._container.properties.recommended) > 0 and \ self._version == sorted([r.system.name for r in self._container.properties.recommended], reverse=True)[0]: return "recommended+latest" else: return "recommended+outofdate" else: # FIXME: not sure why it doesn't work if I omit the string conversion # FIXME: fails in tank 1.14, should be fixed in 1.15 #if str(self._revision) in [str(r) for r in self._container.latest_revisions.values()]: if str(self._revision) in [str(r) for r in tank.find(str(self._container)).latest_revisions.values()]: return "general+latest" else: return "general+outofdate" else: return "unknown"
def test_dependencies_match(self): assert len(self._scene.dependencies) == 2 assert self._scene.dependencies[0].data.name == "ref1" assert self._scene.dependencies[1].data.name == "ref2" scene = self._scene ref1 = self._scene.dependencies[0] ref2 = self._scene.dependencies[1] scene.container = tank.find("animation(shot(sh_0000), sequence(seq_001), department(animation))") scene.revision_type = tank.find("xml") ref1.container = tank.find("animation(shot(sh_0001), sequence(seq_001), department(animation))") ref1.revision_type = tank.find("xml") ref2.container = tank.find("animation(shot(sh_0002), sequence(seq_001), department(animation))") ref2.revision_type = tank.find("xml") scene.publish(description="test")
def attach_haircaches(node): namespace = node.data.reference.namespace start_time = pm.playbackOptions(query=True, minTime=True) end_time = pm.playbackOptions(query=True, maxTime=True) node_labels = node.labels.values() scene_labels = node.scene.labels.values() container_type = tank.find(plugin_utils.get_latest_container('Anim_v')) # find hairsystems in the given namespace for hairsystem in pm.ls(namespace + ":*", type="hairSystem"): name = str(hairsystem.stripNamespace()) # find container with node and scene labels named the same as the # hair system (same type as scene container) labels_set = set(node_labels + [label for label in scene_labels if label.system.type.system.name != 'Layer']) container = tank.find_ex(container_type, name=name, labels=labels_set) # find latest revision of type HairCache revision = container.latest_revisions["HairCache"] cache_filename = revision.system.vfs_full_paths[0] cache_name = "cache_" + namespace.replace(":", "_") + "_" + name if pm.objExists(cache_name): diskcache = pm.ls(cache_name) else: # create and set-up the node diskcache = pm.createNode("diskCache", name=cache_name) hairsystem_start_time = hairsystem.startFrame.get() # set the start/end time diskcache.startTime.set(hairsystem_start_time) diskcache.endTime.set(end_time) # set some sane defaults diskcache.enable.set(True) diskcache.samplingType.set(0) # TODO: may need to grab this from a revision attribute diskcache.samplingRate.set(1) diskcache.cacheType.set("mchp") diskcache.copyLocally.set(1) # set the filename if diskcache.cacheName.isLocked(): diskcache.cacheName.unlock() diskcache.cacheName.set(cache_filename) # need to lock it to prevent it from being changed on save diskcache.cacheName.lock() # not sure what this is for, but the cache is ignored if it's not set # following the naming convention maya uses: hidden1_namespace_hairSystemName.mchp if diskcache.hiddenCacheName.isLocked(): diskcache.hiddenCacheName.unlock() hidden_cache_name = "hidden1_" + namespace.replace(":", "_") + "_" + name + ".mchp" diskcache.hiddenCacheName.set(hidden_cache_name) # finally, connect the cache node to the hair system if not diskcache.diskCache.isConnected(): diskcache.diskCache.connect(hairsystem.diskCache)
def tankObject( self ): if ( self._tankAddress ): return tank.find(self._tankAddress.replace('Movie(','Frames(')).get_object() return None
def tankObject(self): if (self._tankAddress): return tank.find(self._tankAddress.replace( 'Movie(', 'Frames(')).get_object() return None
def determine_aux_data_from_vfs_path(path=None, tank_rev=None, project=None, include_shotgun_data=False): ''' Given the tank vfs path, return ex: {"context_type":"shot", "scene":"19d","shot":"19d_010"} include shotgun data will query additional shotgun information ''' TANK_VFS_ROOT = tank.util.config.virtual_tree.fuse_mount_point import FullContextSession if project==None: project = os.environ.get("DRD_JOB", "hf2") if not tank_rev: if path and path.startswith(TANK_VFS_ROOT): try: if os.path.isfile(path): tank_rev = tank.find(path) elif re.search("\.([0-9]+)_([0-9]+)\.[a-zA-Z0-9]+$", path): tank_rev = tank.find(path) else: tank_rev = tank.find(os.path.split(path)[0]) except: print "Warning: failed to find tank object from path %s" % path import traceback traceback.print_exc() elif re.search("/([0-9]+)/r([0-9]+)_", path): useless, rid = re.search("/([0-9]+)/r([0-9]+)_", path).groups() tank_rev = tank.server.Em().get_revision_by_id(int(rid)) tank_rev = tank.find(str(tank_rev)) if type(tank_rev)==tank.asset.tank_revision.TankRevision: tank_asset_rev = tank_rev tank_rev = tank_rev.get_object() # ensure the revision is from a tank render container if not tank_rev or not is_tank_render_container(project, tank_rev.get_asset()): return None # now we have the tank address, get the scene shot data_hash = determine_aux_data_from_tank_address_fast(str(tank_rev)) if data_hash.has_key("scene") and data_hash["scene"] and data_hash["shot"]: data_hash.update( { #"rev_name": tank_rev.get_name(), "context_type":"shot", 'tank_asset_rev_obj':tank_asset_rev, 'tank_rev_obj':tank_rev, 'tank_rev_id':(tank_rev.get_asset().get_id(), tank_rev.get_id()), }) if include_shotgun_data and FullContextSession.get_project().get_scene(data_hash["scene"]): c_shot = FullContextSession.get_project().get_scene(data_hash["scene"]).get_shot(data_hash["shot"], no_exception=True) if c_shot: data_hash["cut_range"] = c_shot.get_cut_info() data_hash["cut_order"] = c_shot.get_cut_order(as_string=True) data_hash["cut_order_index"] = c_shot.get_cut_order() return data_hash else: print "Warning: can not determine scene shot from address %s..." % tank_rev
def get_scene_shot_from_tank_address(address): asset = tank.find(address).asset return asset.labels["Scene"].system.name, asset.labels["SceneShot"].system.name
def get_scene_shot_from_tank_address(address): asset = tank.find(address).asset return asset.labels["Scene"].system.name, asset.labels[ "SceneShot"].system.name
def determine_aux_data_from_tank_address(tank_rev, include_shotgun_data=False): import tank if type(tank_rev) in (str,unicode): tank_rev = tank.find(tank_rev) return determine_aux_data_from_vfs_path(tank_rev = tank_rev, include_shotgun_data=include_shotgun_data )
def determine_aux_data_from_vfs_path(path=None, tank_rev=None, project=None, include_shotgun_data=False): ''' Given the tank vfs path, return ex: {"context_type":"shot", "scene":"19d","shot":"19d_010"} include shotgun data will query additional shotgun information ''' TANK_VFS_ROOT = tank.util.config.virtual_tree.fuse_mount_point import FullContextSession if project == None: project = os.environ.get("DRD_JOB", "hf2") if not tank_rev: if path and path.startswith(TANK_VFS_ROOT): try: if os.path.isfile(path): tank_rev = tank.find(path) elif re.search("\.([0-9]+)_([0-9]+)\.[a-zA-Z0-9]+$", path): tank_rev = tank.find(path) else: tank_rev = tank.find(os.path.split(path)[0]) except: print "Warning: failed to find tank object from path %s" % path import traceback traceback.print_exc() elif re.search("/([0-9]+)/r([0-9]+)_", path): useless, rid = re.search("/([0-9]+)/r([0-9]+)_", path).groups() tank_rev = tank.server.Em().get_revision_by_id(int(rid)) tank_rev = tank.find(str(tank_rev)) if type(tank_rev) == tank.asset.tank_revision.TankRevision: tank_asset_rev = tank_rev tank_rev = tank_rev.get_object() # ensure the revision is from a tank render container if not tank_rev or not is_tank_render_container(project, tank_rev.get_asset()): return None # now we have the tank address, get the scene shot data_hash = determine_aux_data_from_tank_address_fast(str(tank_rev)) if data_hash.has_key("scene") and data_hash["scene"] and data_hash["shot"]: data_hash.update({ #"rev_name": tank_rev.get_name(), "context_type": "shot", 'tank_asset_rev_obj': tank_asset_rev, 'tank_rev_obj': tank_rev, 'tank_rev_id': (tank_rev.get_asset().get_id(), tank_rev.get_id()), }) if include_shotgun_data and FullContextSession.get_project().get_scene( data_hash["scene"]): c_shot = FullContextSession.get_project().get_scene( data_hash["scene"]).get_shot(data_hash["shot"], no_exception=True) if c_shot: data_hash["cut_range"] = c_shot.get_cut_info() data_hash["cut_order"] = c_shot.get_cut_order(as_string=True) data_hash["cut_order_index"] = c_shot.get_cut_order() return data_hash else: print "Warning: can not determine scene shot from address %s..." % tank_rev
def __init__(self, parent=None, **kwargs): super(LabelCullProxyModel, self).__init__(parent, dynamicSortFilter=True, **kwargs) self._includeRevisionTypes = False self._validContainerTypes = frozenset(tank.find(ct) for ct in tank.list_container_types()) self._validRevisionTypes = frozenset(tank.find(rt) for rt in tank.list_revision_types()) self._selectionModel = None
def fetchMore(self): if self.children is None: return sorted([RevisionTypeItem(tank.find(rt), self) for rt in tank.list_revision_types()])
def fetchMore(self): if self.children is None: return sorted([ContainerTypeItem(tank.find(ct), self) for ct in tank.list_container_types()])
def __init__(self): super(RootItem, self).__init__() self.children = [RevisionMetaItem(self), ContainerMetaItem(self)] self.children.extend(sorted([LabelTypeItem(tank.find(lt), self) for lt in tank.list_label_types()]))