def setConvergenceDistanceToSelected(*args): """ Sets the convergence distance on the current viewing camera to the the specified selection. If more than one object is selected. It takes the average distance between each selection. Note, this only works with the standard StereoCamera rig and does not support generic rig data types. """ selList = cmds.ls(sl=True) if not selList: # Report an error if nothing was selected. # stereoCameraErrors.displayError('kNothingSelected') # Find the centroid of all selected objects. This will become the # convergence distance. # avg = [0, 0, 0] for s in selList: pos = cmds.xform(s, query=True, worldSpace=True, translation=True) avg = [avg[0] + pos[0], avg[1] + pos[1], avg[2] + pos[2]] c = len(selList) avg = [avg[0] / c, avg[1] / c, avg[2] / c] parent = currentViewCamera(args) pos = cmds.xform(parent, query=True, worldSpace=True, translation=True) sub_pos = [avg[0] - pos[0], avg[1] - pos[1], avg[2] - pos[2]] dist = sub_pos[0] * sub_pos[0] + sub_pos[1] * sub_pos[1] + sub_pos[ 2] * sub_pos[2] dist = math.sqrt(dist) # The smallest convergence distance we allow is 1 cm. # if dist < 1: dist = 1 stereoCameraRig.setZeroParallaxPlane(parent, dist) return dist
def runCallbackChecks(): loaded = cmds.pluginInfo("stereoCamera", query=True, loaded=True) if not loaded: stereoCameraErrors.displayError('kPluginNotLoaded') return False return True
def __addAttrAndConnect(attr, node, otherNode): """ Private method to create a dynamic message attribute if it does not exist yet. The attribute is then connected to the one passed as argument. """ try: if cmds.attributeQuery(attr, n=node, exists=True): if not cmds.attributeQuery(attr, n=node, message=True): stereoCameraErrors.displayError('kAttributeAlreadyExists', attr, node) return False else: cmds.addAttr(node, longName=attr, attributeType='message') # otherNode can be None for the optional rig nodes if otherNode <> None: connections = cmds.listConnections(node + '.' + attr, shapes=True, source=True, destination=False) # Keep the connection if it was set already in the rig structure. if (connections == None): cmds.connectAttr(otherNode + '.message', node + '.' + attr) return True except: stereoCameraErrors.displayError('kCannotConnect', attr, node) return False
def switchToCamera(*args): """ Switch the viewport editor the specified camera name. """ if not stereoCameraUtil.runCallbackChecks(): return editor = args[1] cameraName = args[0] root = cameraName # Display an error to the user if the camera set contains no data. # if cmds.objectType(cameraName, isa="cameraSet"): nl = cmds.cameraSet(cameraName, query=True, numLayers=True) if nl == 0: stereoCameraErrors.displayError('kNoDataInCameraSet', cameraName) editor = getValidPanel(editor) # Users can switch to a stereo camera using camera sets or via # rigs. If it is a camera set then we don't need to find the # root. We can simply view that camera set. # if not cmds.objectType(cameraName, isa="cameraSet"): root = stereoCameraRig.rigRoot(cameraName) cmds.stereoCameraView(editor, edit=True, rigRoot=root) if len(args) > 2 and args[2]: # The 3rd argument indicates if we should select the camera # after assignment. It is tiggered by an option box on the # camera switcher. # cmds.select(cameraName, replace=True)
def __findCam(viewCam, attribute): "Private method to find left, right, center cameras" cam = __followRootConnection(viewCam, attribute) if cam <> None: return cam stereoCameraErrors.displayError('kNoStereoCameraFound', viewCam, attribute) return viewCam
def checkMultibyte(self): import maya.mel as mel check_list = [self._templateName, self._camSetPrefix ] + [x[0] for x in self._camSetPrefixLayer] for c in check_list: if mel.eval('containsMultibyte( "%s" )' % c): stereoCameraErrors.displayError('kNoMultibyte', c) return 1 return 0
def _getDefinition( rigType ): """ Get the definition for this object. """ definitions = [] if rigType: try: definitions = cmds.stereoRigManager(rigDefinition=rigType) except: stereoCameraErrors.displayError('kNoStereoRigCommand', rigType) return definitions
def switchToSelected(*args): """ Switch the viewing camera to the current selection. """ if not stereoCameraUtil.runCallbackChecks(): return nodes = stereoCameraRig.selectedCameras() if nodes: switchToCamera(nodes[0], args[0]) else: stereoCameraErrors.displayError('kNotAValidStereoCamera')
def setStereoPair(rigRoot, leftCam, rightCam): """ Take an existing rig, and change the left and right ca """ for pair in [[leftCam, 'leftCam'], [rightCam, 'rightCam']]: cam = pair[0] attr = pair[1] if not cmds.attributeQuery(attr, n=rigRoot, exists=True): stereoCameraErrors.displayError('kAttributeNotFound', attr, node) else: cmds.connectAttr(cam + '.message', rigRoot + '.' + attr, force=True)
def createStereoCameraRig(rigName=""): """ Create a stereo camera rig. The rig creation call back is called, then specific dynamic attributes are created to track cameras belonging to stereo rigs. If no rigName is set, the default rig tool is used. Return an array [rig root, Left eye camera, right eye camera] """ definitions = None rigRoot = None leftCam = '' rightCam = '' proxyObj = None try: definitions = cmds.stereoRigManager(rigDefinition=rigName) except: stereoCameraErrors.displayError('kNoStereoRigCommand', rigName) try: # Call the creation method dagObjects = stereoCameraUtil.__call(definitions[0], definitions[1], rigName) if dagObjects <> 'Error': try: size = len(dagObjects) # For those users who want to create custom rigs # have the proxy object selected after creation, they need to pass # back a 4th parameter when the rig is created. This 4th parameter # points to the actual object to be selected. # if size == 3 or size == 4: [rigRoot, leftCam, rightCam] = __validateRig(dagObjects[0], dagObjects[1], dagObjects[2]) if size == 4: proxyObj = dagObjects[3] else: stereoCameraErrors.displayError('kRigReturnError', rigName, len(dagObjects)) except: stereoCameraErrors.displayError('kRigReturnNotArray', rigName) except: stereoCameraErrors.displayError('kCannotCreateRig', rigName) if not rigRoot == None: rigTypeName = rigName if rigTypeName == "": rigTypeName = cmds.stereoRigManager(query=True, defaultRig=True) makeStereoCameraRig(rigRoot, rigTypeName, leftCam, rightCam) if proxyObj: rigRoot = proxyObj cmds.select(proxyObj, replace=True) else: cmds.select(rigRoot, replace=True) return [rigRoot, leftCam, rightCam]
def switchToCameraSet(*args): """ Switch the viewport editor the specified cameraSet name. """ if not stereoCameraUtil.runCallbackChecks(): return editor = args[1] cameraSetName = args[0] editor = getValidPanel(editor) if cmds.objectType(cameraSetName, isa="cameraSet"): nl = cmds.cameraSet(cameraSetName, query=True, numLayers=True) if nl == 0: stereoCameraErrors.displayError('kNoDataInCameraSet', cameraSetName) else: cmds.stereoCameraView(editor, edit=True, rigRoot=cameraSetName)
def getValidEditor(panel): if panel: ttype = cmds.getPanel(typeOf=panel) if ttype == 'scriptedPanel': stype = cmds.scriptedPanel(panel, query=True, type=True) if stype == 'Stereo': return panel + 'Editor' # We don't recognize this panel type. Try to find one we like. # spanel = cmds.getPanel(scriptType='Stereo') if spanel and spanel[0]: return spanel[0] + "Editor" else: stereoCameraErrors.displayError('kNoValidPanelsFound') return None
def _gatherSelObjects(): """ Private method that gets the active selection list, finds all selected transforms and returns two lists: 1) a list of cameras attached to camera sets stuff into a python set in the form (cameraSet, cameraSet layerId, cameraName, objectSet) 2) a list of objects to attach to the items found in 1) """ objects = cmds.ls(type="transform", sl=True) cameras = [] setObj = [] for x in objects: if (stereoCameraRig.isRigRoot(x)): cameras.append(x) else: setObj.append(x) camWithSets = [] for c in cameras: connections = cmds.listConnections(c + ".message", t='cameraSet') if not connections: continue # Scan over all unique connections. list(set(connections)) # uniquifies the list. A camera can belong to the same set # twice. # for con in list(set(connections)): layers = cmds.cameraSet(con, query=True, numLayers=True) for l in range(layers): camera = cmds.cameraSet(con, query=True, layer=l, camera=True) if (cmds.ls(camera, l=True) == cmds.ls(c, l=True)): objSet = cmds.cameraSet(con, query=True, layer=l, objectSet=True) camWithSets.append((con, l, camera, objSet)) if len(camWithSets) == 0: stereoCameraErrors.displayError('kNoValidCameraSelected') if len(setObj) == 0: stereoCameraErrors.displayError('kNoObjectsSelected') return (camWithSets, setObj)
def getValidPanel(editor): """ This function checks the given editor to make sure it is an editor that we recognize. If it is not an known editor then we try to find an editor that will work. """ panel = cmds.modelEditor(editor, query=True, panel=True) ttype = cmds.getPanel(typeOf=panel) if ttype == 'scriptedPanel': stype = cmds.scriptedPanel(panel, query=True, type=True) if stype == 'Stereo': return editor # We don't recognize this panel type. Try to find one we like. # spanel = cmds.getPanel(scriptType='Stereo') if spanel and spanel[0]: cmds.scriptedPanel(spanel[0], edit=True, replacePanel=editor) return spanel[0] + "Editor" else: stereoCameraErrors.displayError('kNoValidPanelsFound')
def __validateRig(rigRoot, leftCam, rightCam): """Make sure the 3 objects form a valid stereo rig. If the rig is valid, return the transforms, even if the shapes were passed in. If the rig is invalid, print an error message and return [None, None, None] """ result = [None, None, None] # Make sure the arguments are cameras. if not __isCamera(rigRoot): stereoCameraErrors.displayError('kNotACamera', rigRoot, 1) return result # Use the transform, if the shape was passed in rigRoot = __makeTransform(rigRoot) if not __isCamera(leftCam): stereoCameraErrors.displayError('kNotACamera', leftCam, 2) return result # Use the transform, if the shape was passed in leftCam = __makeTransform(leftCam) if not __isCamera(rightCam): stereoCameraErrors.displayError('kNotACamera', rightCam, 3) return result # Use the transform, if the shape was passed in rightCam = __makeTransform(rightCam) return [rigRoot, leftCam, rightCam]
def __add(layout, nameBox, langMenu, createBox, createCamSet): name = cmds.textField(nameBox, query=True, text=True) lang = cmds.optionMenu(langMenu, query=True, value=True) create = cmds.textField(createBox, query=True, text=True) camSet = cmds.textField(createCamSet, query=True, text=True) # Multibyte string is not allowed for node name if mel.eval(u'containsMultibyte \"%s\"' % name) == 1: stereoCameraErrors.displayError('kRigToolMultiByteName', arg1=name) return if name == '': stereoCameraErrors.displayError('kRigToolNoName') elif create == '': stereoCameraErrors.displayError('kRigToolNoCreate') elif name in cmds.stereoRigManager(listRigs=True): stereoCameraErrors.displayError('kRigToolAlreadyExists', arg1=name) else: cmds.stereoRigManager(add=[name, lang, create]) cmds.stereoRigManager(cameraSetFunc=[name, camSet]) rebuildUI(layout)
def create(self, *args): """ Create the Maya nodes per the specification of this template. """ if self.checkMultibyte(): return rigs = cmds.stereoRigManager(listRigs=True) defaultCam = cmds.stereoRigManager(query=True, defaultRig=True) standardDefault = defaultRigType.rigTypeName swapWithDefault = False askedUserAlready = False for i in range(self.layers()): rtype = self.rigTypeForLayer(i) if rtype not in rigs: if rtype == standardDefault and defaultCam != standardDefault: # Check to make sure we haven't already asked the user # for this create call. There are multiple layers # of a multi-rig and we don't want to ask the user # the same question multiple times. # if not askedUserAlready: swapWithDefault = swapDefault(standardDefault, defaultCam) askedUserAlready = True if not swapWithDefault: stereoCameraErrors.displayError('kRigNotFound', rtype) return else: stereoCameraErrors.displayError('kRigNotFound', rtype) return camSet = None camSetType = self.cameraSetNodeType() val = cmds.objectType(tagFromType=camSetType) if val > 0: camSet = cmds.createNode(camSetType, name=self._templateName) else: stereoCameraErrors.displayError('kCameraSetNotFound', camSetType) return masterPrefix = self._camSetPrefix.replace(' ', '_') uniqueRigs = [] for i in range(self.layers()): rtype = self.rigTypeForLayer(i) if rtype == standardDefault and swapWithDefault: rtype = defaultCam stereoCameraErrors.displayWarning('kDefaultRigSwap', rtype) if rtype not in uniqueRigs: uniqueRigs.append(rtype) layerPrefix = self.layerPrefixForLayer(i).replace(' ', '_') prefix = masterPrefix + layerPrefix autoCreateSet = self.autoCreateSet(i) rig = stereoCameraRig.createStereoCameraRig(rtype) objSet = None if autoCreateSet: objSet = cmds.createNode('objectSet', name=prefix + 'Set') stereoCameraSets.addNewRigToSet(rig[0], camSet, objSet) baseName = rig[0] for r in rig: cmds.rename(r, r.replace(baseName, prefix)) # Notify once to all unique rigs that we have finished # building the multi rig. # for u in uniqueRigs: stereoCameraSets.notifyCameraSetCreateFinished(camSet, u)
def __call(language, method, rigName, kwords={}, cmd_args=[]): """Private method to call a MEL or Python callback. Return 'Error' in case of error. We avoid None, [], '' because those are more likely to be returned by the command we call""" errReturn = 'Error' if language == 'MEL': try: call_string = method for item in kwords.items(): flag = ' -%s %s' if type(item[1]) == str: flag = ' -%s "%s"' call_string = call_string + flag % (str(item[0]), str(item[1])) for arg in cmd_args: argstr = ' "%s"' if type(arg) != str: argstr = ' %s' call_string = call_string + argstr % str(arg) return mel.eval(call_string) except: stereoCameraErrors.displayError('kRigCommandFailed', method, rigName) return errReturn elif language == 'Python': pair = method.rsplit('.', 1) if len(pair) < 2: # Happens if ther is no . in the method stereoCameraErrors.displayError('kRigCommandPython', method, rigName) return errReturn [moduleName, funcName] = pair path = '' pair = moduleName.rsplit('.', 1) if len(pair) > 1: [path, moduleName] = pair if not sys.modules.has_key(moduleName): path = path.replace('.', '/') alteredPath = [ sys.path[i] + '/' + path for i in range(len(sys.path)) ] try: desc = imp.find_module(moduleName, alteredPath) if desc: try: imp.load_module(moduleName, desc[0], desc[1], desc[2]) finally: # Since we may exit via an exception, close fp desc[0].close() except: pass if sys.modules.has_key(moduleName): module = sys.modules[moduleName] funcPtr = module.__dict__[funcName] if kwords or cmd_args: return funcPtr(*cmd_args, **kwords) else: return funcPtr() stereoCameraErrors.displayError('kMissingPythonCB', method, rigName) return errReturn stereoCameraErrors.displayError('kLanguageNotSupported', language, rigName) return errReturn