def snap(obj=None, targets=None, position=True, rotation=True, rotateAxis=False, rotateOrder=False, rotatePivot=False, scalePivot=False, objPivot='rp', objMode=None, objLoc=False, targetPivot='rp', targetMode=None, targetLoc=False, queryMode=False, space='w', mark=False, **kws): """ Core snap functionality. :parameters: obj(str): Object to modify target(str): Objects to snap to objPivot targetPivot objMode = targetMode position rotation rotateAxis rotateOrder scalePivot space mark :returns success(bool) """ try: _str_func = 'snap' try: obj = obj.mNode except: pass _obj = VALID.mNodeString(obj) if targets is None: log.debug("|{0}| >> self target... ".format(_str_func)) _targets = [_obj] else: _targets = VALID.mNodeStringList(targets) reload(VALID) _pivotObj = VALID.kw_fromDict(objPivot, SHARED._d_pivotArgs, noneValid=True) _pivotTar = VALID.kw_fromDict(targetPivot, SHARED._d_pivotArgs, noneValid=True) _space = VALID.kw_fromDict(space, SHARED._d_spaceArgs, noneValid=False, calledFrom=__name__ + _str_func + ">> validate space") log.debug( "|{0}| >> obj: {1}({2}-{3}) | target:({4}-{5})({6}) | space: {7}". format(_str_func, _obj, _pivotObj, objMode, _pivotTar, targetMode, _targets, _space)) log.debug( "|{0}| >> position: {1} | rotation:{2} | rotateAxis: {3} | rotateOrder: {4}" .format(_str_func, position, rotation, rotateAxis, rotateOrder)) kws_xform = {'ws': False, 'os': False} if _space == 'world': kws_xform['ws'] = True else: kws_xform['os'] = True #Mode type defaults... if objMode is None: if _pivotObj is 'boundingBox': objMode = 'center' elif _pivotObj in ['castCenter', 'castFar', 'castNear', 'axisBox']: objMode = 'z+' if targetMode is None: if _pivotTar is 'boundingBox': targetMode = 'center' elif _pivotTar in ['castCenter', 'castFar', 'castNear', 'axisBox']: targetMode = 'z+' if _pivotTar in ['castFar', 'castAllFar', 'castNear', 'castAllNear']: if targetMode == 'center': log.debug( "|{0}| >> Center target mode invalid with {1}. Changing to 'z+' " .format(_str_func, _pivotTar)) targetMode = 'z+' #cgmGEN.func_snapShot(vars()) if position or objLoc or targetLoc or rotatePivot or scalePivot: kws_xform_move = copy.copy(kws_xform) if _pivotTar == 'sp': kws_xform_move['spr'] = True else: kws_xform_move['rpr'] = True #>>>Target pos ------------------------------------------------------------------------------ log.debug( "|{0}| >> Position True. Getting target pivot pos {1} ".format( _str_func, _pivotTar)) l_nameBuild = [ '_'.join([NAMES.get_base(o) for o in _targets]), _pivotTar ] if targetMode and _pivotTar not in [ 'sp', 'rp', 'closestPoint', 'groundPos' ]: l_nameBuild.append(targetMode) l_pos = [] if _pivotTar in ['sp', 'rp']: log.debug("|{0}| >> xform query... ".format(_str_func)) for t in _targets: l_pos.append(POS.get(t, _pivotTar, _space)) pos_target = DIST.get_average_position(l_pos) elif _pivotTar == 'closestPoint': log.debug("|{0}|...closestPoint...".format(_str_func)) pos_target = DIST.get_by_dist(_obj, _targets, resMode='pointOnSurface') else: log.debug("|{0}| >> special query... ".format(_str_func)) _targetsSpecial = copy.copy(_targets) if _pivotTar not in [ 'axisBox', 'groundPos', 'castCenter', 'boundingBox' ]: _targetsSpecial.insert(0, _obj) pos_target = get_special_pos(_targetsSpecial, _pivotTar, targetMode) if not pos_target: return log.error("No position detected") if targetLoc: _loc = mc.spaceLocator()[0] mc.move(pos_target[0], pos_target[1], pos_target[2], _loc, ws=True) mc.rename(_loc, '{0}_loc'.format('_'.join(l_nameBuild))) log.debug("|{0}| >> Target pivot: {1}".format( _str_func, pos_target)) #>>>Obj piv ------------------------------------------------------------------------------ log.debug("|{0}| >> Getting obj pivot pos {1} ".format( _str_func, _pivotObj)) l_nameBuild = [NAMES.get_base(_obj), _pivotObj] if objMode and _pivotObj not in [ 'sp', 'rp', 'closestPoint', 'groundPos' ]: l_nameBuild.append(objMode) l_pos = [] if _pivotObj in ['sp', 'rp']: log.debug("|{0}| >> xform query... ".format(_str_func)) pos_obj = POS.get(_obj, _pivotObj, _space) elif _pivotObj == 'closestPoint': log.debug("|{0}|...closestPoint...".format(_str_func)) pos_obj = DIST.get_by_dist(_targets[0], _obj, resMode='pointOnSurface') else: log.debug("|{0}| >> special query... ".format(_str_func)) pos_obj = get_special_pos(_obj, _pivotObj, objMode) if objLoc: _loc = mc.spaceLocator()[0] mc.move(pos_obj[0], pos_obj[1], pos_obj[2], _loc, ws=True) mc.rename(_loc, '{0}_loc'.format('_'.join(l_nameBuild))) log.debug("|{0}| >> Obj pivot: {1}".format(_str_func, pos_obj)) if queryMode: pprint.pprint(vars()) log.warning("|{0}| >> Query mode. No snap".format(_str_func)) mc.select([_obj] + _targets) return True #>>>Obj piv ------------------------------------------------------------------------------ if position: log.debug("|{0}| >> Positioning... ".format(_str_func)) if _pivotObj == 'rp': TRANS.position_set(obj, pos_target) #POS.set(_obj, pos_target) else: p_start = TRANS.position_get(_obj) _vector_to_objPivot = COREMATH.get_vector_of_two_points( p_start, pos_obj) _dist_base = DIST.get_distance_between_points( p_start, pos_obj) #...get our base distance p_result = DIST.get_pos_by_vec_dist( pos_target, _vector_to_objPivot, -_dist_base) cgmGEN.func_snapShot(vars()) POS.set(_obj, p_result) if rotateAxis: log.debug("|{0}|...rotateAxis...".format(_str_func)) mc.xform(obj, ra=mc.xform(_targets[0], q=True, ra=True, **kws_xform), p=True, **kws_xform) if rotateOrder: log.debug("|{0}|...rotateOrder...".format(_str_func)) mc.xform(obj, roo=mc.xform(_targets[0], q=True, roo=True), p=True) if rotation: log.debug("|{0}|...rotation...".format(_str_func)) _t_ro = ATTR.get_enumValueString(_targets[0], 'rotateOrder') _obj_ro = ATTR.get_enumValueString(obj, 'rotateOrder') if _t_ro != _obj_ro: #Creating a loc to get our target space rotateOrder into new space log.debug( "|{0}|...rotateOrders don't match...".format(_str_func)) _loc = mc.spaceLocator(n='tmp_roTranslation')[0] ATTR.set(_loc, 'rotateOrder', _t_ro) rot = mc.xform(_targets[0], q=True, ro=True, **kws_xform) mc.xform(_loc, ro=rot, **kws_xform) mc.xform(_loc, roo=_obj_ro, p=True) rot = mc.xform(_loc, q=True, ro=True, **kws_xform) mc.delete(_loc) else: rot = mc.xform(_targets[0], q=True, ro=True, **kws_xform) mc.xform(_obj, ro=rot, **kws_xform) if rotatePivot: log.debug("|{0}|...rotatePivot...".format(_str_func)) mc.xform(obj, rp=pos_target, p=True, **kws_xform) if scalePivot: log.debug("|{0}|...scalePivot...".format(_str_func)) mc.xform(obj, sp=pos_target, p=True, **kws_xform) except Exception, err: cgmGEN.cgmExceptCB(Exception, err)
def alongLine(objList=None, mode='even', curve='linear', spans=2): """ Arrange a list of objects evenly along a vector from first to last :parameters: objList(list): objects to layout mode(string) 'even' - evenly distributed along line 'spaced' - distribute along line as close as possible to current position :returns list of constraints(list) """ _str_func = 'onLine' objList = VALID.mNodeStringList(objList) log.info("|{0}| >> ObjList: {1} ".format(_str_func, objList)) _len = len(objList) if _len < 3: raise ValueError, "|{0}| >> Need at least 3 objects".format(_str_func) _pos_start = POS.get(objList[0]) _pos_end = POS.get(objList[-1]) curveBuffer = [] if curve == 'linear': if mode != 'even': curveBuffer = mc.curve(d=1, ep=[_pos_start, _pos_end]) elif curve in ['cubic', 'cubicRebuild']: l_pos = [POS.get(o) for o in objList] knot_len = len(l_pos) + 3 - 1 crv1 = mc.curve(d=3, ep=l_pos, k=[i for i in range(0, knot_len)], os=True) curveBuffer = [crv1] if curve == 'cubicRebuild': curveBuffer.append( mc.rebuildCurve(crv1, ch=0, rpo=0, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=spans, d=3, tol=0.001)[0]) elif curve == 'cubicArc': _mid = MATH.get_midIndex(_len) log.info("|{0}| >> cubicArc | mid: {1} ".format(_str_func, _mid)) l_pos = [POS.get(o) for o in [objList[0], objList[_mid], objList[-1]]] knot_len = len(l_pos) + 3 - 1 curveBuffer = mc.curve(d=3, ep=l_pos, k=[i for i in range(0, knot_len)], os=True) else: raise ValueError, "|{0}| >>unknown curve setup: {1}".format( _str_func, curve) if mode == 'even': if curve == 'linear': _vec = MATH.get_vector_of_two_points(_pos_start, _pos_end) _offsetDist = DIST.get_distance_between_points( _pos_start, _pos_end) / (_len - 1) _l_pos = [ DIST.get_pos_by_vec_dist(_pos_start, _vec, (_offsetDist * i)) for i in range(_len) ] log.info("|{0}| >> offset: {1} ".format(_str_func, _offsetDist)) log.info("|{0}| >> l_pos: {1} ".format(_str_func, _l_pos)) for i, o in enumerate(objList[1:-1]): POS.set(o, _l_pos[i + 1]) else: _l_pos = CURVES.getUSplitList(curveBuffer, points=_len, rebuild=1) for i, o in enumerate(objList[1:-1]): POS.set(o, _l_pos[i + 1]) elif mode == 'spaced': _l_pos = [] for i, o in enumerate(objList[1:-1]): #SNAP.go(o,curveBuffer,pivot= 'closestPoint') p = DIST.get_by_dist(o, curveBuffer, resMode='pointOnSurface') POS.set(o, p) _l_pos.append(p) else: try: raise ValueError, "{0} >> mode not supported: {1}".format( sys._getframe().f_code.co_name, mode) except: raise ValueError, "mode not supported: {0}".format(mode) if curveBuffer: mc.delete(curveBuffer) return _l_pos
def getAndMove(loc, targets=None, mode=None, forceBBCenter=False): log.debug("|{0}| >> mode: {1} | targets: {2}".format( _str_func, mode, targets)) if not targets: raise ValueError, "Must have targets" _kws = {'target': loc, 'move': True, 'rotate': True} if mode == 'fromTarget': _d = POS.get_info(targets[0]) _kws['infoDict'] = _d elif mode == 'midPoint': if len(targets) == 1: _d = POS.get_info(targets[0], boundingBox=True) _kws['infoDict'] = _d elif not len(targets) >= 2: raise ValueError, "midPoint mode must have at least two targets" else: _d = get_midPointDict(targets, forceBBCenter) _kws['infoDict'] = _d elif mode == 'closestPoint': if not len(targets) >= 2: raise ValueError, "midPoint mode must have at least two targets" _d = { 'position': DIST.get_by_dist(targets[0], targets[1:], resMode='pointOnSurface') } _kws['infoDict'] = _d _kws['rotate'] = False elif mode == 'closestTarget': if not len(targets) >= 3: raise ValueError, "midPoint mode must have at least three targets" _d = POS.get_info( DIST.get_by_dist(targets[0], targets[1:], resMode='object')) _d['rotateOrder'] = False _d['rotateAxis'] = False _kws['infoDict'] = _d elif mode == 'rayCast': _dbuffer = r9Meta.MetaClass(_loc).cgmLocDat _d = {} _p = POS.get_uv_position(_target[0], _dbuffer['uv']) if _dbuffer.get('offsetDist'): _v = POS.get_uv_normal(_target[0], _dbuffer['uv']) _dist = _dbuffer.get('offsetDist') _p = DIST.get_pos_by_vec_dist(_p, _v, _dist) _d['position'] = _p _kws['infoDict'] = _d _kws['rotate'] = False else: log.error("|{0}| >> unknown mode: {1}".format(_str_func, _mode)) return False 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
def go(obj = None, target = None, position = True, rotation = True, rotateAxis = False,rotateOrder = False, scalePivot = False, pivot = 'rp', space = 'w', mode = 'xform'): """ Core snap functionality. We're moving an object by it's rp to move it around. The scale pivot may be snapped as well :parameters: obj(str): Object to modify target(str): Object to snap to sourceObject(str): object to copy from :returns success(bool) """ _str_func = 'go' try:obj = obj.mNode except:pass _obj = VALID.mNodeString(obj) _target = VALID.mNodeString(target) _pivot = VALID.kw_fromDict(pivot, SHARED._d_pivotArgs, noneValid=False,calledFrom= __name__ + _str_func + ">> validate pivot") _space = VALID.kw_fromDict(space,SHARED._d_spaceArgs,noneValid=False,calledFrom= __name__ + _str_func + ">> validate space") #_mode = VALID.kw_fromDict(mode,_d_pos_modes,noneValid=False,calledFrom= __name__ + _str_func + ">> validate mode") _mode = mode log.debug("|{0}| >> obj: {1} | target:{2} | pivot: {5} | space: {3} | mode: {4}".format(_str_func,_obj,_target,_space,_mode,_pivot)) log.debug("|{0}| >> position: {1} | rotation:{2} | rotateAxis: {3} | rotateOrder: {4}".format(_str_func,position,rotation,rotateAxis,rotateOrder)) kws = {'ws':False,'os':False} if _space == 'world': kws['ws']=True else:kws['os']=True #cgmGEN.walk_dat(kws) if position: kws_move = copy.copy(kws) if _pivot == 'sp': kws_move['spr'] = True else: kws_move['rpr'] = True if _pivot == 'closestPoint': log.debug("|{0}|...closestPoint...".format(_str_func)) _targetType = SEARCH.get_mayaType(_target) p = DIST.get_by_dist(_obj,_target,resMode='pointOnSurface') POS.set(_obj,p) else: log.debug("|{0}|...postion...".format(_str_func)) pos = POS.get(target,_pivot,_space,_mode) #log.debug(pos) #cgmGEN.print_dict(kws,'move kws','snap.go') mc.move (pos[0],pos[1],pos[2], _obj, **kws_move) #log.debug(POS.get(_obj)) if rotateAxis: log.debug("|{0}|...rotateAxis...".format(_str_func)) mc.xform(obj,ra = mc.xform(_target, q=True, ra=True, **kws), p=True, **kws) if rotateOrder: log.debug("|{0}|...rotateOrder...".format(_str_func)) mc.xform(obj,roo = mc.xform(_target, q=True, roo=True), p=True) if rotation: log.debug("|{0}|...rotation...".format(_str_func)) _t_ro = ATTR.get_enumValueString(_target,'rotateOrder') _obj_ro = ATTR.get_enumValueString(obj,'rotateOrder') if _t_ro != _obj_ro: #Creating a loc to get our target space rotateOrder into new space log.debug("|{0}|...rotateOrders don't match...".format(_str_func)) _loc = mc.spaceLocator(n='tmp_roTranslation')[0] ATTR.set(_loc,'rotateOrder',_t_ro) rot = mc.xform (_target, q=True, ro=True, **kws ) mc.xform(_loc, ro = rot, **kws) mc.xform(_loc, roo = _obj_ro, p=True) rot = mc.xform (_loc, q=True, ro=True, **kws ) mc.delete(_loc) else: rot = mc.xform (_target, q=True, ro=True, **kws ) mc.xform(_obj, ro = rot, **kws) if scalePivot: log.debug("|{0}|...scalePivot...".format(_str_func)) mc.xform(obj,sp = mc.xform(_target, q=True, sp=True,**kws), p=True, **kws) return pos = infoDict['position'] mc.move (pos[0],pos[1],pos[2], _target, ws=True) mc.xform(_target, roo=infoDict['rotateOrder'],p=True) mc.xform(_target, ro=infoDict['rotation'], ws = True) mc.xform(_target, ra=infoDict['rotateAxis'],p=True) #mTarget = r9Meta.getMObject(target) mc.xform(_target, rp=infoDict['position'], ws = True, p=True) mc.xform(_target, sp=infoDict['scalePivot'], ws = True, p=True)