def testSoftSelection(self): # open maya file mayaFile = os.path.abspath('UsdReferenceAssemblySelectionTest.ma') cmds.file(mayaFile, open=True, force=True) # load all the assemblies self._LoadAll('Collapsed') # enable soft select with a medium radius OBJECT_MODE = 3 cmds.softSelect(softSelectEnabled=1, softSelectFalloff=OBJECT_MODE, softSelectDistance=4.0) centerCube = 'Cube_49' neighborCube = 'Cube_48' neighborFullName = cmds.ls(neighborCube, long=True)[0] cmds.select(centerCube) # make sure more than 1 thing was selected softSel = self._GetSoftSelection() self.assertEqual(len(softSel), 9) self.assertTrue(self._ContainsAssembly(neighborFullName, softSel)) # clear the selection cmds.select([]) # set one of the things nearby and make it expanded cmds.assembly(neighborCube, edit=True, active='Expanded') # select thing again. It should no longer include the thing that we've # made expanded. cmds.select(centerCube) softSel = self._GetSoftSelection() self.assertFalse(self._ContainsAssembly(neighborFullName, softSel))
def testAssemblyConnectedToTime(self): """ This tests that when the Playback representation of a USD reference assembly node is activated that its input time is connected to Maya's global time. Other representations should NOT have this connection. """ assemblyNode = self._SetupScene('CubeModel.usda', '/CubeModel') # Time should not be connected when no representation is active. self._AssertTimeIsNotConnected(assemblyNode) # Change representations to 'Collapsed' and validate. cmds.assembly(assemblyNode, edit=True, active='Collapsed') self._AssertTimeIsNotConnected(assemblyNode) # Change representations to 'Expanded' and validate. cmds.assembly(assemblyNode, edit=True, active='Expanded') self._AssertTimeIsNotConnected(assemblyNode) # Change representations to 'Full' and validate. cmds.assembly(assemblyNode, edit=True, active='Full') self._AssertTimeIsNotConnected(assemblyNode) # Change representations to 'Playback' and validate. cmds.assembly(assemblyNode, edit=True, active='Playback') self._AssertTimeIsConnected(assemblyNode) # Change representations to 'Collapsed' once more and validate. cmds.assembly(assemblyNode, edit=True, active='Collapsed') self._AssertTimeIsNotConnected(assemblyNode)
def CreateAssemblyDefinition_Def(*args): nameAs = cmds.textField('CreateAsName',query=True,text=True) #print nameAs cmds.assembly(name=str(nameAs)) print nameAs cmds.assembly(nameAs, edit=True, createRepresentation='Locator',repName=("myLocator"+'_'+nameAs), input=nameAs) AssemblySet_Selection(0)
def testGenerateImages(self): cmds.file(os.path.abspath('InstancerDrawTest.ma'), open=True, force=True) # Draw in VP2 at current frame. self._SetModelPanelsToViewport2() self._WriteViewportImage("InstancerTest", "initial") # Load assembly in "Cards" to use cards drawmode. cmds.assembly("CubeModel", edit=True, active="Cards") self._WriteViewportImage("InstancerTest", "cards") # Change the time; this will change the instancer positions. cmds.currentTime(50, edit=True) self._WriteViewportImage("InstancerTest", "frame50") # Delete the first instance. # Tickle the second instance so that it draws. # Note: it's OK that we need to tickle; the instancing support is not # the greatest and we're just checking that it doesn't break horribly. cmds.delete("instance1") cmds.setAttr("instance2.t", 15, 0, 0, type="double3") self._WriteViewportImage("InstancerTest", "instance2") # Delete the second instance. cmds.delete("instance2") self._WriteViewportImage("InstancerTest", "empty") # Reload the scene. We should see the instancer come back up. # Hopefully the instancer imager has reloaded in a sane way! cmds.file(os.path.abspath('InstancerDrawTest.ma'), open=True, force=True) self._SetModelPanelsToViewport2() self._WriteViewportImage("InstancerTest", "reload")
def getInformation(self): contents = '' for ar in cmds.ls(type=["assemblyReference"]): allADs = cmds.assembly(ar + ".representations", query=True, lr=True) tmpRpt = cmds.assembly(ar, query=True, active=True) if not allADs: continue if len(allADs) < 4: continue if len(set(["gpu.abc","box.mb","abc.abc"]) - set([x.lower().split("_")[-1] for x in allADs])) == 0\ or len(set(["gpu.abc","box.abc","abc.abc"]) - set([x.lower().split("_")[-1] for x in allADs])) == 0: temp = allADs[0].split("_") asset = '' for i in range(len(temp)): if i == len(temp) - 1: continue elif i == len(temp) - 2: asset += temp[i] else: asset += temp[i] + "_" label = ar cmds.select(ar) transform = cmds.xform(worldSpace=True, translation=True, query=True) rotation = cmds.xform(worldSpace=True, rotation=True, query=True) scale = cmds.xform(worldSpace=True, scale=True, query=True) contents += self.setContents(asset, label, transform, rotation, scale) return contents
def CreateAssemblyReference(*args): ''' multipleFilters = "All Files (*.*)" filename_AsDeifintion = cmds.fileDialog2(fileFilter=multipleFilters,fileMode=1, dialogStyle=2) #fileMode = 1 is Indicate what the dialog is to return.( A single existing file.) print filename_AsDeifintion ''' nameAsRef = cmds.textField('CreateAssemblyReference',query=True,text=True) cmds.assembly(name=(nameAsRef+'Reference'), type='assemblyReference')
def getConstrainAssemblyReferenceNew(): all_top_ars = list() if cmds.objExists('assets'): for grp in cmds.listRelatives('assets', c=1, f=1): try: for ar in cmds.listRelatives(grp, c=1, f=1): if cmds.nodeType(ar) == 'assemblyReference': all_top_ars.append(ar) except: pass all_parent_cons = list() connects_ars = list() for top_ar in all_top_ars: all_constraints = cmds.listRelatives(top_ar, ad=True, type='constraint') if all_constraints: for constraint in all_constraints: parent_con = cmds.listRelatives(constraint, p=1, f=1)[0] all_parent_cons.append(parent_con) parents = cmds.listRelatives(constraint, p=1, f=1)[0].split('|') parents.reverse() for p in parents: if p.endswith('_AR'): if cmds.objExists(p) and cmds.nodeType( p) == 'assemblyReference': if not is_asb(p): connects_ars.append(p) continue for parent_con in all_parent_cons: ars = cmds.listRelatives(parent_con, ad=1, f=1, type='assemblyReference') if ars: connects_ars.extend(ars) all_connects = list() for ar in list(set(connects_ars)): if is_asb(ar): act = cmds.assembly(ar, q=1, a=1) if act.endswith('.abc'): acts = cmds.assembly(ar, q=1, lr=1) for a in acts: if a.endswith('.ma'): cmds.assembly(ar, e=1, a=a) asb_c = cmds.listRelatives(ar, ad=1, type='assemblyReference') all_connects.extend(asb_c) else: all_connects.append(ar) all_connects_ars = list() for ar in all_connects: full = pm.PyNode(ar).fullPath() all_connects_ars.append(full) return all_connects_ars
def ExpandReferenceAssemblies(parentNodes=None): """ Activates the "Expanded" representation of USD reference assembly nodes. """ refAssemblies = GetReferenceAssemblies(parentNodes=parentNodes) for refAssembly in refAssemblies: try: cmds.assembly(refAssembly, edit=True, active='Expanded') except: cmds.warning('Failed to expand USD reference assembly: %s' % refAssembly)
def LoadReferenceAssemblies(parentNodes=None): """ Loads USD reference assembly nodes in the scene. USD reference assemblies that do not already have a representation activated will have their "Collapsed" representation activated. """ refAssemblies = GetReferenceAssemblies(parentNodes=parentNodes) numRefAssemblies = len(refAssemblies) if numRefAssemblies < 1: return mainProgressBar = _GetMainProgressBar() if mainProgressBar: cmds.progressBar(mainProgressBar, edit=True, beginProgress=True, isInterruptable=True, minValue=0, maxValue=numRefAssemblies, status='Loading USD reference assemblies...') for i in xrange(numRefAssemblies): refAssembly = refAssemblies[i] if mainProgressBar: shouldStop = cmds.progressBar(mainProgressBar, query=True, isCancelled=True) if shouldStop: cmds.warning('Cancelled loading USD reference assemblies') break cmds.progressBar(mainProgressBar, edit=True, status='Loading "%s" (%d of %d)' % (refAssembly, i, numRefAssemblies)) cmds.progressBar(mainProgressBar, edit=True, step=1) activeRep = cmds.assembly(refAssembly, query=True, active=True) if activeRep: continue try: cmds.assembly(refAssembly, edit=True, active='Collapsed') except: cmds.warning('Failed to load USD reference assembly: %s' % refAssembly) if mainProgressBar: cmds.progressBar(mainProgressBar, edit=True, endProgress=True)
def testImportCubeAnimatedModel(self): """ Tests that importing a cube model that has animation authored directly in the model brings in the animation correctly when the model is referenced into a set. """ nestedAssemblyNode = 'NS_Cube_set:AnimationDirectlyInModelCube' cmds.assembly(nestedAssemblyNode, edit=True, active='Full') cubeTransformDagNodePath = 'NS_Cube_set:NS_AnimationDirectlyInModelCube:Cube' self._AssertAnimation(cubeTransformDagNodePath, self.KEYFRAME_TIMES, self.KEYFRAME_VALUES)
def testImportCubeAnimationLayerWithModelReference(self): """ Tests that importing a cube model that is referenced by another layer that adds animation opinions brings in the animation correctly when the animation layer is referenced into a set. """ nestedAssemblyNode = 'NS_Cube_set:AnimationInLayerOnReferencedCube' cmds.assembly(nestedAssemblyNode, edit=True, active='Full') cubeTransformDagNodePath = 'NS_Cube_set:NS_AnimationInLayerOnReferencedCube:Cube' self._AssertAnimation(cubeTransformDagNodePath, self.KEYFRAME_TIMES, self.KEYFRAME_VALUES)
def testComplexSetAssemblyChangeReps(self): """ This tests that changing representations of a USD reference assembly node in Maya that references a complex hierarchy of different types of prims works as expected, including undo'ing and redo'ing representation changes. """ assemblyNode = self._SetupScene('ComplexSet.usda', '/ComplexSet') # No representation has been activated yet, so ensure the assembly node # has no children. self._ValidateUnloaded(assemblyNode) # Change representations to 'Collapsed' and validate. cmds.assembly(assemblyNode, edit=True, active='Collapsed') self._ValidateCollapsed(assemblyNode) # Change representations to 'Cards' and validate. cmds.assembly(assemblyNode, edit=True, active='Cards') self._ValidateCards(assemblyNode) # Change representations to 'Expanded' and validate. cmds.assembly(assemblyNode, edit=True, active='Expanded') self._ValidateComplexSetExpandedTopLevel(assemblyNode) # Change representations to 'Full' and validate. cmds.assembly(assemblyNode, edit=True, active='Full') self._ValidateComplexSetFullTopLevel(assemblyNode) # Undo and the node should be back to Expanded. cmds.undo() self._ValidateComplexSetExpandedTopLevel(assemblyNode) # Undo and the node should be back to Cards. cmds.undo() self._ValidateCards(assemblyNode) # Undo and the node should be back to Collapsed. cmds.undo() self._ValidateCollapsed(assemblyNode) # Undo once more and no representation should be active. cmds.undo() self._ValidateUnloaded(assemblyNode) # Redo and it's back to Collapsed. cmds.redo() self._ValidateCollapsed(assemblyNode) # Redo and it's back to Cards. cmds.redo() self._ValidateCards(assemblyNode) # Redo again and it's back to Expanded. cmds.redo() self._ValidateComplexSetExpandedTopLevel(assemblyNode) # Redo once more and it's back to Full. cmds.redo() self._ValidateComplexSetFullTopLevel(assemblyNode)
def testSimpleSceneDrawsAndReloads(self): # a memory issue would sometimes cause maya to crash when opening a new # scene. for _ in xrange(20): cmds.file(new=True, force=True) for i in xrange(10): usdFilePath = os.path.abspath('plane%d.usda' % (i%2)) assembly = cmds.assembly(name='plane', type='pxrUsdReferenceAssembly') cmds.setAttr("%s.filePath" % assembly, usdFilePath, type='string') cmds.assembly(assembly, edit=True, active='Collapsed') cmds.refresh() cmds.file(new=True, force=True)
def importAsset(self): '''Asset import to scene as Scene Assembly Reference''' currentType = self.ui.assetType_comboBox.currentText() currentAsset = self.ui.main_listWidget.currentItem().text() import_method = self.ui.importAs_comboBox.currentText() asset_pubDir = getInfo.assetPath + '/' + currentType + '/' + currentAsset + '/scenes/pub' # import as Assembly if import_method == self.import_asSAM: referenceNode_name = currentAsset + "_AD" definition_name = currentAsset + "_AD.ma" definition_Path = asset_pubDir + '/' + definition_name if not os.path.exists(definition_Path): print("Path not exist : " + definition_Path) return print("import : " + definition_Path) result = cmds.assembly(name=referenceNode_name + "_AR", type='assemblyReference') cmds.setAttr(result + ".definition", definition_Path, type="string") try: cmds.assembly(result, e=True, active='Render') except RuntimeError as e: print("skip : " + result) # import as Reference elif import_method == self.import_asREF: # Find pub_fileName = [ file for file in os.listdir(asset_pubDir) if file.endswith("_pub.ma") ] # Reference file if len(pub_fileName) == 1: cmds.file(asset_pubDir + '/' + pub_fileName[0], r=True) elif len(pub_fileName) > 1: ui_choosePubFile(pub_fileName, scenePath=asset_pubDir) else: print "Not have any publish file."
def testNestedAssemblyChangeReps(self): """ This tests that changing representations of a USD reference assembly node in Maya that references a hierarchy of assemblies works as expected, including undo'ing and redo'ing representation changes. """ assemblyNode = self._SetupScene('OneCube_set.usda', '/set') # No representation has been activated yet, so ensure the assembly node # has no children. self._ValidateUnloaded(assemblyNode) # Change representations to 'Collapsed' and validate. cmds.assembly(assemblyNode, edit=True, active='Collapsed') self._ValidateCollapsed(assemblyNode) # Change representations to 'Expanded' and validate. cmds.assembly(assemblyNode, edit=True, active='Expanded') self._ValidateNestedExpandedTopLevel(assemblyNode) # Change representations to 'Full' and validate. cmds.assembly(assemblyNode, edit=True, active='Full') self._ValidateNestedFullTopLevel(assemblyNode) # Undo and the node should be back to Expanded. cmds.undo() self._ValidateNestedExpandedTopLevel(assemblyNode) # Undo and the node should be back to Collapsed. cmds.undo() self._ValidateCollapsed(assemblyNode) # Undo once more and no representation should be active. cmds.undo() self._ValidateUnloaded(assemblyNode) # Redo and it's back to Collapsed. cmds.redo() self._ValidateCollapsed(assemblyNode) # Redo again and it's back to Expanded. cmds.redo() self._ValidateNestedExpandedTopLevel(assemblyNode) # Redo once more and it's back to Full. cmds.redo() self._ValidateNestedFullTopLevel(assemblyNode) # Now test changing representations of the sub-assembly. # Start by unloading the sub-assembly. childNodes = self._GetChildren(assemblyNode) nestedAssemblyNode = childNodes[0] cmds.assembly(nestedAssemblyNode, edit=True, active='') # From here, testing the nested assembly node should be the same as # testing a standalone model reference node. self._ValidateAllModelRepresentations(nestedAssemblyNode)
def _ValidateAllModelRepresentations(self, nodeName): """ Tests all representations of an assembly node that references a model (i.e. has no sub-assemblies). This should apply for both a standalone model reference node as well as a nested assembly reference node that references a model. """ # No representation has been activated yet, so ensure the assembly node # has no children. self._ValidateUnloaded(nodeName) # Change representations to 'Collapsed' and validate. cmds.assembly(nodeName, edit=True, active='Collapsed') self._ValidateCollapsed(nodeName) # Change representations to 'Cards' and validate. cmds.assembly(nodeName, edit=True, active='Cards') self._ValidateCards(nodeName) # Change representations to 'Expanded' and validate. cmds.assembly(nodeName, edit=True, active='Expanded') self._ValidateModelExpanded(nodeName) # Change representations to 'Full' and validate. cmds.assembly(nodeName, edit=True, active='Full') self._ValidateModelFull(nodeName) # Undo and the node should be back to Expanded. cmds.undo() self._ValidateModelExpanded(nodeName) # Undo and the node should be back to Cards. cmds.undo() self._ValidateCards(nodeName) # Undo and the node should be back to Collapsed. cmds.undo() self._ValidateCollapsed(nodeName) # Undo once more and no representation should be active. cmds.undo() self._ValidateUnloaded(nodeName) # Redo and it's back to Collapsed. cmds.redo() self._ValidateCollapsed(nodeName) # Redo and it's back to Cards. cmds.redo() self._ValidateCards(nodeName) # Redo again and it's back to Expanded. cmds.redo() self._ValidateModelExpanded(nodeName) # Redo once more and it's back to Full. cmds.redo() self._ValidateModelFull(nodeName)
def UnloadReferenceAssemblies(parentNodes=None): """ Unloads USD reference assembly nodes in the scene. """ refAssemblies = GetReferenceAssemblies(parentNodes=parentNodes) for refAssembly in refAssemblies: if not cmds.objExists(refAssembly): # Unloading a parent assembly may have caused the child assembly # to go away. continue try: cmds.assembly(refAssembly, edit=True, active='') except: cmds.warning('Failed to unload USD reference assembly: %s' % refAssembly)
def setUp(self): cmds.file(new=True, force=True) self.assemblyNodeName = cmds.assembly(name='TestAssemblyNode', type='pxrUsdReferenceAssembly') cmds.setAttr('%s.filePath' % self.assemblyNodeName, self.usdFile, type='string') cmds.setAttr('%s.primPath' % self.assemblyNodeName, self.primPath, type='string')
def AssemblySet_Selection(val): myinput = int(val) print myinput Assembly_set = cmds.ls(selection=True) #print Assembly_set As_position = 0 for i in Assembly_set: #print i print (Assembly_set[As_position]) #As_position = (As_position+1) As_Check = cmds.assembly(Assembly_set[As_position], query=True, listRepresentations=True) #check list of Representations print As_Check[myinput] cmds.assembly(Assembly_set[As_position],edit=True,active=As_Check[myinput]) As_position = As_position + 1
def testDrawCubeRepresentations(self): """ Tests drawing USD proxy shapes while changing the assembly representation. """ self._testName = 'RefAssemblyDrawRepresentationsTest' mayaSceneFile = '%s.ma' % self._testName mayaSceneFullPath = os.path.abspath(mayaSceneFile) cmds.file(mayaSceneFullPath, open=True, force=True) UsdMaya.LoadReferenceAssemblies() for representation in ['Cards', 'Collapsed', 'Expanded', 'Full', 'Playback']: cmds.assembly('Cube_1', edit=True, active=representation) self._WriteViewportImage(self._testName, representation)
def set_active(self, rep, selected=None, not_include_hide=True): ar_nodes = self.get_all_ar_nodes(selected) for ar_node in ar_nodes: if not_include_hide: if not pm.PyNode(ar_node).isVisible(): print "%s is not visible" % ar_node continue reps = mc.assembly(ar_node, q=1, listRepresentations=1) if rep not in reps: print "%s not in the representations of node %s" % (rep, ar_node) continue active_label = mc.assembly(ar_node, q=1, activeLabel=1) if active_label == rep: print "%s current active label is %s" % (ar_node, rep) continue mc.assembly(ar_node, e=1, activeLabel=rep)
def testMeshNextToAssemblyAndImported(self): """ Tests the colors between a mesh with (0.55, 0.55, 0.55) exporting that file and then re-importing it, and also referencing it back into the same scene. While this is a bit more than just "GL" testing, it's a useful place to centralize all this. If we don't like that this is testing usdImport functionality, we can remove This will render as follows: blank | usdImport | ---------+----------- modeled | ref'd | """ x = self._PlaneWithColor((0.55, 0.55, 0.55)) cmds.loadPlugin('pxrUsd') cwd = os.path.abspath('.') usdFile = os.path.join(cwd, 'plane.usd') cmds.select(x) cmds.usdExport(file=usdFile, selection=True, shadingMode='displayColor') assembly = cmds.assembly(name='ref', type='pxrUsdReferenceAssembly') cmds.xform(assembly, translation=(30.48, 0, 0)) cmds.setAttr('%s.filePath' % assembly, usdFile, type='string') cmds.setAttr('%s.primPath' % assembly, '/pPlane1', type='string') cmds.assembly(assembly, edit=True, active='Collapsed') x = cmds.usdImport(file=usdFile) cmds.xform(x, translation=(30.48, 30.48, 0)) cmds.setAttr("hardwareRenderingGlobals.floatingPointRTEnable", 0) cmds.setAttr('defaultColorMgtGlobals.outputTransformEnabled', 0) self._Snapshot('default') cmds.setAttr("hardwareRenderingGlobals.floatingPointRTEnable", 1) cmds.setAttr('defaultColorMgtGlobals.outputTransformEnabled', 1) self._Snapshot('colorMgt')
def create_representation(node, rep_type, rep_name, rep_label, input_path): if not mc.objExists(node): logger.error("%s does not exist." % node) return all_representation = mc.assembly(node, q=1, listRepresentations=1) if all_representation and rep_name in all_representation: logger.warning("%s in the representation" % rep_name) return mc.assembly(node, e=1, createRepresentation=rep_type, repName=rep_name, input=input_path) all_representation = mc.assembly(node, q=1, listRepresentations=1) index = all_representation.index(rep_name) if rep_label: mc.setAttr("%s.rep[%s].rla" % (node, index), rep_label, type="string")
def setUpClass(cls): standalone.initialize('usd') cmds.loadPlugin('pxrUsd', quiet=True) usdFile = os.path.abspath('%s.usda' % cls.SET_NAME) primPath = '/%s' % cls.SET_NAME assemblyNode = cmds.createNode('pxrUsdReferenceAssembly', name=cls.SET_NAME) cmds.setAttr("%s.filePath" % assemblyNode, usdFile, type="string") cmds.setAttr("%s.primPath" % assemblyNode, primPath, type="string") # The set layer specifies a frame range of 101-149, so when we activate # the 'Full' representation and trigger an import, we expect the # current frame range in Maya to be expanded to include that. We set # it to something inside that range now so we can make sure that that # happens. OMA.MAnimControl.setAnimationStartEndTime(OM.MTime(121), OM.MTime(130)) cmds.assembly(assemblyNode, edit=True, active='Full')
def setActiveRep(assemblyNodes, name): ''' set active representations ''' amount = len(assemblyNodes) exclude_nodes = cmds.textScrollList("exclude_list", q=True, allItems=True) exclude_nodes = exclude_nodes if exclude_nodes != None else list() print amount progress = cmds.progressWindow(title='Switching...', progress=0, max=int(amount), isInterruptable=True) cmds.refresh() for indx, asm in enumerate(assemblyNodes): # Check progress bar cancelation if cmds.progressWindow(progress, query=True, isCancelled=True): break is_ignore = True if asm in exclude_nodes else False try: if cmds.assembly(asm, q=True, active=True) != name and not is_ignore: cmds.assembly(asm, e=True, active=name) except RuntimeError as e: print("RuntimeError > skip : " + asm) except TypeError as e: print("TypeError > skip : " + asm) except ValueError as e: print("ValueError > skip : " + asm) cmds.progressWindow(progress, edit=True, step=1, status=('Switching to ' + name + ' : ' + str(indx + 1) + '/' + str(amount))) # if cmds.progressWindow( progress, query=True, progress=True ) >= 100 : cmds.progressWindow(progress, endProgress=True)
def get_all_reps(self, selected=None): ar_nodes = self.get_all_ar_nodes(selected) if not ar_nodes: return all_reps = list() for node in ar_nodes: reps = mc.assembly(node, q=1, listRepresentations=1) if not reps: continue all_reps.extend(reps) all_reps = list(set(all_reps)) return all_reps
def get_all_ar_files(): files = list() ar_nodes = mc.ls(type="assemblyReference") if ar_nodes: for node in ar_nodes: reps = mc.assembly(node, q=1, listRepresentations=1) if not reps: continue for index, rep in enumerate(reps): file_path = mc.getAttr("%s.rep[%s].rda" % (node, index)) files.append(file_path) return files
def testModelNoDefaultPrimChangeReps(self): """ This validates the behavior of changing representation of a USD reference assembly node in Maya that references a model when the USD file being referenced does NOT specify a default prim. In this case, switching to Expanded or Full representations will ONLY work when the assembly node provides the prim path. """ assemblyNode = self._SetupScene('CubeModel_NoDefaultPrim.usda', '/CubeModel') self._ValidateAllModelRepresentations(assemblyNode) assemblyNodeNoPrimPath = self._SetupScene('CubeModel_NoDefaultPrim.usda') self._ValidateUnloaded(assemblyNodeNoPrimPath) # Change representations to 'Collapsed' and validate. This should work. cmds.assembly(assemblyNodeNoPrimPath, edit=True, active='Collapsed') self._ValidateCollapsed(assemblyNodeNoPrimPath) # Change representations to 'Expanded'. This should fail and we should # end up with nothing below the assembly (same as unloaded). cmds.assembly(assemblyNodeNoPrimPath, edit=True, active='Expanded') self._ValidateUnloaded(assemblyNodeNoPrimPath) # Change representations to 'Full'. Should be the same as 'Expanded'. cmds.assembly(assemblyNodeNoPrimPath, edit=True, active='Full') self._ValidateUnloaded(assemblyNodeNoPrimPath)
def testNestedAssembliesWithVariantSetsChangeReps(self): """ This tests that changing representations of a hierarchy of USD reference assembly nodes in Maya works as expected when the referenced prims have variant sets. """ assemblyNode = self._SetupScene('SetWithModelingVariants_set.usda', '/SetWithModelingVariants_set') # Set the modelingVariant on the top-level assembly to the one that has # child prims. varSetAttrName = 'usdVariantSet_modelingVariant' cmds.addAttr(assemblyNode, ln=varSetAttrName, dt='string', internalSet=True) cmds.setAttr('%s.%s' % (assemblyNode, varSetAttrName), 'Cubes', type='string') # No representation has been activated yet, so ensure the assembly node # has no children. self._ValidateUnloaded(assemblyNode) # Change representations to 'Collapsed' and validate. cmds.assembly(assemblyNode, edit=True, active='Collapsed') self._ValidateCollapsed(assemblyNode) # Change representations to 'Cards' and validate. cmds.assembly(assemblyNode, edit=True, active='Cards') self._ValidateCards(assemblyNode) # Change representations to 'Expanded' and validate. cmds.assembly(assemblyNode, edit=True, active='Expanded') childNodes = self._GetChildren(assemblyNode) cubesGroupNode = childNodes[0] childNodes = self._GetChildren(cubesGroupNode) cubeOneAssemblyNode = childNodes[0] # XXX: This test should be expanded to cover more combinations of # representations like the other tests do, but more work is needed to # ensure that variant set selections work correctly with hierarchies of # assemblies. # For example, this model reference assembly does not currently behave # correctly when it appears because it is in a variant selection of a # parent assembly. For now, we just make sure that it doesn't crash # like it used to. # self._ValidateAllModelRepresentations(cubeOneAssemblyNode) cmds.assembly(cubeOneAssemblyNode, edit=True, active='Expanded')
def CollapseReferenceAssemblies(parentNodes=None): """ Activates the "Collapsed" representation of USD reference assembly nodes. Note that assemblies that have no representation activated are ignored. """ refAssemblies = GetReferenceAssemblies(parentNodes=parentNodes) for refAssembly in refAssemblies: if not cmds.objExists(refAssembly): # Collapsing a parent assembly may have caused the child assembly # to go away. continue activeRep = cmds.assembly(refAssembly, query=True, active=True) if not activeRep: continue try: cmds.assembly(refAssembly, edit=True, active='Collapsed') except: cmds.warning('Failed to collapse USD reference assembly: %s' % refAssembly)
def testAssemblyEditsAfterRename(self): """ Tests that assembly edits made prior to a rename are still present on the assembly after it has been renamed. """ # Create the initial assembly and activate its 'Full' representation. assemblyNodeName = self._CreateAssemblyNode() cmds.assembly(assemblyNodeName, edit=True, active='Full') # Make an edit on a node inside the assembly. self._MakeAssemblyEdit(assemblyNodeName, 'Cube') # Now do the rename. cmds.rename(assemblyNodeName, 'FooBar') editPath = Sdf.Path('Geom/Cube') # Because the rename does not change the 'repNamespace' attribute on # the assembly, it should still be the same as it was before the rename. refEdit = self._GetAssemblyEdit('FooBar', editPath) expectedEditString = 'setAttr "NS_TestAssemblyNode:Geom|NS_TestAssemblyNode:Cube.translateX" 5' self.assertEqual(refEdit.editString, expectedEditString)
def testDisjointAssembliesVariantSetsChange(self): """ Tests that changing a variant set in a nested assembly |A1|B does not affect the variant sets on a different nested assembly |A2|B where A1 and A2 reference the same model. """ cmds.file(new=True, force=True) usdFile = os.path.abspath("OneCube_set.usda") primPath = "/set" assemblyNodes = [] for name in ["assembly1", "assembly2"]: assemblyNode = cmds.assembly( name=name, type=self.ASSEMBLY_TYPE_NAME) cmds.setAttr("%s.filePath" % assemblyNode, usdFile, type='string') cmds.setAttr("%s.primPath" % assemblyNode, primPath, type='string') cmds.assembly(assemblyNode, edit=True, active='Expanded') assemblyNodes.append(assemblyNode) cube1 = 'NS_%s:Cube_1' % assemblyNodes[0] self.assertTrue(cmds.objExists(cube1)) cube2 = 'NS_%s:Cube_1' % assemblyNodes[1] self.assertTrue(cmds.objExists(cube2)) cmds.setAttr('%s.usdVariantSet_shadingVariant' % cube1, 'Blue', type='string') prim1 = UsdMaya.GetPrim(cube1) self.assertEqual( prim1.GetVariantSet('shadingVariant').GetVariantSelection(), 'Blue') prim2 = UsdMaya.GetPrim(cube2) self.assertEqual( prim2.GetVariantSet('shadingVariant').GetVariantSelection(), 'Default')
def _CreateAssemblyNode(nodeName='TestAssemblyNode'): """ Creates a model reference assembly node for testing. """ ASSEMBLY_TYPE_NAME = 'pxrUsdReferenceAssembly' assetName = 'CubeModel' usdFile = os.path.abspath('%s.usda' % assetName) primPath = '/%s' % assetName assemblyNodeName = cmds.assembly(name=nodeName, type=ASSEMBLY_TYPE_NAME) cmds.setAttr('%s.filePath' % assemblyNodeName, usdFile, type='string') cmds.setAttr('%s.primPath' % assemblyNodeName, primPath, type='string') return assemblyNodeName
def _SetupScene(self, usdFilePath, primPath=None): """ Sets up the test scene with an assembly node for the given usdFilePath and primPath and returns the name of the assembly node. """ ASSEMBLY_NODE_NAME = 'TestAssemblyNode' cmds.file(new=True, force=True) usdFile = os.path.abspath(usdFilePath) assemblyNode = cmds.assembly(name=ASSEMBLY_NODE_NAME, type=self.ASSEMBLY_TYPE_NAME) cmds.setAttr("%s.filePath" % assemblyNode, usdFile, type='string') if primPath: cmds.setAttr("%s.primPath" % assemblyNode, primPath, type='string') self.assemNamespace = 'NS_%s' % assemblyNode return assemblyNode
def _publish_assemblyDefinition_for_item(self, mytasks, item, output, work_template, primary_publish_path, sg_task, comment, thumbnail_path, progress_cb): """ Export a gpu cache for the specified item and publish it to Shotgun. """ group_name = item["name"].strip("|") tank_type = output["tank_type"] publish_template = output["publish_template"] # get the current scene path and extract fields from it # using the work template: scene_path = os.path.abspath(cmds.file(query=True, sn= True)) fields = work_template.get_fields(scene_path) publish_version = fields["version"] # update fields with the group name: fields["grp_name"] = group_name ## create the publish path by applying the fields ## with the publish template: publish_path = publish_template.apply_fields(fields) ## GET THE PREVIOUS SECONDARY PATHS NOW myAlembicFilePath = '' myBoundingBoxSceneFilePath = '' myGPUFilePath = '' myMayaScenePath = primary_publish_path.replace('\\', '/') ## Now fetch these paths by processing each secondary outputs publishPath again for eachSecondary in mytasks: sec_item = eachSecondary["item"] sec_output = eachSecondary["output"] sec_group_name = sec_item["name"].strip("|") sec_tank_type = sec_output["tank_type"] sec_publish_template = sec_output["publish_template"] # get the current scene path and extract fields from it # using the work template: sec_scene_path = os.path.abspath(cmds.file(query=True, sn= True)) sec_fields = work_template.get_fields(sec_scene_path) sec_publish_version = sec_fields["version"] # update fields with the group name: sec_fields["grp_name"] = group_name ## create the publish path by applying the fields ## with the publish template: sec_publish_path = sec_publish_template.apply_fields(sec_fields) if sec_output["name"] == "alembic_cache": myAlembicFilePath = (sec_publish_path).replace('\\', '/') elif sec_output["name"] == 'bounding_box': myBoundingBoxSceneFilePath = (sec_publish_path).replace('\\', '/') elif sec_output["name"] == 'gpu_cache': myGPUFilePath = (sec_publish_path).replace('\\', '/') else: pass # print myAlembicFilePath # print myBoundingBoxSceneFilePath # print myGPUFilePath # print myMayaScenePath ## build and execute the assembly definition export command for this item: try: self.parent.log_debug("Executing scene assembly export now to: \n\t\t%s" % publish_path) print '=====================' print 'Publishing scene assembly now to %s' % publish_path try: assemblyName = '%s_ADEF' % group_name.split('_hrc')[0] cmds.assembly(n = assemblyName) print 'AssemblyDef created: \t %s' % assemblyName except: raise TankError("Scene Assembly plugin not loaded!!") #cmds.assembly(assemblyName, edit = True, createRepresentation = 'Locator') ## No point, as we're modeling to world positions. cmds.assembly(assemblyName, edit = True, input = myGPUFilePath, createRepresentation = 'Cache') cmds.assembly(assemblyName, edit = True, input = myAlembicFilePath, createRepresentation = 'Cache') cmds.assembly(assemblyName, edit = True, input = myBoundingBoxSceneFilePath, createRepresentation = 'Scene') cmds.assembly(assemblyName, edit = True, input = myMayaScenePath, createRepresentation = 'Scene') myRepresentations = cmds.assembly(assemblyName, query = True, listRepresentations = True) print 'Added Representations: \t%s' % myRepresentations for x in range(0, len(myRepresentations)): getRepName = cmds.getAttr("%s.representations[%s].repName" % (assemblyName, x)) getRepData = cmds.getAttr("%s.representations[%s].repData" % (assemblyName, x)) getRepLabel = cmds.getAttr("%s.representations[%s].repLabel" % (assemblyName, x)) getRepType = cmds.getAttr("%s.representations[%s].repType" % (assemblyName, x)) if 'alembic' in getRepData: cmds.setAttr("%s.representations[%s].repLabel" % (assemblyName, x), 'alembicCache', type = 'string') cmds.setAttr("%s.representations[%s].repName" % (assemblyName, x), 'alembicCache', type = 'string') elif 'gpu' in getRepData: cmds.setAttr("%s.representations[%s].repLabel" % (assemblyName, x), 'gpuCache', type = 'string') cmds.setAttr("%s.representations[%s].repName" % (assemblyName, x), 'gpuCache', type = 'string') elif 'bbox' in getRepData: cmds.setAttr("%s.representations[%s].repLabel" % (assemblyName, x), 'bbox', type = 'string') cmds.setAttr("%s.representations[%s].repName" % (assemblyName, x), 'bbox', type = 'string') elif 'maya' in getRepData: cmds.setAttr("%s.representations[%s].repLabel" % (assemblyName, x), 'full', type = 'string') cmds.setAttr("%s.representations[%s].repName" % (assemblyName, x), 'full', type = 'string') # if 'Locator' in getRepType: # cmds.setAttr("%s.representations[%s].repLabel" % (assemblyName, x), 'locator', type = 'string') print 'Done setting representation labels.' cmds.assembly(assemblyName, edit = True, active = 'gpuCache') print 'Done setting active to gpuCache.' ##Now set the auxNodes to something that won't clash during a shot build!! bad = ['hyperLayout', 'hyperGraphInfo', 'hyperView'] for each in bad: print "CHECKING FOR ASSEMBLY DEFINITION HYPERLAYOUTS NOW" for eachNaughty in cmds.ls(type = each): try: getAdef = cmds.listConnections(eachNaughty) if getAdef: if '_ADEF' in getAdef[0]: print 'Renamed %s to %s' % (eachNaughty, '%s_%s' % (getAdef[0], each)) cmds.rename(eachNaughty, '%s_%s' % (getAdef[0], each)) except TypeError: pass ## Now do the export cmds.select(assemblyName, r = True) print 'Exporting sceneAssemblyDefinition: \t %s' % publish_path cmds.file(publish_path, options = "v=0;", typ = "mayaAscii", es = True , force = True) cmds.delete(assemblyName) print 'Finished scene assembly publish...' print '=====================' except Exception, e: raise TankError("Failed to export scene assembly definition %s" % e)
def _upResAssemblyRefs(self, aRef): if cmds.nodeType(aRef) == 'assemblyReference': ## Check to see what isn't loaded to full res for exporting. Those that are not turn them to full res now for cache exporting. if not cmds.assembly(aRef, query = True, active = True) == 'full': cmds.assembly(aRef, edit = True, active = 'full')
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 = cmds.file(query=True, sn= True) 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}) ## ANIM CURVES ## If shot step is animation only not layout if 'Anm' in scene_name.split('/'): ## ATOM items.append({"type":"anim_atom", "name":"Animation Curves"}) ## CREASE XML items.append({"type":"crease_xml", "name":"Crease XML"}) ## Delete any stack .type hrc children of those roots that already have .type caches_type = [each for each in cmds.ls(type = 'transform') if cmds.objExists('%s.type' % each) if 'anim' in str(cmds.getAttr('%s.type' % each)) or 'static' in str(cmds.getAttr('%s.type' % each))] for each in caches_type: descendents_hrc = cmds.listRelatives(each, allDescendents = True, type = 'transform', fullPath = True) stack = [x for x in descendents_hrc if cmds.objExists('%s.type' % x) if 'anim' in str(cmds.getAttr('%s.type' % x)) or 'static' in str(cmds.getAttr('%s.type' % x))] if descendents_hrc else None [cmds.deleteAttr('%s.type' % hrc) for hrc in stack] if stack else None ## Make sure all definitions necessary are at FULL RES for alembic exporting! for each in cmds.ls(transforms = True): myType = '' if cmds.nodeType(each) == 'assemblyReference': ## FIRST Check to see what the active state is of the assembly reference node ## If it is still on GPU add this for gpu rendering ## Else look for what type of building it is for the alembic caching ## GPU CACHES if cmds.assembly(each, query = True, active = True) == 'gpuCache': if 'Anm' in scene_name.split('/'): cmds.assembly(each, edit = True, active = 'full') if cmds.getAttr( '%s.type' % cmds.listRelatives(each, children = True, fullPath = True)[0] ) == 'animBLD': items.append( {"type":"anim_caches", "name":each} ) else: items.append( {"type":"static_caches", "name":each} ) else: ## FULL GEO RIGGED OR STATIC ## Check what type is its. Static or Animated try: for eachChild in cmds.listRelatives(each, children = True): try: myType = cmds.getAttr('%s.type' % eachChild) except ValueError: print '%s is not set to a valid assemblyReference type to query for export...' % eachChild pass ## RIGGED BLD -- Now get the rigged buildings if myType == 'animBLD': ## Now put the Assembly References into items, remember the type is set to match the shot_step.yml secondary output type! items.append({"type":"anim_caches", "name":each}) ## STATIC BLD -- Now get the static buildings elif myType == 'staticBLD': ## Now put the Assembly References into items, remember the type is set to match the shot_step.yml secondary output type! items.append({"type":"static_caches", "name":each}) elif myType == 'staticLND': ## Now put the Assembly References into items, remember the type is set to match the shot_step.yml secondary output type! items.append({"type":"static_caches", "name":each}) else: pass except: pass else: try: myType = cmds.getAttr('%s.type' % each) ## FLUIDS -- Now get the fluid containers ## caches = [CONST.FOAM_FLUID_SHAPENODE, CONST.WAKE_FLUID_SHAPENODE, CONST.INTERACTIVE_WAKE_FLUID_SHAPENODE, CONST.INTERACTIVE_FOAM_FLUID_SHAPENODE] if 'oceanWakeFoamTexture' in myType or 'oceanWakeTexture' in myType: items.append({"type":"fluid_caches", "name":'%sShape' % each}) if myType == 'fx': items.append({"type":"fx_caches", "name":each}) ## CAMERA -- Now get the camera elif myType == 'shotCam' or myType == 'shotcam': items.append({"type":"camera", "name":each}) ## REFERENCES -- Now process the references to get their types elif myType == 'animCHAR' or myType == 'char': items.append({"type":"anim_caches", "name":each}) elif myType == 'animPROP': items.append({"type":"anim_caches", "name":each}) elif myType == 'animBLD' and '_ADef_' not in each: items.append({"type":"anim_caches", "name":each}) elif myType == 'staticPROP': items.append({"type":"static_caches", "name":each}) elif myType == 'staticCHAR': items.append({"type":"static_caches", "name":each}) else: pass except: pass ## Check if the ocean exists..if it does do some work... if cmds.objExists('OCEAN_hrc'): ## Hide the preview planes cmds.setAttr('oceanPreviewPlane_prv.visibility', 1) cmds.setAttr('animPreviewPlane_prv.visibility', 0) ## Now make sure the wakes are calculating #cmds.setAttr('OCEAN_hrc.oceanCalcOnOff', 0) ## Now set the ocean preview plane res to something very low and fast to calc cmds.setAttr('OCEAN_hrc.oceanRes', 1) else: raise TankError("MAYA OCEAN IS MISSING FROM YOUR SHOT!!! YOU SHOULD FIX THIS BEFORE PUBLISHING TO LIGHTING!!!!!!") cleanup.turnOnModelEditors() ## Now delete any groups from the parenting tool for each in cmds.ls(transforms = True): if 'tmXML' in each: cmds.delete(each) ## NOW ADD THE TAGS FOR CREASES TO BE EXPORTED CORRECTLY ## NEED TO DO THIS LONG WAY IN CASE THE ATTR ALREADY EXISTS AND FAILS>. for each in cmds.ls(type = 'mesh', l = True): if not cmds.objExists('%s.SubDivisionMesh' % each): try: cmds.addAttr('%s' % each, ln = 'SubDivisionMesh', at = 'bool') cmds.setAttr("%s.SubDivisionMesh" % each, 1) except: pass ## Check if cacheFiles exist and if yes, delete all of those. [cmds.delete(cache) for cache in cmds.ls(type = 'cacheFile')] [cmds.delete(cache) for cache in cmds.ls(type = 'cacheBlend')] ## remove unknown nodes from scene cleanup.cleanupUnknown() ## NOW MOVE ON TO PUBLISHING STEPS check_static_caches = [each['name'] for each in items if each['type'] == 'static_caches'] if not check_static_caches: return items else: setName = 'static_caches_set' cmds.delete(setName) if cmds.objExists(setName) else None ## Delete sets first cmds.sets(check_static_caches, name = setName) if check_static_caches else None ## Attach statics into newly created set cmds.confirmDialog(title = 'STATIC CACHES DETECTED!', message = 'All the statics are stored inside the "%s" set inside the outliner.\n\n1. Use the BBB Tool "CleanOut Static ENV"\n2. Check if animated building is tagged wrongly as static\n\nIf 2, scene breakdown or ask rigger to republish!' % setName, button = 'OK!', backgroundColor = [1, 0.3, 0.3])
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 = cmds.file(query=True, sn= True) 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}) ## Make sure all definitions are at FULL RES for alembic exporting. for each in cmds.ls(transforms = True): myType = '' if cmds.nodeType(each) == 'assemblyReference': ## FIRST Check to see what the active state is of the assembly reference node ## If it is still on GPU add this for gpu rendering ## Else look for what type of building it is for the alembic caching ## GPU CACHES if cmds.assembly(each, query = True, active = True) == 'gpuCache': items.append({"type":"gpu_caches", "name":each}) else: ## FULL GEO RIGGED OR STATIC ## Check what type is its. Static or Animated try: for eachChild in cmds.listRelatives(each, children = True): try: myType = cmds.getAttr('%s.type' % eachChild) except ValueError: print '%s is not set to a valid assemblyReference type to query for export...' % eachChild pass ## RIGGED BLD -- Now get the rigged buildings if myType == 'animBLD': ## Now put the Assembly References into items, remember the type is set to match the shot_step.yml secondary output type! items.append({"type":"anim_caches", "name":each}) ## STATIC BLD -- Now get the static buildings elif myType == 'staticBLD': ## Now put the Assembly References into items, remember the type is set to match the shot_step.yml secondary output type! items.append({"type":"static_caches", "name":each}) elif myType == 'staticLND': ## Now put the Assembly References into items, remember the type is set to match the shot_step.yml secondary output type! items.append({"type":"static_caches", "name":each}) else: pass except: pass else: try: myType = cmds.getAttr('%s.type' % each) ## FLUIDS -- Now get the fluid containers # if myType == 'oceanWakeFoamTexture' or myType == 'oceanWakeTexture': # items.append({"type":"fx_caches", "name":'%sShape' % each}) if myType == 'fx': items.append({"type":"fx_caches", "name":each}) ## CAMERA -- Now get the camera elif myType == 'shotCam' or myType == 'shotcam': items.append({"type":"camera", "name":each}) ## REFERENCES -- Now process the references to get their types elif myType == 'animCHAR' or myType == 'char': items.append({"type":"anim_caches", "name":each}) elif myType == 'animPROP': items.append({"type":"anim_caches", "name":each}) elif myType == 'staticPROP': items.append({"type":"static_caches", "name":each}) elif myType == 'staticCHAR': items.append({"type":"static_caches", "name":each}) else: pass except: pass ## NPARTICLES for eachNpart in cmds.ls(type = 'nParticle'): ## Now put the fx nodes to be cached into items, remember the type is set to match the shot_step.yml secondary output type! items.append({"type":"nparticle_caches", "name":eachNpart}) ## Now turn off all the modelEditors to speed up exporting ## cleanup.turnOffModelEditors() ## Check if the ocean exists..if it does do some work... if cmds.objExists('OCEAN_hrc'): ## Hide the preview planes cmds.setAttr('oceanPreviewPlane_prv.visibility', 0) cmds.setAttr('animPreviewPlane_prv.visibility', 0) ## Now make sure the wakes are calculating #cmds.setAttr('OCEAN_hrc.oceanCalcOnOff', 0) ## Now set the ocean preview plane res to something very low and fast to calc cmds.setAttr('OCEAN_hrc.oceanRes', 1) else: raise TankError("MAYA OCEAN IS MISSING FROM YOUR SHOT!!! YOU SHOULD FIX THIS BEFORE PUBLISHING TO LIGHTING!!!!!!") cleanup.turnOnModelEditors() ## Cleanup panels so nParticles don't keep crashing on export. # for each in cmds.lsUI(panels = True): # if 'outlinerPanel' in each or 'nodeEditorPanel' in each: # cmds.deleteUI(each, panel = True) cleanup.cleanupUnknown() ## NOW MOVE ON TO PUBLISHING STEPS return items
def _LoadAll(self, assemblyMode): for a in cmds.ls(type='pxrUsdReferenceAssembly'): cmds.assembly(a, edit=True, active=assemblyMode)
def run_app(self): """ Callback from when the menu is clicked. """ ## Tell the artist to be patient... eg not genY inprogressBar = pbui.ProgressBarUI(title = 'Fetching all shot assets:') inprogressBar.show() inprogressBar.updateProgress(percent = 5, doingWhat = 'Processing scene info...') #self.dbWrap = DoubleBarrel #self.sg = doubleBarrelWrapper._getShotgunObject(self.dbWrap, self) ## Instantiate the API tk = sgtk.sgtk_from_path("T:/software/bubblebathbay") debug(app = self, method = 'run_app', message = 'API instanced...\n%s' % tk, verbose = False) debug(app = self, method = 'run_app', message = 'Fetch Shot Assets launched...', verbose = False) context = self.context ## To get the step debug(app = self, method = 'run_app', message = 'context: %s' % context, verbose = False) debug(app = self, method = 'run_app', message = 'context Step...%s' % context.step['name'], verbose = False) if context.step['name'] == 'Anm' or context.step['name'] == 'Blocking' or context.step['name'] == 'Light': ## Build an entity type to get some values from. entity = self.context.entity ## returns {'type': 'Shot', 'name': 'ep100_sh010', 'id': 1166} debug(app = self, method = 'run_app', message = 'entity... %s' % entity, verbose = False) ## Filter for the matching ID for the shot sg_filters = [["id", "is", entity["id"]]] debug(app = self, method = 'run_app', message = 'sg_filters... %s' % sg_filters, verbose = False) ## Build an entity type to get some values from. sg_entity_type = self.context.entity["type"] ## returns Shot debug(app = self, method = 'run_app', message = 'sg_entity_type...\n%s' % sg_entity_type, verbose = False) ## DATA #import time #start = time.time() data = self.shotgun.find_one(sg_entity_type, filters=sg_filters, fields=['assets']) #data = self.dbWrap.find_one(self.sg, sg_entity_type, sg_filters, ['assets']) #print 'TIME: %s' % (time.time()-start) debug(app = self, method = 'run_app', message = 'Assets...\n%s' % data['assets'], verbose = False) ## Set the template to the maya publish folder maya_assetRootTemplate = tk.templates[self.get_setting('sg_AssetTemplate')] debug(app = self, method = 'run_app', message = 'Asset template...\n%s' % maya_assetRootTemplate, verbose = False) ### NOTE: ### ALL CHARS MUST BE RIGGED ### ALL PROPS MUST BE RIGGED ### ALL BLDS SHOULD BE PUBLISHED TO AN ENV as well as ALL LND ### ALL ROOT_HRC GROUPS SHOULD BE CASE SENSITIVE SUCH AS CHAR_Sydney_hrc ## Set model panel to show None before fetch asset modelPanels = cmds.getPanel(type = 'modelPanel') if modelPanels: [cmds.modelEditor(mp, edit = True, allObjects = False) for mp in modelPanels] debug(app = self, method = 'run_app', message = 'Looping assets now...', verbose = False) for eachAsset in data['assets']: ## Turn this into the shotgun friendly name for the fileNames as underscores are not permitted in shotgun filenames for some obscure reason. debug(app = self, method = 'run_app', message = 'eachAsset[name]...\n%s' % eachAsset['name'], verbose = False) inprogressBar.updateProgress(percent = 50, doingWhat = 'Fetching Assets...') x = 50 if 'CHAR' in eachAsset["name"]: x = x + 5 inprogressBar.updateProgress(percent = x, doingWhat = 'Fetching Char Assets...') self.processAsset(tk = tk, eachAsset = eachAsset, RIG = True, MDL = False, ENV = False, CHAR = True, BLD = False, PROP = False, templateFile = maya_assetRootTemplate) elif 'PROP' in eachAsset["name"]: x = x + 5 inprogressBar.updateProgress(percent = x, doingWhat = 'Fetching Prop Assets...') self.processAsset(tk = tk, eachAsset = eachAsset, RIG = True, MDL = False, ENV = False, CHAR = False, BLD = False, PROP = True, templateFile = maya_assetRootTemplate) elif 'ENV' in eachAsset["name"]: x = x + 5 inprogressBar.updateProgress(percent = x, doingWhat = 'Fetching Env Assets...') self.processAsset(tk = tk, eachAsset = eachAsset, RIG = False, MDL = True, ENV = True, CHAR = False, BLD = False, PROP = False, templateFile = maya_assetRootTemplate) elif 'BLD' in eachAsset["name"]: x = x + 5 inprogressBar.updateProgress(percent = x, doingWhat = 'Fetching Env Assets...') self.processAsset(tk = tk, eachAsset = eachAsset, RIG = True, MDL = False, ENV = False, CHAR = False, BLD = True, PROP = False, templateFile = maya_assetRootTemplate) else: debug(app = self, method = 'run_app', message = 'Invalid Asset Type...\n%s' % eachAsset['name'], verbose = False) pass ## Set all AD to None [cmds.assembly(each, edit = True, active = '') for each in cmds.ls(type = 'assemblyReference')] ## Set model panel to show All if modelPanels: [cmds.modelEditor(mp, edit = True, allObjects = True) for mp in modelPanels] debug(app = self, method = 'run_app', message = 'Moving on to save working scene...', verbose = False) inprogressBar.updateProgress(percent = 75, doingWhat = 'Setting Render Globals...') ## Now make sure the scene is set to pal and cm and renderglobals settings._setRenderGlobals(animation = True) ## Now save the working scene inprogressBar.updateProgress(percent = 90, doingWhat = 'Saving vers up scene...') shotName = entity['name'] debug(app = self, method = 'run_app', message = 'shotName...\n%s' % shotName, verbose = False) work_template = tk.templates['shot_work_area_maya'] debug(app = self, method = 'run_app', message = 'work_template...\n%s' % work_template, verbose = False) ## context.step['name'] = Blocking try: debug(app = self, method = 'run_app', message = "Shot: %s" % shotName, verbose = False) debug(app = self, method = 'run_app', message = "context.step: %s" % context.step['name'], verbose = False) debug(app = self, method = 'run_app', message = 'Trying to fetch pathToWorking now...', verbose = False) pathToWorking = r'%s' % tk.paths_from_template(work_template, {"Shot" : shotName, "Step":context.step['name']})[0] pathToWorking.replace('\\\\', '\\') debug(app = self, method = 'run_app', message = 'pathToWorking...\n%s' % pathToWorking, verbose = False) except: ## There are NO working files yet so we have to handle this propelry ## This needs to be the root folder and 000 for version up\ ## we need to find the sequence from the workspaces index0 of this is default getWorkspace = cmds.workspace( listWorkspaces=True )[1] # Result: [u'default', u'I:/lsapipeline/episodes/eptst/eptst_sh060/Blck/work/maya'] getSequence = getWorkspace.split('/')[4] work_path = work_template.apply_fields({'Sequence' : getSequence, 'Shot': shotName, 'Step': context.step['name']}) debug(app = self, method = 'run_app', message = 'New work_path: %s' % work_path, verbose = False) pathToWorking = r"%s" % work_template ## Scan the folder and find the highest version number fileShotName = "".join(shotName.split('_')) or '' debug(app = self, method = 'run_app', message = 'fileShotName...\n%s' % fileShotName, verbose = False) padding = '' debug(app = self, method = 'run_app', message = 'padding...\n%s' % padding, verbose = False) versionNumber = '' debug(app = self, method = 'run_app', message = 'versionNumber...\n%s' % versionNumber, verbose = False) if os.path.exists(pathToWorking): debug(app = self, method = 'run_app', message = 'Path to working exists...', verbose = False) getfiles = os.listdir(pathToWorking) debug(app = self, method = 'run_app', message = 'getfiles...\n%s' % getfiles, verbose = False) ## Remove the stupid Keyboard folder if it exists.. thx autodesk.. not if 'Keyboard' in getfiles: getfiles.remove('Keyboard') ## Process a clean list now.. trying to remove from the current list is giving me grief and I'm too fn tired to care... finalFiles = [] for each in getfiles: if each.split('.')[0] == fileShotName: finalFiles.append(each) else: pass debug(app = self, method = 'run_app', message = 'finalFiles...\n%s' % finalFiles, verbose = False) if finalFiles: highestVersFile = max(finalFiles) debug(app = self, method = 'run_app', message = 'highestVersFile...\n%s' % highestVersFile, verbose = False) versionNumber = int(highestVersFile.split('.')[1].split('v')[1]) + 1 debug(app = self, method = 'run_app', message = 'versionNumber...\n%s' % versionNumber, verbose = False) else: versionNumber = 1 debug(app = self, method = 'run_app', message = 'versionNumber...\n%s' % versionNumber, verbose = False) ## Now pad the version number if versionNumber < 10: padding = '00' elif versionNumber < 100: padding = '0' else: padding = '' debug(app = self, method = 'run_app', message = 'padding...\n%s' % padding, verbose = False) ## Rename the file renameTo = '%s.v%s%s' % (fileShotName, padding, versionNumber) debug(app = self, method = 'run_app', message = 'renameTo...\n%s' % renameTo, verbose = False) ## Now save the file cmds.file(rename = renameTo) cmds.file(save = True, force = True, type = 'mayaAscii') cmds.headsUpMessage("Assets retrieved successfully...", time = 1) cmds.cycleCheck(e = 0) inprogressBar.updateProgress(percent = 100, doingWhat = 'Finished') inprogressBar.close() else: debug(app = self, method = 'run_app', message = 'Invalid Path to working, skipping save...', verbose = False) inprogressBar.close() cmds.headsUpMessage("Scene not saved. This is most likely due to a first time load of blocking/anim fetch...\nUse Shotgun saveAs now...", time = 2) else: inprogressBar.close() cmds.headsUpMessage("Current context is not a valid Shot context. Please make sure you are under a valid shotgun Shot context!", time = 2)