def get_constraintsTo(node=None, fullPath=True, typeFilter=None, typeMask=None): """ Get the constraints on a given node :parameters: node(str): node to query fullPath(bool): How you want list :returns list of constraints(list) """ _str_func = 'get_constraintsTo' node = VALID.mNodeString(node) _res = mc.listRelatives(node, type='constraint', fullPath=fullPath) or [] _res = LISTS.get_noDuplicates(_res) if typeFilter: typeFilter = VALID.listArg(typeFilter) for i, t in enumerate(typeFilter): if 'Constraint' not in t: typeFilter[i] = t + 'Constraint' log.debug( cgmGEN.logString_msg(_str_func, 'typeFilter: {0}'.format(typeFilter))) _res_filter = [] for o in _res: _type = VALID.get_mayaType(o) if _type in typeFilter: _res_filter.append(o) _res = _res_filter if typeMask: typeMask = VALID.listArg(typeMask) for i, t in enumerate(typeMask): if 'Constraint' not in t: typeMask[i] = t + 'Constraint' log.debug( cgmGEN.logString_msg(_str_func, 'typeMask: {0}'.format(typeMask))) for o in _res: _type = VALID.get_mayaType(o) if _type in typeMask: _res.remove(o) log.debug( cgmGEN.logString_msg(_str_func, 'removing: {0}'.format(o))) if fullPath: return [NAMES.long(o) for o in _res] return _res
def killRoguePanel(method=''): """ hattip: https://forums.autodesk.com/t5/maya-forum/error-cannot-find-procedure-quot-dcf-updateviewportlist-quot/td-p/8342659?fbclid=IwAR3IhCeCqzZvEREmxo5eA7ECQu9n82MEN_vqCFTmdySwNNbsrYREdDcv_QA """ #['DCF_updateViewportList', 'CgAbBlastPanelOptChangeCallback'] EVIL_METHOD_NAMES = cgmValid.listArg(method) capitalEvilMethodNames = [name.upper() for name in EVIL_METHOD_NAMES] modelPanelLabel = mel.eval('localizedPanelLabel("ModelPanel")') processedPanelNames = [] panelName = mc.sceneUIReplacement(getNextPanel=('modelPanel', modelPanelLabel)) while panelName and panelName not in processedPanelNames: editorChangedValue = mc.modelEditor(panelName, query=True, editorChanged=True) parts = editorChangedValue.split(';') newParts = [] changed = False for part in parts: for evilMethodName in capitalEvilMethodNames: if evilMethodName in part.upper(): changed = True break else: newParts.append(part) if changed: mc.modelEditor(panelName, edit=True, editorChanged=';'.join(newParts)) processedPanelNames.append(panelName) panelName = mc.sceneUIReplacement(getNextPanel=('modelPanel', modelPanelLabel)) log.info("Processed: {0}".format(panelName))
def get_bb_size(arg=None, shapes=False, mode=None, asEuclid=False): """ Get the bb size of a given arg :parameters: arg(str/list): Object(s) to check shapes(bool): Only check dag node shapes mode(varied): True/'max': Only return max value 'min': Only min maxFill - [max,max.max] :returns boundingBox size(list) """ _str_func = 'get_bb_size' #_arg = VALID.stringListArg(arg,False,_str_func) arg = VALID.mNodeString(arg) if shapes: log.debug("|{0}| >> shapes mode ".format(_str_func)) arg = VALID.listArg(arg) l_use = [] for o in arg: log.debug("|{0}| >> o: '{1}' ".format(_str_func, o)) l_shapes = mc.listRelatives(o, s=True, fullPath=True) or [] if l_shapes: l_use.extend(l_shapes) else: l_use.append(o) arg = l_use log.debug("|{0}| >> arg: '{1}' ".format(_str_func, arg)) _box = mc.exactWorldBoundingBox(arg) if mode == 'raw': if asEuclid: log.debug("|{0}| >> asEuclid...".format(_str_func)) return EUCLID.Vector3(_box[0], _box[1], _box[2]) return _box _res = [(_box[3] - _box[0]), (_box[4] - _box[1]), (_box[5] - _box[2])] if mode is None: if asEuclid: log.debug("|{0}| >> asEuclid...".format(_str_func)) return EUCLID.Vector3(_res[0], _res[1], _res[2]) return _res elif mode in [True, 'max']: return max(_res) elif mode in ['min']: return min(_res) elif mode == 'maxFill': _max = max(_res) return [_max, _max, _max] else: log.error("|{0}| >> Unknown mode. Returning default. {1} ".format( _str_func, mode)) return _res
def get_axisBox_size(targets=None, maxDistance=10000000, mark=False): try: _str_func = 'get_axisBox_size' log.debug("|{0}| >> ".format(_str_func) + '-' * 80) targets = VALID.listArg(targets) _targets = VALID.mNodeStringList(targets) if not _targets: raise ValueError, "Must have targets!" d_res = {'x': [], 'y': [], 'z': []} for t in _targets: log.debug("|{0}| >> On t: {1}".format(_str_func, t)) _proxy = CORERIG.create_axisProxy(t) _startPoint = POS.get(_proxy, 'bb') for k in d_res.keys(): log.debug("|{0}| >> On t: {1} | {2}".format(_str_func, t, k)) pos_positive = RAYS.get_cast_pos(t, k + '+', 'near', _proxy, startPoint=_startPoint, mark=False, maxDistance=maxDistance) pos_neg = RAYS.get_cast_pos(t, k + '-', 'near', _proxy, startPoint=_startPoint, mark=False, maxDistance=maxDistance) if mark: LOCINATOR.LOC.create(position=pos_positive, name="{0}_{1}Pos_loc".format(t, k)) LOCINATOR.LOC.create(position=pos_neg, name="{0}_{1}Neg_loc".format(t, k)) dist = DIST.get_distance_between_points(pos_positive, pos_neg) d_res[k].append(dist) mc.delete(_proxy) for k, v in d_res.iteritems(): d_res[k] = COREMATH.average(v) return d_res['x'], d_res['y'], d_res['z'] except Exception, err: cgmGEN.cgmExceptCB(Exception, err)
def get_driver(driven=None, getPlug=True, select=True): """ Get the driver objects or plugs by following the anim curve out of our intial driven :parameters: driven(str): Attribute to map. If none provided, checks selection getPlug(bool): Whether to get plug or node select(bool): Select the result :returns driven """ _str_func = 'get_driver' driven = VALID.listArg(driven) if not driven: driven = SEARCH.get_selectedFromChannelBox(False) or [] log.debug("|{0}| >> Driven: {1}".format(_str_func, driven)) if not driven: log.error( "|{0}| >> No driven found or offered. Try selecting an attribute that is an sdk driven" .format(_str_func)) return False l_driver = [] for d in driven: _buffer = mc.listConnections(d, scn=True, s=True, d=False) or [] if not _buffer: log.error("|{0}| >> Driven: {1} | No data found".format( _str_func, d)) for c in _buffer: log.debug("|{0}| >> Checking: {1}".format(_str_func, c)) #b_transform = VALID.is_transform(c) #if not b_transform: l_driver.append( SEARCH.seek_upStream(c, mode='isTransform', getPlug=getPlug)) l_driver = LISTS.get_noDuplicates(l_driver) if not l_driver: log.error("|{0}| >> No driver found".format(_str_func)) return False if select: mc.select(l_driver) pprint.pprint(l_driver) return l_driver
def get_bb_sizeOLD(arg=None, shapes=False, mode=None): """ Get the bb size of a given arg :parameters: arg(str/list): Object(s) to check shapes(bool): Only check dag node shapes mode(varied): True/'max': Only return max value 'min': Only min :returns boundingBox size(list) """ _str_func = 'get_bb_size' #_arg = VALID.stringListArg(arg,False,_str_func) if shapes: log.debug("|{0}| >> shapes mode ".format(_str_func)) arg = VALID.listArg(arg) l_use = [] for o in arg: log.debug("|{0}| >> o: '{1}' ".format(_str_func, o)) l_shapes = mc.listRelatives(o, s=True) or [] if l_shapes: l_use.extend(l_shapes) else: l_use.append(o) arg = l_use log.debug("|{0}| >> arg: '{1}' ".format(_str_func, arg)) _box = mc.exactWorldBoundingBox(arg) _res = [(_box[3] - _box[0]), (_box[4] - _box[1]), (_box[5] - _box[2])] if mode is None: return _res elif mode in [True, 'max']: return max(_res) elif mode in ['min']: return min(_res) else: log.error("|{0}| >> Unknown mode. Returning default. {1} ".format( _str_func, mode)) return _res
def scale_to_axisSize(arg=None, size=None, skip=None): _str_func = 'scale_to_axisSize' log.debug(cgmGEN.logString_start(_str_func)) _currentSize = get_axisSize(arg) _currentScale = ATTR.get(arg, 'scale') _skip = VALID.listArg(skip) _targetScale = [] for i, s in enumerate(size): if skip and i in _skip: _targetScale.append(_currentScale[i]) if s is not None: v = (_currentScale[i] * s) / _currentSize[i] _targetScale.append(v) else: _targetScale.append(_currentScale[i]) #log.info(_targetScale) for i, a in enumerate('xyz'): if size[i]: ATTR.set(arg, 's{0}'.format(a), _targetScale[i])
def color_mesh(target=None, mode='puppetmesh'): _str_func = "color_mesh" if not target: raise ValueError, "|{0}| >> Must have a target".format(_str_func) l_targets = VALID.listArg(target) _shader, _set = getControlShader(None, 'puppetmesh', False, False, False) for t in l_targets: log.debug("|{0}| >> t: {1} ...".format(_str_func, t)) _type = VALID.get_mayaType(t) log.debug("|{0}| >> shapes: {1} ...".format(_str_func, TRANS.shapes_get(t, True))) log.debug("|{0}| >> type: {1} ...".format(_str_func, _type)) mc.sets(t, edit=True, remove='initialShadingGroup') if _type in ['nurbsSurface', 'mesh']: mc.sets(t, e=True, forceElement=_set) else: for s in TRANS.shapes_get(t, True): log.debug("|{0}| >> s: {1} ...".format(_str_func, s)) _type = VALID.get_mayaType(s) if _type in ['nurbsSurface', 'mesh']: mc.sets(s, edit=True, forceElement=_set) mc.sets(s, remove='initialShadingGroup') try: mc.disconnectAttr( '{0}.instObjGroups.objectGroups'.format(s), 'initialShadingGroup.dagSetMembers') except: pass else: log.debug("|{0}| >> Not a valid target: {1} | {2}".format( _str_func, s, _type)) mc.sets(t, edit=True, remove='initialShadingGroup') return True
def override_color(target=None, key=None, index=None, rgb=None, pushToShapes=True): """ Sets the color of a shape or object via override. In Maya 2016, they introduced rgb value override. :parameters target(str): What to color - shape or transform with shapes key(varied): if str will check against our shared color dict definitions for rgb and index entries index(int): Color index rgb(list): rgb values to set in Maya 2016 or above pushToShapes(bool): Push the overrides to shapes of passed transforms :returns info(dict) """ _str_func = "set_color" if not target: raise ValueError, "|{0}| >> Must have a target".format(_str_func) l_targets = VALID.listArg(target) for t in l_targets: _shapes = [] #If it's accepable target to color #mTarget = r9Meta.MetaClass(target, autoFill=False) if ATTR.has_attr(t, 'overrideEnabled'): log.debug( "|{0}| >> overrideEnabled on target...".format(_str_func)) _shapes.append(t) if pushToShapes: _bfr = mc.listRelatives(t, s=True, fullPath=True) if _bfr: _shapes.extend(_bfr) if not _shapes: raise ValueError, "|{0}| >> Not a shape and has no shapes: '{1}'".format( _str_func, t) #log.debug(key) #log.debug(index) #log.debug(rgb) if index is None and rgb is None and key is None: raise ValueError, "|{0}| >> Must have a value for index,rgb or key".format( _str_func) #...little dummy proofing.. if key: _type = type(key) if _type not in [str, unicode]: log.debug( "|{0}| >> Not a string arg for key...".format(_str_func)) if rgb is None and issubclass(_type, list) or issubclass( _type, tuple): log.debug( "|{0}| >> vector arg for key...".format(_str_func)) rgb = key key = None elif index is None and issubclass(_type, int): log.debug("|{0}| >> int arg for key...".format(_str_func)) index = key key = None else: raise ValueError, "|{0}| >> Not sure what to do with this key arg: {1}".format( _str_func, key) _b_RBGMode = False _b_2016Plus = False if cgmGEN.__mayaVersion__ >= 2016: _b_2016Plus = True if key is not None: _color = False if _b_2016Plus: log.debug("|{0}| >> 2016+ ...".format(_str_func)) _color = SHARED._d_colors_to_RGB.get(key, False) if _color: rgb = _color if _color is False: log.debug( "|{0}| >> Color key not found in rgb dict checking index..." .format(_str_func)) _color = SHARED._d_colors_to_index.get(key, False) if _color is False: raise ValueError, "|{0}| >> Unknown color key: '{1}'".format( _str_func, key) if rgb is not None: if not _b_2016Plus: raise ValueError, "|{0}| >> RGB values introduced in maya 2016. Current version: {1}".format( _str_func, cgmGEN.__mayaVersion__) _b_RBGMode = True if len(rgb) == 3: _color = rgb else: raise ValueError, "|{0}| >> Too many rgb values: '{1}'".format( _str_func, rgb) if index is not None: _color = index log.debug("|{0}| >> Color: {1} | rgbMode: {2}".format( _str_func, _color, _b_RBGMode)) for i, s in enumerate(_shapes): mShape = r9Meta.MetaClass(s) mShape.overrideEnabled = True #attributes.doSetAttr(s,'overrideEnabled',True) if _b_RBGMode: mShape.overrideRGBColors = 1 mShape.overrideColorRGB = _color #attributes.doSetAttr(s,'overrideRGBColors','RGB')#...brilliant attr naming here Autodesk... #attributes.doSetAttr(s,'overrideColorsRGB',[1,1,1]) else: if _b_2016Plus: mShape.overrideRGBColors = 0 mShape.overrideColor = _color
def get_special_pos(targets=None, arg='rp', mode=None, mark=False): """ This had to move here for import loop considerations :parameters: obj(str): Object to modify target(str): Object to snap to sourceObject(str): object to copy from arg rp sp boundingBoxEach boundingBoxAll - all targets bounding box cumulative axisBox castFar castNear groundPos mode - Relative to center front x :returns success(bool) """ try: _str_func = 'get_special_pos' _sel = mc.ls(sl=True) or [] targets = VALID.listArg(targets) _targets = VALID.mNodeStringList(targets) if not _targets: raise ValueError, "Must have targets!" _arg = VALID.kw_fromDict(arg, SHARED._d_pivotArgs, noneValid=True, calledFrom=__name__ + _str_func + ">> validate pivot") if _arg is None: _arg = arg if _arg == 'cast': _arg = 'castNear' if mode is None: if _arg in ['boundingBox']: mode = 'center' else: mode = 'z+' l_nameBuild = ['_'.join([NAMES.get_base(o) for o in _targets]), _arg] if mode: l_nameBuild.append(mode) l_res = [] if _arg in ['rp', 'sp']: for t in _targets: l_res.append(POS.get(t, _arg, 'world')) elif _arg == 'boundingBox': l_res.append(POS.get_bb_pos(_targets, False, mode)) elif _arg == 'boundingBoxShapes': l_res.append(POS.get_bb_pos(_targets, True, mode)) elif _arg == 'boundingBoxEach': for t in _targets: l_res.append(POS.get_bb_pos(t, False, mode)) elif _arg == 'boundingBoxEachShapes': for t in _targets: l_res.append(POS.get_bb_pos(t, True, mode)) elif _arg == 'groundPos': for t in targets: pos = TRANS.position_get(t) l_res.append([pos[0], 0.0, pos[2]]) elif _arg.startswith('castAll'): _type = _arg.split('castAll')[-1].lower() log.debug("|{0}| >> castAll mode: {1} | {2}".format( _str_func, mode, _type)) pos = RAYS.get_cast_pos(_targets[0], mode, _type, None, mark=False, maxDistance=100000) l_res.append(pos) elif _arg.startswith('cast'): _type = _arg.split('cast')[-1].lower() log.debug("|{0}| >> cast mode: {1} | {2}".format( _str_func, mode, _type)) if len(_targets) > 1: log.debug("|{0}| >> more than one target...".format(_str_func)) pos = RAYS.get_cast_pos(_targets[0], mode, _type, _targets[1:], mark=False, maxDistance=100000) else: pos = RAYS.get_cast_pos(_targets[0], mode, _type, _targets, mark=False, maxDistance=100000) if not pos: return False l_res.append(pos) elif _arg == 'axisBox': log.warning("|{0}| >> axisBox mode is still wip".format(_str_func)) if not targets: raise ValueError, "No targets in axisBox cast!" for t in targets: log.debug("|{0}| >> AxisBox cast: {1} ".format(_str_func, t)) _proxy = CORERIG.create_axisProxy(t) #Start point is bb center because rp can sometimes be in odd places and we care about the axisBox pos = RAYS.get_cast_pos(t, mode, 'near', _proxy, startPoint=POS.get(_proxy, 'bb'), mark=False, maxDistance=100000) log.debug("|{0}| >> AxisBox dat: {1}".format(_str_func, pos)) #if not pos: # pprint.pprint(vars()) l_res.append(pos) mc.delete(_proxy) else: raise ValueError, "|{0}| >> Unknown mode: {1}".format( _str_func, _arg) #cgmGEN.func_snapShot(vars()) if len(l_res) > 1: _res = DIST.get_average_position(l_res) else: _res = l_res[0] if mark: _loc = mc.spaceLocator()[0] mc.move(_res[0], _res[1], _res[2], _loc, ws=True) mc.rename(_loc, '{0}_loc'.format('_'.join(l_nameBuild))) if _sel and not mark: mc.select(_sel) return _res except Exception, err: cgmGEN.cgmExceptCB(Exception, err)
def get_axisBox_size(arg=None, children=False, mode=None, asEuclid=False): """ Get the bb size of a given arg :parameters: arg(str/list): Object(s) to check shapes(bool): Only check dag node shapes mode(varied): True/'max': Only return max value 'min': Only min :returns boundingBox size(list) """ _str_func = 'get_axisBox_size' #_arg = VALID.stringListArg(arg,False,_str_func) try: log.debug("|{0}| >> shapes mode ".format(_str_func)) arg = VALID.listArg(arg) _dag = VALID.getTransform(arg[0]) if not _dag: raise ValueError, "Must have a dag node. Obj: {0}".format(_dag) if VALID.is_shape(_dag): l_shapes = [_dag] else: l_shapes = mc.listRelatives(_dag, s=True, fullPath=True) or [] _dup = mc.duplicate(l_shapes, po=False, rc=True)[0] if not children: for o in mc.listRelatives( _dup, children=True, type='transform', fullPath=True) or []: mc.delete(o) try: _dup = mc.parent(_dup, world=True)[0] except: pass #Reset our stuff before we make our bb... ATTR.reset(_dup, ['t', 'r', 'shear']) _size = get_bb_size(_dup, True) mc.delete(_dup) _res = _size if mode is None: if asEuclid: log.debug("|{0}| >> asEuclid...".format(_str_func)) return EUCLID.Vector3(_res[0], _res[1], _res[2]) return _res elif mode in [True, 'max']: return max(_res) elif mode in ['min']: return min(_res) else: log.error("|{0}| >> Unknown mode. Returning default. {1} ".format( _str_func, mode)) return _res except Exception, err: cgmGen.cgmExceptCB(Exception, err, msg=vars())
def specialSnap(obj=None, targets=None, arg='axisBox', mode='center', castOffset=False): """ Special snap functionality :parameters: obj(str): Object to modify target(str): Object to snap to sourceObject(str): object to copy from :returns success(bool) """ try: _str_func = 'specialSnap' _obj = VALID.mNodeString(obj) _targets = VALID.listArg(targets) if not _targets: _targets = [_obj] if arg not in ['axisBox']: _targets.insert(0, _obj) p = get_special_pos(_targets, arg, mode, False) if castOffset: p_start = TRANS.position_get(_obj) _vector_to_hit = COREMATH.get_vector_of_two_points(p_start, p) _vector_to_start = COREMATH.get_vector_of_two_points(p, p_start) _cast = RAYS.cast(startPoint=p_start, vector=_vector_to_hit) _hit = _cast.get('near') _dist_base = DIST.get_distance_between_points( p_start, p) #...get our base distance _dist_to_hit = DIST.get_distance_between_points( p_start, _hit) #...get our base distance p_result = DIST.get_pos_by_vec_dist(p_start, _vector_to_hit, (_dist_base + _dist_to_hit)) #_cast = RayCast.cast(self.l_mesh, startPoint=_pos_obj,vector=_vec_obj) #_nearHit = _cast['near'] #_dist_firstHit = DIST.get_distance_between_points(_pos_obj,_nearHit) #log.debug("baseDist: {0}".format(_dist_base)) #log.debug("firstHit: {0}".format(_dist_firstHit)) """ if not _m_normal: if self.mode == 'far': _dist_new = _dist_base + _dist_firstHit else: _dist_new = _dist_base - _dist_firstHit _offsetPos = DIST.get_pos_by_vec_dist(_pos_obj,_vec_obj,(_dist_new)) else: log.debug("|{0}| >> mesh normal offset!".format(_str_funcName)) _offsetPos = DIST.get_pos_by_vec_dist(_pos_base,_m_normal,(_dist_firstHit))""" #cgmGEN.func_snapShot(vars()) POS.set(_obj, p_result) return POS.set(_obj, p) except Exception, err: cgmGEN.cgmExceptCB(Exception, err, msg=vars())
def main(tests='all', verbosity=1, testCheck=False, **kwargs): """ Core test runner for us. :parameters: tests(list): Str list of tests to be run. Should be in data lists above in the module. 'all' will run all found tests. verbosity(int): 1,2 testCheck(bool): If True, no tests will run it will just collect the list so you can see what would have run """ v = verbosity tests = VALID.listArg(tests) _l_testModules = [] _d_testModulePaths = {} _d_tests = {} #...gather up our tests and paths... if tests == ['all']: log.info("testing all") for m in _l_all_order: #log.info(m) _tests = _d_modules.get(m, False) for t in _tests: _key = "{0}.{1}".format(m, t) _l_testModules.append(t) _d_testModulePaths[t] = "test_{0}.test_{1}".format(m, t) else: for t in tests: for k, l in _d_modules.iteritems(): if t == k: for t2 in l: _key = "{0}.{1}".format(k, t2) _l_testModules.append(_key) _d_testModulePaths[_key] = "test_{0}.test_{1}".format( k, t2) if t in l: _key = "{0}.{1}".format(k, t) _l_testModules.append(_key) _d_testModulePaths[_key] = "test_{0}.test_{1}".format(k, t) #cgmGEN.log_info_dict(_d_testModulePaths) if not _l_testModules: raise ValueError, "No modules detected to test. Test arg: {0}".format( tests) #....meat of it... if testCheck is not True: import cgm cgm.core._reload() sceneSetup() _t_start = time.clock() _len_all = 0 print(cgmGEN._str_hardBreak) for mod in _l_testModules: suite = unittest.TestSuite() module = "cgm.core.tests.{0}".format(_d_testModulePaths[mod]) print(">>> Testing: {0} | {1}".format(mod, module) + '-' * 100) try: exec("import {0}".format(module)) exec("reload({0})".format(module)) except Exception, err: log.error("New File fail!") for arg in err.args: log.error(arg) raise Exception, err tests = unittest.defaultTestLoader.loadTestsFromName(module) suite.addTest(tests) if testCheck is not True: unittest.TextTestRunner(verbosity=v).run(suite) #print("Tests: ") for t in tests: for t2 in t: if v == 1: _class = t2.__class__.__name__.split('Test_')[-1] _test = t2._testMethodName.split('test_')[-1] print(" > " + "{0} | {1}".format(_class, _test)) _len_all += 1 #print(cgmGEN._str_subLine) if testCheck is not True: print("<<< Module complete : {0} | {1} ...".format( mod, format(module)))
def get_constraintsFrom(node=None, fullPath=True, typeFilter=None, typeMask=None): """ Get the constraints a given node drives :parameters: node(str): node to query fullPath(bool): How you want list :returns list of constraints(list) """ _str_func = 'get_constraintsFrom' node = VALID.mNodeString(node) _res = mc.listConnections(node, source=False, destination=True, skipConversionNodes=True, type='constraint') or [] _res = LISTS.get_noDuplicates(_res) #_l_objectConstraints = get(node) #for c in _l_objectConstraints: #if c in _res:_res.remove(c) if typeFilter: typeFilter = VALID.listArg(typeFilter) for i, t in enumerate(typeFilter): if 'Constraint' not in t: typeFilter[i] = t + 'Constraint' log.debug( cgmGEN.logString_msg(_str_func, 'typeFilter: {0}'.format(typeFilter))) _res_filter = [] for o in _res: _type = VALID.get_mayaType(o) if _type in typeFilter: _res_filter.append(o) _res = _res_filter if typeMask: typeMask = VALID.listArg(typeMask) for i, t in enumerate(typeMask): if 'Constraint' not in t: typeMask[i] = t + 'Constraint' log.debug( cgmGEN.logString_msg(_str_func, 'typeMask: {0}'.format(typeMask))) for o in _res: _type = VALID.get_mayaType(o) if _type in typeMask: _res.remove(o) log.debug( cgmGEN.logString_msg(_str_func, 'removing: {0}'.format(o))) if fullPath: return [NAMES.long(o) for o in _res] return _res
def create_MRS_batchFile(f=None, blocks=[None], process=False, postProcesses=True, deleteAfterProcess=False, gatherOptionVars=True): _str_func = 'create_MRS_batchFile' cgmGEN.log_start(_str_func) l_pre = [ 'import maya', 'from maya import standalone', 'standalone.initialize()', 'from maya.api import OpenMaya as om2', 'om2.MGlobal.displayInfo("Begin")', 'import maya.cmds as mc', 'mc.loadPlugin("matrixNodes")', 'import cgm.core.mrs.lib.batch_utils as MRSBATCH' ] l_post = [ 'except:', ' import msvcrt#...waits for key', ' om2.MGlobal.displayInfo("Hit a key to continue")', ' msvcrt.getch()', 'om2.MGlobal.displayInfo("End")', 'standalone.uninitialize()' ] log.debug(cgmGEN.logString_sub(_str_func, "Checks ...")) l_paths = [] l_dirs = [] l_check = VALID.listArg(f) l_mFiles = [] l_batch = [] if not l_check: log.debug( cgmGEN.logString_msg(_str_func, "No file passed. Using current")) l_check = [mc.file(q=True, sn=True)] for f in l_check: mFile = PATHS.Path(f) if not mFile.exists(): log.error("Invalid file: {0}".format(f)) continue log.debug(cgmGEN.logString_sub(_str_func)) _path = mFile.asFriendly() l_paths.append(_path) _name = mFile.name() _d = mFile.up().asFriendly() log.debug(cgmGEN.logString_msg(_str_func, _name)) _batchPath = os.path.join(_d, _name + '_MRSbatch.py') log.debug(cgmGEN.logString_msg(_str_func, "batchPath: " + _batchPath)) log.debug(cgmGEN.logString_msg(_str_func, "template: " + _path)) mTar = PATHS.Path(_batchPath) _l = "try:MRSBATCH.process_blocks_rig('{0}',postProcesses = {1})".format( mFile.asString(), postProcesses) if mTar.getWritable(): if mTar.exists(): os.remove(mTar) log.warning("Writing file: {0}".format(_batchPath)) with open(_batchPath, 'a') as TMP: for l in l_pre + [_l] + l_post: TMP.write('{0}\n'.format(l)) l_batch.append(mTar) else: log.warning("Not writable: {0}".format(_batchPath)) if process: log.debug(cgmGEN.logString_sub(_str_func, "Processing ...")) for f in l_batch: log.warning("Processing file: {0}".format(f.asFriendly())) #subprocess.call([sys.argv[0].replace("maya.exe","mayapy.exe"),f.asFriendly()]) subprocess.Popen( [ sys.argv[0].replace("maya.exe", "mayapy.exe"), '-i', f.asFriendly() ], creationflags=subprocess.CREATE_NEW_CONSOLE) # env=my_env if deleteAfterProcess: os.remove(f) '''
try: return position(**_kws) except Exception, err: log.error("|{0}| >> loc: {1}".format(_str_func, loc)) cgmGeneral.log_info_dict(_kws['infoDict'], "{0} >> {1}".format(_str_func, mode)) log.error("|{0}| >> err: {1}".format(_str_func, _err)) return False _str_func = "update" _loc = VALID.objString(loc, noneValid=True, calledFrom=__name__ + _str_func + ">> validate loc") _type = VALID.get_mayaType(_loc) _targets = VALID.listArg(targets) if _type == 'locator': if mode and _targets: log.debug("|{0}| >> mode override...".format(_str_func)) return getAndMove(_loc, _targets, mode, forceBBCenter) elif _targets: log.debug("|{0}| >> source mode...".format(_str_func)) if len(_targets) > 1: log.debug("|{0}| >> assuming midPoint...".format(_str_func)) return getAndMove(_loc, _targets, 'midPoint', forceBBCenter) else: log.debug("|{0}| >> singleTarget...".format(_str_func)) _d = POS.get_info(_targets, boundingBox=forceBBCenter)
def __init__(self, mode = 'surface', mesh = None, create = False, closestOnly = True, clampIntersections = False, dragStore = False, maxStore = False, posOffset = None, clampValues = [None,None,None], offsetMode = 'normal', orientSnap = True, timeDelay = None, tagAndName = {}, toCreate = [], toSnap = [],#...objects to snap on release *a,**kws): _str_funcName = 'clickMesh.__init__' log.info(">>> %s >> "%_str_funcName + "="*75) #>>> Store our info ==================================================================== self._createModes = ['locator','joint','jointChain','curve','follicle','group',False] self._l_modes = _clickMesh_modes self.l_mesh = [] self.d_meshPos = {} #creating this pretty much just for follicle mode so we can attache to a specific mesh self.d_meshUV = {} self.f_meshArea = 1 self.l_toSnap = cgmValid.listArg(toSnap) self._createMode = create self._getUV = False self._time_start = time.clock() self._time_delayCheck = timeDelay if self._createMode == 'follicle':#Only get uv intersection for follicles self._getUV = True self.b_closestOnly = closestOnly self.l_created = [] self.b_clampSetting = clampIntersections self.b_dragStoreMode = dragStore self.l_return = [] self.d_tagAndName = tagAndName self._posBuffer = False self.v_posOffset = posOffset or False self.str_offsetMode = offsetMode self.b_orientSnap = orientSnap self._createModeBuffer = False self.int_maxStore = maxStore self.l_toCreate = toCreate self.v_clampValues = clampValues if toCreate: self.int_maxStore = len(toCreate) self.setMode(mode) ContextualPick.__init__(self, drag = True, space = 'screen',projection = 'viewPlane', *a,**kws ) if mesh is None: log.info("Using all visible mesh!") for l in mc.ls(type='mesh',visible = True), mc.ls(type='nurbsSurface',visible = True): for o in l: self.addTargetMesh( cgmMeta.getTransform(o)) if mesh is not None: assert type(mesh) is list,"Mesh call must be in list form when called" for m in mesh: self.addTargetMesh(m) self.updateMeshArea()
def shapeParent_in_place(obj, shapeSource, keepSource=True, replaceShapes=False, snapFirst=False): """ Shape parent a curve in place to a obj transform :parameters: obj(str): Object to modify shapeSource(str): Curve to shape parent keepSource(bool): Keep the curve shapeParented as well replaceShapes(bool): Whether to remove the obj's original shapes or not snapFirst(bool): whether to snap source to obj before transfer :returns success(bool) """ _str_func = 'shapeParent_in_place' l_shapes = VALID.listArg(shapeSource) obj = VALID.mNodeString(obj) log.debug( "|{0}| >> obj: {1} | shapeSource: {2} | keepSource: {3} | replaceShapes: {4}" .format(_str_func, obj, shapeSource, keepSource, replaceShapes)) if replaceShapes: _l_objShapes = mc.listRelatives(obj, s=True, fullPath=True) if _l_objShapes: log.debug("|{0}| >> Removing obj shapes...| {1}".format( _str_func, _l_objShapes)) mc.delete(_l_objShapes) mc.select(cl=True) #mc.refresh() for c in l_shapes: try: _shapeCheck = SEARCH.is_shape(c) if not _shapeCheck and not mc.listRelatives( c, f=True, shapes=True, fullPath=True): raise ValueError, "Has no shapes" if coreNames.get_long(obj) == coreNames.get_long(c): raise ValueError, "Cannot parentShape self" if VALID.get_mayaType(c) == 'nurbsCurve': mc.ls(['%s.ep[*]' % (c)], flatten=True) #This is for a really weird bug in 2016 where offset curve shapes don't work right unless they're components are queried. if _shapeCheck: _dup_curve = duplicate_shape(c)[0] log.debug("|{0}| >> shape duplicate".format(_str_func)) if snapFirst: SNAP.go(_dup_curve, obj) else: log.debug("|{0}| >> regular duplicate".format(_str_func)) _dup_curve = mc.duplicate(c)[0] for child in TRANS.children_get(_dup_curve, True): mc.delete(child) if snapFirst: SNAP.go(_dup_curve, obj) _l_parents = SEARCH.get_all_parents(obj) ATTR.set_standardFlags(_dup_curve, lock=False, visible=True, keyable=True) _dup_curve = parent_set(_dup_curve, False) copy_pivot(_dup_curve, obj) #piv_pos = mc.xform(obj, q=True, ws=True, rp = True) #mc.xform(_dup_curve,ws=True, rp = piv_pos) pos = mc.xform(obj, q=True, os=True, rp=True) curveScale = mc.xform(_dup_curve, q=True, s=True, r=True) objScale = mc.xform(obj, q=True, s=True, r=True) #account for freezing #mc.makeIdentity(_dup_curve,apply=True,translate =True, rotate = True, scale=False) # make our zero out group #group = rigging.groupMeObject(obj,False) group = create_at(obj, 'null') _dup_curve = mc.parent(_dup_curve, group)[0] # zero out the group mc.xform(group, ws=True, t=pos) #mc.xform(group,roo = 'xyz', p=True) mc.xform(group, ra=[0, 0, 0], p=False) mc.xform(group, ro=[0, 0, 0], p=False) mc.makeIdentity(_dup_curve, apply=True, translate=True, rotate=True, scale=False) #main scale fix baseMultiplier = [0, 0, 0] baseMultiplier[0] = (curveScale[0] / objScale[0]) baseMultiplier[1] = (curveScale[1] / objScale[1]) baseMultiplier[2] = (curveScale[2] / objScale[2]) mc.setAttr(_dup_curve + '.sx', baseMultiplier[0]) mc.setAttr(_dup_curve + '.sy', baseMultiplier[1]) mc.setAttr(_dup_curve + '.sz', baseMultiplier[2]) #parent scale fix if _l_parents: _l_parents.reverse() multiplier = [ baseMultiplier[0], baseMultiplier[1], baseMultiplier[2] ] for p in _l_parents: scaleBuffer = mc.xform(p, q=True, s=True, r=True) multiplier[0] = ((multiplier[0] / scaleBuffer[0])) multiplier[1] = ((multiplier[1] / scaleBuffer[1])) multiplier[2] = ((multiplier[2] / scaleBuffer[2])) mc.setAttr(_dup_curve + '.sx', multiplier[0]) mc.setAttr(_dup_curve + '.sy', multiplier[1]) mc.setAttr(_dup_curve + '.sz', multiplier[2]) _dup_curve = parent_set(_dup_curve, False) mc.delete(group) #freeze for parent shaping mc.makeIdentity(_dup_curve, apply=True, translate=True, rotate=True, scale=True) shape = mc.listRelatives(_dup_curve, f=True, shapes=True, fullPath=True) mc.parent(shape, obj, add=True, shape=True) mc.delete(_dup_curve) if not keepSource: mc.delete(c) except Exception, err: cgmGEN.cgmExceptCB(Exception, err, msg=vars())
def colorControl(target=None, direction='center', controlType='main', pushToShapes=True, rgb=True, shaderSetup=True, shaderOnly=False, transparent=False, proxy=False, directProxy=False): """ Sets the override color on shapes and more :parameters target(str): What to color - shape or transform with shapes direction controlType pushToShapes rgb shaderSetup transparent proxy - offsets the color down to not match curve color exactly directProxy(bool) - Setpu transparent shader for 'invisible' controls :returns info(dict) """ _str_func = "color_control" if not target: raise ValueError, "|{0}| >> Must have a target".format(_str_func) l_targets = VALID.listArg(target) if rgb: _color = SHARED._d_side_colors[direction][controlType] else: _color = SHARED._d_side_colors_index[direction][controlType] _shader = False _set = False if shaderSetup: _shader, _set = getControlShader(direction, controlType, transparent, proxy, directProxy) for t in l_targets: log.debug("|{0}| >> t: {1} ...".format(_str_func, t)) _type = VALID.get_mayaType(t) log.debug("|{0}| >> shapes: {1} ...".format(_str_func, TRANS.shapes_get(t, True))) log.debug("|{0}| >> type: {1} ...".format(_str_func, _type)) if not shaderOnly: if rgb: override_color(t, _color, pushToShapes=pushToShapes) else: _v = SHARED._d_colors_to_index[_color] override_color(t, index=_v, pushToShapes=pushToShapes) if shaderSetup: mc.sets(t, edit=True, remove='initialShadingGroup') if _type in ['nurbsSurface', 'mesh']: mc.sets(t, e=True, forceElement=_set) else: for s in TRANS.shapes_get(t, True): log.debug("|{0}| >> s: {1} ...".format(_str_func, s)) _type = VALID.get_mayaType(s) if _type in ['nurbsSurface', 'mesh']: mc.sets(s, edit=True, forceElement=_set) mc.sets(s, remove='initialShadingGroup') try: mc.disconnectAttr( '{0}.instObjGroups.objectGroups'.format(s), 'initialShadingGroup.dagSetMembers') except: pass else: log.debug( "|{0}| >> Not a valid target: {1} | {2}".format( _str_func, s, _type)) mc.sets(t, edit=True, remove='initialShadingGroup') return True
def get_space_value(arg, mode='mayaSpace'): """ Space conversion of values. api which is in cm to maya space and vice versa :parameters: arg(float/list) mode(str) mayaSpace -- api(cm) to maya apiSpace -- maya to api(cm) :returns converted value(s) :Acknowledgement Thanks to parentToSurface.mel from autodesk for figuring out this was necessary """ _str_func = 'get_space_value' _values = VALID.listArg(arg) _res = [] unit = mc.currentUnit(q=True, linear=True) if mode == 'mayaSpace': for v in _values: if unit == 'mm': _res.append(v * 10) elif unit == 'cm': _res.append(v) elif unit == 'm': _res.append(v * .01) elif unit == 'in': _res.append(v * 0.393701) elif unit == 'ft': _res.append(v * 0.0328084) elif unit == 'yd': _res.append(v * 0.0109361) else: raise ValueError, "|{0}| >> nonhandled unit: {1}".format( _str_func, unit) elif mode == 'apiSpace': for v in _values: if unit == 'mm': _res.append(v * .1) elif unit == 'cm': _res.append(v) elif unit == 'm': _res.append(v * 100) elif unit == 'in': _res.append(v * 2.54) elif unit == 'ft': _res.append(v * 30.48) elif unit == 'yd': _res.append(v * 91.44) else: raise ValueError, "|{0}| >> nonhandled unit: {1}".format( _str_func, unit) else: raise ValueError, "|{0}| >> unknown mode: {1}".format(_str_func, mode) if len(_res) == 1: return _res[0] return _res
def optimize(nodeTypes='multiplyDivide'): _str_func = 'optimize' log.debug("|{0}| >> ".format(_str_func) + '-' * 80) _nodeTypes = VALID.listArg(nodeTypes) d_modeToNodes = {} d_modeToPlugs = {} l_oldNodes = [] for t in _nodeTypes: if t in ['plusMinusAverage']: raise ValueError, "Don't handle type: {0}".format(t) nodes = mc.ls(type=t) l_oldNodes.extend(nodes) for n in nodes: _mode = ATTR.get(n, 'operation') _operator = ATTR.get_enumValueString(n, 'operation') #d_operator_to_NodeType[t][_mode] if not d_modeToNodes.get(_mode): d_modeToNodes[_mode] = [] d_modeToNodes[_mode].append(n) d_plugs = {} d_plugValues = {} for i, inPlug in enumerate(d_node_to_input[t]['in']): d_plugs[i] = ATTR.get_children(n, inPlug) or [] for p in d_plugs[i]: c = ATTR.get_driver(n, p, False, skipConversionNodes=True) if c: d_plugValues[p] = c else: d_plugValues[p] = ATTR.get(n, p) l_outs = ATTR.get_children(n, d_node_to_input[t]['out']) or [] for p in l_outs: d_plugValues[p] = ATTR.get_driven(n, p, False, skipConversionNodes=True) #pprint.pprint(d_modeToNodes) #pprint.pprint(d_plugs) #print l_outs #print cgmGeneral._str_subLine #pprint.pprint(d_plugValues) for i in range(len(l_outs)): _out = d_plugValues[l_outs[i]] if _out: d_set = {'out': _out, 'in': []} log.debug("|{0}| >> Output found on: {1} ".format( _str_func, _out)) _keys = d_plugs.keys() _keys.sort() for k in _keys: d_set['in'].append(d_plugValues[d_plugs[k][i]]) #d_set['in'].append(d_plugs[k][i]) #pprint.pprint(d_set) if not d_modeToPlugs.get(_mode): d_modeToPlugs[_mode] = [] d_modeToPlugs[_mode].append(d_set) # if VALID.stringArg() l_inPlugs = ['input1', 'input2'] l_outplugs = [u'output'] l_new = [] _cnt = 0 for operator, d_sets in d_modeToPlugs.iteritems(): if operator == 1: for nodeSet in d_sets: newNode = mc.createNode('multDoubleLinear') newNode = mc.rename(newNode, 'optimize_{0}_mdNode'.format(_cnt)) _cnt += 1 l_new.append(newNode) _ins = d_set['in'] _outs = d_set['out'] for iii, inPlug in enumerate(_ins): if mc.objExists(inPlug): ATTR.connect(inPlug, "{0}.{1}".format(newNode, l_inPlugs[iii])) else: ATTR.set(newNode, l_inPlugs[iii], inPlug) for out in _outs: ATTR.connect("{0}.output".format(newNode), out) #pprint.pprint(d_setsSorted) print len(d_sets) #print len(d_setsSorted) """ l_inPlugs = {0: [u'input1X', u'input1Y', u'input1Z'], 1: [u'input2X', u'input2Y', u'input2Z']} l_outplugs = [u'outputX', u'outputY', u'outputZ'] for operator,d_sets in d_modeToPlugs.iteritems(): d_setsSorted = LISTS. get_chunks(d_sets,3) for nodeSet in d_setsSorted: newNode = mc.createNode('multiplyDivide') newNode = mc.rename(newNode,'optimize_{0}_mdNode'.format(_cnt)) _cnt+=1 l_new.append(newNode) ATTR.set(newNode,'operation',operator) for i,d_set in enumerate(nodeSet): _ins = d_set['in'] _outs = d_set['out'] for iii,inPlug in enumerate(_ins): if mc.objExists(inPlug): ATTR.connect(inPlug, "{0}.{1}".format(newNode, l_inPlugs[iii][i])) else: ATTR.set(newNode,l_inPlugs[iii][i], inPlug) for out in _outs: ATTR.connect("{0}.{1}".format(newNode, l_outplugs[i]), out) #pprint.pprint(d_setsSorted) print len(d_sets) print len(d_setsSorted) """ mc.delete(l_oldNodes) return len(l_new)
def controls_getDat(self, keys=None, ignore=[], report=False, listOnly=False): """ Function to find all the control data for comparison for mirroing or other reasons """ def addMObj(mObj, mList): if mObj not in mList: log.debug("|{0}| >> adding: {1}".format(_str_func, mObj)) mList.append(mObj) """ if ml_objs is not None: if mObj in ml_objs: ml_objs.remove(mObj) else: log.warning("|{0}| >> Not in list. Skipped: {1}".format(_str_func,mObj)) return log.debug("|{0}| >> adding: {1}".format(_str_func,mObj)) mList.append(mObj)""" _str_func = ' controls_getDat' log.debug("|{0}| >> ".format(_str_func) + '-' * 80) log.debug("{0}".format(self)) ignore = VALID.listArg(ignore) ml_objs = [] #try:ml_objs = self.puppetSet.getMetaList() or [] #except:pass #l_objs = [mObj.mNode for mObj in ml_objs] md_controls = {} ml_controls = [] if ml_objs: for mObj in ml_objs: if mObj.getMayaType() == 'objectSet': ml_objs.remove(mObj) if keys: l_useKeys = VALID.listArg(keys) else: l_useKeys = l_controlOrder if ignore: log.debug("|{0}| >> Ignore found... ".format(_str_func) + '-' * 20) for k in ignore: if k in l_useKeys: l_useKeys.remove(k) for key in l_useKeys: l_options = d_controlLinks.get(key, [key]) log.debug("|{0}| >> {1}:{2}".format(_str_func, key, l_options)) md_controls[key] = [] _ml = md_controls[key] for o in l_options: mObj = self.getMessageAsMeta(o) if mObj: log.debug("|{0}| >> Message found: {1} ".format(_str_func, o)) addMObj(mObj, _ml) elif self.msgList_exists(o): log.debug("|{0}| >> msgList found: {1} ".format(_str_func, o)) _msgList = self.msgList_get(o) for mObj in _msgList: addMObj(mObj, _ml) ml_controls.extend(_ml) if ml_objs: ml_dup = copy.copy(ml_objs) log.debug( "|{0}| >> Second pass {1}... ".format(_str_func, len(ml_objs)) + '-' * 20) for mObj in ml_dup: log.debug("|{0}| >> {1} ".format(_str_func, mObj)) if mObj.hasAttr('cgmControlDat'): _tags = mObj.cgmControlDat.get('tags', []) log.debug("|{0}| >> tags: {1} ".format(_str_func, _tags)) for t in _tags: _t = str(t) #if keys is not None and _t not in l_useKeys: # continue if not md_controls.get(_t): md_controls[_t] = [] _ml = md_controls[_t] ml_controls.append(mObj) addMObj(mObj, _ml) if not keys and 'spacePivots' not in ignore: md_controls['spacePivots'] = [] _ml = md_controls['spacePivots'] for mObj in ml_controls: mBuffer = mObj.msgList_get('spacePivots') for mSpace in mBuffer: addMObj(mSpace, _ml) ml_controls.append(mSpace) if report: log.info("|{0}| >> Dict... ".format(_str_func)) pprint.pprint(md_controls) log.info("|{0}| >> List... ".format(_str_func)) pprint.pprint(ml_controls) if ml_objs and keys is None and not ignore: log.debug("|{0}| >> remaining... ".format(_str_func)) pprint.pprint(ml_objs) raise ValueError, ( "|{0}| >> Resolve missing controls!".format(_str_func)) #return log.error("|{0}| >> Resolve missing controls!".format(_str_func)) if report: return if keys or listOnly: return ml_controls return md_controls, ml_controls