Maya: 第三周 作业

lesson7_轻松获取节点连接关系


image.png

动画数据转移.gif

思路:1.找出与源物体的相连接的animCurve节点(判断出哪些属性有K帧)
2.通过animCurve节点找出属性接口的完整连接关系
3.把完整连接关系的列表中的来源物体名字替换为目标物体名字
4.用参数控制是否断开来源物体连接
5.连接目标物体

import maya.cmds as cmds


def transfer_keyframe_connection(source_obj, target_obj, source_disconnect=True):
    """Transfer Keyframe Connection From Source Object To Target Object

    :param source_obj: Str
    :param target_obj: Str
    :param source_disconnect: Bool. 
    :return:
    """

    source_anim_curves = cmds.listConnections(source_obj, t="animCurve")
    if not source_anim_curves:
        cmds.inViewMessage(
            amg="<hl> Warning: The Source Object Has Not Any Keyframe ! </hl>.",
            pos='midCenter', fade=True)
        return False

    source_obj_keyframe_connection = [cmds.listConnections(anim_crv, c=True, p=True) for anim_crv in source_anim_curves]       
    target_obj_keyframe_connection = [[c[0], c[1].replace(c[1].split('.')[0], target_obj)] for c in 
                                      source_obj_keyframe_connection]
    for index, items in enumerate(source_obj_keyframe_connection):
        if source_disconnect:
            cmds.disconnectAttr(items[0], items[1])
        cmds.connectAttr(target_obj_keyframe_connection[index][0], target_obj_keyframe_connection[index][1])

transfer_keyframe_connection('pSphere1', 'pCube1', source_disconnect=True)

lesson8_几种物体约束的命令


image.png

控制器.gif

思路:
1.利用约束的保持偏移的属性来吸附到物体坐标以及方向
2.独立写一个函数来处理控制器形态的改变,如果没有指定控制器形态则默认形态是圆环控制器
3.利用参数控制控制器是否对物体有父子约束,缩放约束以及偏移组的个数

import maya.cmds as cmds


def transfer_curve_shape(source_obj, target_obj):
    """Transfer Shapes From Source Object To Target Object

    :param source_obj:str. curve object
    :param target_obj:str. curve object
    :return:str
    """

    target_obj_shapes = cmds.listRelatives(target_obj, s=True)
    if not target_obj_shapes:
        return False
    cmds.delete(target_obj_shapes)
    temp_source_obj = cmds.duplicate(source_obj, n='_{}_TEMP_CURVE'.format(source_obj))[0]
    if cmds.listRelatives(temp_source_obj, p=True):
        cmds.parent(temp_source_obj, w=True)
    temp_source_obj_shapes = cmds.listRelatives(temp_source_obj, s=True)
    if not temp_source_obj_shapes:
        return False
    cmds.xform(temp_source_obj, cp=1)
    temp_world_grp = cmds.group(em=True)
    cmds.delete(cmds.parentConstraint(temp_world_grp, temp_source_obj))
    cmds.makeIdentity(temp_source_obj, n=0, s=1, r=1, t=1, apply=True, pn=1)

    for s in temp_source_obj_shapes:
        cmds.parent(s, target_obj, s=True, add=True)
    cmds.delete(temp_source_obj, temp_world_grp)
    new_target_obj_shapes = cmds.listRelatives(target_obj, s=True)
    for index, s in enumerate(new_target_obj_shapes):
        cmds.rename(s, '{}Shape{}'.format(target_obj, index + 1))

    return target_obj


def controller(target_obj, controller_shape=None, controller_name=None, offset_group_number=0,
               object_mode=True, parent_constrain=True, scale_constrain=False):
    """Create controller for object

    :param target_obj: Str
    :param controller_name: Str
    :param controller_shape: Str . You Can Custom Controller Shape
    :param offset_group_number: Int
    :param object_mode: Bool.
    :param parent_constrain: Bool.
    :param scale_constrain: Bool.
    :return: list. Controller Name And Offset Groups
    """
    if not controller_name:
        controller_name = '{}_control'.format(target_obj)
    control_grp = cmds.group(em=True, n='{}_grp'.format(controller_name))
    default_con = cmds.circle(n=controller_name, nr=(0, 1, 0))
    if controller_shape:
        transfer_curve_shape(controller_shape, default_con[0])
    cmds.parent(default_con[0], control_grp)
    offset_grp = []
    if offset_group_number > 0:
        for i in range(offset_group_number):
            temp_grp = cmds.group(default_con[0],
                                  name='{}_offset_{}_grp'.format(default_con[0], offset_group_number - i))
            offset_grp.append(temp_grp)
    offset_grp.append(control_grp)
    
    if object_mode:
        cmds.delete(cmds.parentConstraint(target_obj, control_grp))

    if parent_constrain:
        cmds.parentConstraint(default_con[0], target_obj, mo=True, weight=True)

    if scale_constrain:
        cmds.scaleConstraint(default_con[0], target_obj, mo=True, weight=True)
    
    return [default_con[0], offset_grp]

controller('joint1', 
           controller_shape='nurbsCircle1', 
           controller_name='test_joint_ctrl',
           object_mode=True, 
           parent_constrain=True, 
           scale_constrain=True,
           offset_group_number=3)

lesson9_创建和获取关键帧信息


image.png

随机抖动.gif

思路:
1.利用animCurve类型来判断需要抖动的属性是否有关键帧,如果有则利用listAttr的time参数来获取时间段每一帧的属性数值
2.利用range函数的step参数来控制时间段的间隔,这样可以控制隔几帧K下关键帧
3.利用keyTangent函数改变K帧后的曲线模式
4.利用参数控制曲线模式改变的开启与关闭(比如想保留当前随机出来的结果,那么就可以开启edit_key_tangent参数来改变曲线的模式)
5.抖动则可以用sin 或者cos函数,随机浮点则可以用 random.uniform或者随机整数

import random
import math
import maya.cmds as cmds


def random_shake(target_obj, time_range=None, keyframe_step=1, 
                 shake_offset_range=5, attr_name=None, attr_original_value=0,
                 key_tangent='auto', edit_key_tangent=False):
    """Random Shake For Object. Support Set Offset Keyframe Base On Original Value

    :param target_obj:Str
    :param time_range:list. time range
    :param keyframe_step:Int. Step for keyframe
    :param shake_offset_range: Amplitude for shake
    :param attr_name:Str. attr name
    :param attr_original_value:float . attr original value
    :param key_tangent:Str "auto", "spline", "clamped", "linear", "flat"
    :param edit_key_tangent:Bool
    :return: None
    """
    if attr_name is None:
        attr_name = 'ty'
    if time_range is None:
        time_range = [0, 100]
    if not edit_key_tangent:
        current_attr_value = attr_original_value
        attr_anim_curves = cmds.listConnections("{}.{}".format(target_obj, attr_name), t="animCurve")
        for i in range(time_range[0], time_range[-1] + 1, keyframe_step):
            shake_value = math.sin(i) * random.uniform(0, shake_offset_range)
            if attr_anim_curves:
                current_attr_value = cmds.getAttr("{}.{}".format(target_obj, attr_name), t=i)
            cmds.setKeyframe(target_obj, at=attr_name, time=i, v=shake_value + current_attr_value)

    new_anim_curves = cmds.listConnections("{}.{}".format(target_obj, attr_name), t="animCurve")
    if not new_anim_curves:
        return False
    cmds.keyTangent(new_anim_curves[0], itt=key_tangent, ott=key_tangent)

random_shake('pSphere1',
             time_range=[1, 200],
             keyframe_step=5,
             shake_offset_range=3,
             attr_name='ty',
             key_tangent="auto",
             attr_original_value=10,
             edit_key_tangent=False)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348