python类addAttr()的实例源码

interactive.py 文件源码 项目:config 作者: mindbender-studio 项目源码 文件源码 阅读 29 收藏 0 点赞 0 评论 0
def clone_special(*args):
    """Clone in localspace, and preserve user-defined attributes"""

    for transform in cmds.ls(selection=True, long=True):
        if cmds.nodeType(transform) != "transform":
            cmds.warning("Skipping '%s', not a `transform`" % transform)
            continue

        shape = _find_shape(transform)
        type = cmds.nodeType(shape)

        if type not in ("mesh", "nurbsSurface", "nurbsCurve"):
            cmds.warning("Skipping '{transform}': cannot clone nodes "
                         "of type '{type}'".format(**locals()))
            continue

        cloned = commands.clone(shape, worldspace=False)
        new_transform = cmds.listRelatives(cloned,
                                           parent=True,
                                           fullPath=True)[0]

        new_transform = cmds.rename(new_transform,
                                    new_transform.rsplit(":", 1)[-1])

        for attr in cmds.listAttr(transform,
                                  userDefined=True) or list():
            try:
                cmds.addAttr(new_transform, longName=attr, dataType="string")
            except Exception:
                continue

            value = cmds.getAttr(transform + "." + attr)
            cmds.setAttr(new_transform + "." + attr, value, type="string")

        # Connect visibility
        cmds.connectAttr(transform + ".visibility",
                         new_transform + ".visibility")
zbw_softDeformer.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 28 收藏 0 点赞 0 评论 0
def softWave(sftmod, arrow, ctrl,  *args):
    # add values to positions in graph
    positions = [0.0, 0.3, 0.6, 0.9, 0.95]
    values = [1.0, -0.3, 0.1, -0.05, 0.01]
    for i in range(len(positions)):
        cmds.setAttr("{0}.falloffCurve[{1}].falloffCurve_Position".format(sftmod, i), positions[i])
        cmds.setAttr("{0}.falloffCurve[{1}].falloffCurve_FloatValue".format(sftmod, i), values[i])
        cmds.setAttr("{0}.falloffCurve[{1}].falloffCurve_Interp".format(sftmod, i), 2)

    cmds.addAttr(arrow, ln="WaveAttrs", at="enum", k=True)
    cmds.setAttr("{0}.WaveAttrs".format(arrow), l=True)

    # expose these on the control
    for j in range(5):
        cmds.addAttr(arrow, ln="position{0}".format(j), at="float", min=0.0, max=1.0, dv=positions[j], k=True)
        cmds.connectAttr("{0}.position{1}".format(arrow, j),
                         "{0}.falloffCurve[{1}].falloffCurve_Position".format(sftmod, j))

    for j in range(5):
        cmds.addAttr(arrow, ln="value{0}".format(j), at="float", min=-1.0, max=1.0, dv=values[j], k=True)
        cmds.connectAttr("{0}.value{1}".format(arrow, j),
                         "{0}.falloffCurve[{1}].falloffCurve_FloatValue".format(sftmod, j))
        cmds.setAttr("{0}.position{1}".format(arrow, j), l=True)
        cmds.setAttr("{0}.value{1}".format(arrow, j), l=True)
zbw_attributes.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 30 收藏 0 点赞 0 评论 0
def locked_attr(*args):
    """
    creates a locked attr (I use as a separator). Uses the long name as the nice name (literal name in channel box)
    """
    attrName = cmds.textFieldButtonGrp(widgets["lockAttrTFBG"], q=True, tx=True)

    if attrName:
        sel = cmds.ls(sl=True)

        if sel:
            for obj in sel:
                try:
                    cmds.addAttr(obj, ln=attrName, nn=attrName, at="enum", en="-----", k=True)
                    cmds.setAttr("%s.%s" % (obj, attrName), l=True)
                except:
                    cmds.warning("Failed to add %s to %s, skipping!" % (attrName, obj))
        else:
            cmds.warning("Please select some objects to add attr to!")
    else:
        cmds.warning("Please enter a name for the attr!")
zbw_attributes.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 22 收藏 0 点赞 0 评论 0
def add_zero_one_attribute(attrType, *args):
    """
    adds an attribute with range of 0 to 1 to each selected obj
    :param attrType: either "short" or "float"
    :param args:
    :return:
    """
    sel = cmds.ls(sl=True)
    if not sel:
        cmds.warning("You need to select an object add attrs to!")
        return()
    attrName = cmds.textFieldGrp(widgets["newAttrTFG"], q=True, tx=True)
    if not attrName:
        cmds.warning("Please enter a name for the attribute in the field!")
        return()
    for obj in sel:
        try:
            cmds.addAttr(obj, ln=attrName, at=attrType, min=0, max=1, dv=0, k=True)
        except:
            cmds.warning("Couldn't add attr: {0} to object: {1}. Skipping.".format(attrName, obj))
pipeline.py 文件源码 项目:core 作者: getavalon 项目源码 文件源码 阅读 36 收藏 0 点赞 0 评论 0
def lock():
    """Lock scene

    Add an invisible node to your Maya scene with the name of the
    current file, indicating that this file is "locked" and cannot
    be modified any further.

    """

    if not cmds.objExists("lock"):
        with lib.maintained_selection():
            cmds.createNode("objectSet", name="lock")
            cmds.addAttr("lock", ln="basename", dataType="string")

            # Permanently hide from outliner
            cmds.setAttr("lock.verticesOnlySet", True)

    fname = cmds.file(query=True, sceneName=True)
    basename = os.path.basename(fname)
    cmds.setAttr("lock.basename", basename, type="string")
maya_functions.py 文件源码 项目:TACTIC-Handler 作者: listyque 项目源码 文件源码 阅读 36 收藏 0 点赞 0 评论 0
def set_info_to_scene(search_key, context):
    # add info about particular scene
    skey_link = 'skey://{0}&context={1}'.format(search_key, context)
    if not cmds.attributeQuery('tacticHandler_skey', node='defaultObjectSet', exists=True):
        cmds.addAttr('defaultObjectSet', longName='tacticHandler_skey', dataType='string')
    cmds.setAttr('defaultObjectSet.tacticHandler_skey', skey_link, type='string')
__init__.py 文件源码 项目:config 作者: mindbender-studio 项目源码 文件源码 阅读 24 收藏 0 点赞 0 评论 0
def _set_uuid(node):
    """Add mbID to `node`

    Unless one already exists.

    """

    attr = "{0}.mbID".format(node)

    if not cmds.objExists(attr):
        cmds.addAttr(node, longName="mbID", dataType="string")
        _, uid = str(uuid.uuid4()).rsplit("-", 1)
        cmds.setAttr(attr, uid, type="string")
orientjoints.py 文件源码 项目:cmt 作者: chadmv 项目源码 文件源码 阅读 27 收藏 0 点赞 0 评论 0
def create_orient_manipulator(joint, material):
    joint_scale = cmds.jointDisplayScale(query=True)
    joint_radius = cmds.getAttr('{0}.radius'.format(joint))
    radius = joint_scale * joint_radius
    children = cmds.listRelatives(joint, children=True, path=True)
    if children:
        p1 = cmds.xform(joint, q=True, ws=True, t=True)
        p1 = OpenMaya.MPoint(*p1)
        p2 = cmds.xform(children[0], q=True, ws=True, t=True)
        p2 = OpenMaya.MPoint(*p2)
        radius = p1.distanceTo(p2)
    arrow_cvs = [[-1, 0, 0], [-1, 2, 0], [-2, 2, 0], [0, 4, 0], [2, 2, 0], [1, 2, 0], [1, 0, 0], [-1, 0, 0]]
    arrow_cvs = [[x[0]*radius, x[1]*radius, x[2]*radius] for x in arrow_cvs]
    shape = cmds.curve(name='{0}_zForward'.format(joint), degree=1, point=arrow_cvs)
    # shape = cmds.sphere(n='{0}_zForward'.format(joint), p=(0, 0, 0), ax=(0, 0, -1), ssw=0, esw=180, r=radius, d=3, ut=0, tol=0.01, s=8, nsp=4, ch=0)[0]
    # cmds.setAttr('{0}.sz'.format(shape), 0)
    # cmds.select(shape)
    # cmds.hyperShade(assign=material)
    group = cmds.createNode('transform', name='{0}_grp'.format(shape))
    cmds.parent(shape, group)
    cmds.makeIdentity(shape, apply=True)
    cmds.addAttr(shape, longName=MESSAGE_ATTRIBUTE, attributeType='message')
    cmds.connectAttr('{0}.message'.format(joint), '{0}.{1}'.format(shape, MESSAGE_ATTRIBUTE))
    for attr in ['tx', 'ty', 'tz', 'ry', 'rz', 'v']:
        cmds.setAttr('{0}.{1}'.format(shape, attr), lock=True, keyable=False)
    return group, shape
control.py 文件源码 项目:cmt 作者: chadmv 项目源码 文件源码 阅读 32 收藏 0 点赞 0 评论 0
def create_transform_stack(node, count=2):
    """Creates a transform stack above the given node.

    Any previous transform stack will be deleted.

    :param node: Node to parent into a transform stack.
    :param count: Number of transforms to add in the stack.
    :return: A list of the transform nodes created starting from top to bottom.
    """
    previous_parent = cmds.listRelatives(node, parent=True, path=True)
    if previous_parent:
        previous_parent = previous_parent[0]
        while previous_parent and STACK_ATTRIBUTE in (cmds.listAttr(previous_parent, ud=True) or []):
            parent = cmds.listRelatives(previous_parent, parent=True, path=True)
            if parent:
                cmds.parent(node, parent)
                parent = parent[0]
            else:
                cmds.parent(node, world=True)
            cmds.delete(previous_parent)
            previous_parent = parent

    nulls = []
    for i in reversed(range(count)):
        name = '_'.join(node.split('_')[:-1])
        name = '{0}_{1}nul'.format(name, i+1)
        null = cmds.createNode('transform', name=name)
        nulls.append(null)
        cmds.addAttr(null, ln=STACK_ATTRIBUTE, at='message')
        cmds.connectAttr('{0}.message'.format(node), '{0}.{1}'.format(null, STACK_ATTRIBUTE))
        cmds.delete(cmds.parentConstraint(node, null))
        if previous_parent:
            cmds.parent(null, previous_parent)
        previous_parent = null
    cmds.parent(node, previous_parent)
    return nulls
BlendTransforms.py 文件源码 项目:BlendTransforms 作者: duncanskertchly 项目源码 文件源码 阅读 23 收藏 0 点赞 0 评论 0
def BT_Setup(set = None):

    if not set:
        return False

    transforms = cmds.listConnections(set +'.dagSetMembers')
    if not transforms:
        return False

    if not cmds.attributeQuery('Blend_Node', n = set, ex = True):
        cmds.addAttr(set, ln = 'Blend_Node', k = False, h = True, dt = 'string')
    else:
        return False

    btNode = cmds.createNode("BlendTransforms")
    cmds.setAttr(set +'.Blend_Node', btNode, type = "string")

    for i in range(0, len(transforms)):
        baseMatrix = cmds.xform(transforms[i], q = True, m = True)
        baseScale = cmds.getAttr(transforms[i] +'.scale')[0]
        baseRotOffset = [0.0, 0.0, 0.0]

        if cmds.objectType(transforms[i], isType = 'joint'):
            baseRotOffset = cmds.getAttr(transforms[i] +'.jointOrient')[0]

        btAttr = 'transforms[' +str(i) +'].baseMatrix'
        btScaleAttr = 'transforms[' +str(i) +'].baseScale'
        btRotOffsetAttr = 'transforms[' +str(i) +'].baseRotOffset'

        BT_MatrixValuesToNode(values = baseMatrix, node = btNode, attr = btAttr)
        BT_Double3ValuesToNode(values = baseScale, node = btNode, attr = btScaleAttr)
        BT_Double3ValuesToNode(values = baseRotOffset, node = btNode, attr = btRotOffsetAttr)
        BT_ConnectOutputs(index = i, node = btNode, transform = transforms[i])

    return True
BlendTransforms.py 文件源码 项目:BlendTransforms 作者: duncanskertchly 项目源码 文件源码 阅读 24 收藏 0 点赞 0 评论 0
def BT_Setup(set = None):

    if not set:
        return False

    transforms = cmds.listConnections(set +'.dagSetMembers')
    if not transforms:
        return False

    if not cmds.attributeQuery('Blend_Node', n = set, ex = True):
        cmds.addAttr(set, ln = 'Blend_Node', k = False, h = True, dt = 'string')
    else:
        return False

    btNode = cmds.createNode("BlendTransforms")
    cmds.setAttr(set +'.Blend_Node', btNode, type = "string")

    for i in range(0, len(transforms)):
        baseMatrix = cmds.xform(transforms[i], q = True, m = True)
        baseScale = cmds.getAttr(transforms[i] +'.scale')[0]
        baseRotOffset = [0.0, 0.0, 0.0]

        if cmds.objectType(transforms[i], isType = 'joint'):
            baseRotOffset = cmds.getAttr(transforms[i] +'.jointOrient')[0]

        btAttr = 'transforms[' +str(i) +'].baseMatrix'
        btScaleAttr = 'transforms[' +str(i) +'].baseScale'
        btRotOffsetAttr = 'transforms[' +str(i) +'].baseRotOffset'

        BT_MatrixValuesToNode(values = baseMatrix, node = btNode, attr = btAttr)
        BT_Double3ValuesToNode(values = baseScale, node = btNode, attr = btScaleAttr)
        BT_Double3ValuesToNode(values = baseRotOffset, node = btNode, attr = btRotOffsetAttr)
        BT_ConnectOutputs(index = i, node = btNode, transform = transforms[i])

    return True
BlendTransforms.py 文件源码 项目:BlendTransforms 作者: duncanskertchly 项目源码 文件源码 阅读 30 收藏 0 点赞 0 评论 0
def BT_Setup(set = None):

    if not set:
        return False

    transforms = cmds.listConnections(set +'.dagSetMembers')
    if not transforms:
        return False

    if not cmds.attributeQuery('Blend_Node', n = set, ex = True):
        cmds.addAttr(set, ln = 'Blend_Node', k = False, h = True, dt = 'string')
    else:
        return False

    btNode = cmds.createNode("BlendTransforms")
    cmds.setAttr(set +'.Blend_Node', btNode, type = "string")

    for i in range(0, len(transforms)):
        baseMatrix = cmds.xform(transforms[i], q = True, m = True)
        baseScale = cmds.getAttr(transforms[i] +'.scale')[0]
        baseRotOffset = [0.0, 0.0, 0.0]

        if cmds.objectType(transforms[i], isType = 'joint'):
            baseRotOffset = cmds.getAttr(transforms[i] +'.jointOrient')[0]

        btAttr = 'transforms[' +str(i) +'].baseMatrix'
        btScaleAttr = 'transforms[' +str(i) +'].baseScale'
        btRotOffsetAttr = 'transforms[' +str(i) +'].baseRotOffset'

        BT_MatrixValuesToNode(values = baseMatrix, node = btNode, attr = btAttr)
        BT_Double3ValuesToNode(values = baseScale, node = btNode, attr = btScaleAttr)
        BT_Double3ValuesToNode(values = baseRotOffset, node = btNode, attr = btRotOffsetAttr)
        BT_ConnectOutputs(index = i, node = btNode, transform = transforms[i])

    return True
BlendTransforms.py 文件源码 项目:BlendTransforms 作者: duncanskertchly 项目源码 文件源码 阅读 28 收藏 0 点赞 0 评论 0
def BT_Setup(set = None):

    if not set:
        return False

    transforms = cmds.listConnections(set +'.dagSetMembers')
    if not transforms:
        return False

    if not cmds.attributeQuery('Blend_Node', n = set, ex = True):
        cmds.addAttr(set, ln = 'Blend_Node', k = False, h = True, dt = 'string')
    else:
        return False

    btNode = cmds.createNode("BlendTransforms")
    cmds.setAttr(set +'.Blend_Node', btNode, type = "string")

    for i in range(0, len(transforms)):
        baseMatrix = cmds.xform(transforms[i], q = True, m = True)
        baseScale = cmds.getAttr(transforms[i] +'.scale')[0]
        baseRotOffset = [0.0, 0.0, 0.0]

        if cmds.objectType(transforms[i], isType = 'joint'):
            baseRotOffset = cmds.getAttr(transforms[i] +'.jointOrient')[0]

        btAttr = 'transforms[' +str(i) +'].baseMatrix'
        btScaleAttr = 'transforms[' +str(i) +'].baseScale'
        btRotOffsetAttr = 'transforms[' +str(i) +'].baseRotOffset'

        BT_MatrixValuesToNode(values = baseMatrix, node = btNode, attr = btAttr)
        BT_Double3ValuesToNode(values = baseScale, node = btNode, attr = btScaleAttr)
        BT_Double3ValuesToNode(values = baseRotOffset, node = btNode, attr = btRotOffsetAttr)
        BT_ConnectOutputs(index = i, node = btNode, transform = transforms[i])

    return True
SEToolsPlugin.py 文件源码 项目:SETools 作者: dtzxporter 项目源码 文件源码 阅读 25 收藏 0 点赞 0 评论 0
def DagPathFromJoint(name, needsRest=True):
    # Check for it
    if not cmds.objExists(name):
        # Not found in scene
        return False
    # Check to add
    if needsRest:
        # Check for the attr (to set rest pos)
        if not cmds.objExists(name + ".seanimUndoT"):
            # We need to setup the undo data
            ResetTranslation = cmds.getAttr(name + ".t")[0]
            ResetScale = cmds.getAttr(name + ".scale")[0]
            ResetRotation = cmds.getAttr(name + ".jo")[0]
            # Make the attributes
            cmds.addAttr(name, longName="seanimUndoT", dataType="double3", storable=True)
            cmds.addAttr(name, longName="seanimUndoS", dataType="double3", storable=True)
            cmds.addAttr(name, longName="seanimUndoR", dataType="double3", storable=True)
            # Set them
            cmds.setAttr(name + ".seanimUndoT", ResetTranslation[0], ResetTranslation[1], ResetTranslation[2], type="double3")
            cmds.setAttr(name + ".seanimUndoS", ResetScale[0], ResetScale[1], ResetScale[2], type="double3")
            cmds.setAttr(name + ".seanimUndoR", ResetRotation[0], ResetRotation[1], ResetRotation[2], type="double3")
    # Make selector
    sList = OpenMaya.MSelectionList()
    # Add it
    sList.add(name)
    # New Path
    dResult = OpenMaya.MDagPath()
    # Set it
    sList.getDagPath(0, dResult)
    # Return
    return dResult

# Disconnects a MDagPath from it's input keyframes
burnin.py 文件源码 项目:mayakit 作者: danbradham 项目源码 文件源码 阅读 22 收藏 0 点赞 0 评论 0
def toggle_burnin(value):
    '''Toggle default viewport burnin'''

    viewport_burnin = get_viewport_burnin()
    if viewport_burnin:
        cmds.setAttr(viewport_burnin + '.v', value)
        return

    if not value:
        return

    if not cmds.pluginInfo(burnin.type_name, q=True, loaded=True):
        cmds.loadPlugin(burnin.type_name)

    viewport_burnin = cmds.createNode('burnin')
    cmds.addAttr(viewport_burnin, ln='viewport_burnin', at='bool', dv=True)
    cmds.setAttr(viewport_burnin + '.fontSize', 16)
    cmds.setAttr(viewport_burnin + '.fontWeight', 75)
    cmds.setAttr(viewport_burnin + '.fontAlpha', 0.75)

    t0 = viewport_burnin + '.textArray[0]'
    cmds.setAttr(t0 + '.textString', '{frame:0>3d}\n{camera}', type='string')
    cmds.setAttr(t0 + '.textColor', 1, 1, 1)
    cmds.setAttr(t0 + '.textAlign', 7)

    t1 = viewport_burnin + '.textArray[1]'
    cmds.setAttr(t1 + '.textString', '{user}\n{scene}', type='string')
    cmds.setAttr(t1 + '.textColor', 1, 1, 1)
    cmds.setAttr(t1 + '.textAlign', 6)
pipeline.py 文件源码 项目:pyblish-starter 作者: pyblish 项目源码 文件源码 阅读 34 收藏 0 点赞 0 评论 0
def containerise(name, nodes, version):
    """Bundle `nodes` into an assembly and imprint it with metadata

    Containerisation enables a tracking of version, author and origin
    for loaded assets.

    Arguments:
        name (str): Name of resulting assembly
        nodes (list): Long names of nodes to containerise
        version (pyblish-starter:version-1.0): Current version

    """

    assemblies = cmds.ls(nodes, assemblies=True)
    container = cmds.group(assemblies, name=name)

    data = [
        ("id", "pyblish.starter.container"),
        ("author", version["author"]),
        ("loader", self.__name__),
        ("time", version["time"]),
        ("version", version["version"]),
        ("source", version["source"]),
        ("comment", version.get("comment", ""))
    ]

    for key, value in data:

        if not value:
            continue

        cmds.addAttr(container, longName=key, dataType="string")
        cmds.setAttr(container + "." + key, value, type="string")

    return container
lib.py 文件源码 项目:pyblish-starter 作者: pyblish 项目源码 文件源码 阅读 28 收藏 0 点赞 0 评论 0
def imprint(node, data):
    """Write `data` to `node` as userDefined attributes

    Arguments:
        node (str): Long name of node
        data (dict): Dictionary of key/value pairs

    """

    for key, value in data.items():
        if isinstance(value, bool):
            add_type = {"attributeType": "bool"}
            set_type = {"keyable": False, "channelBox": True}
        elif isinstance(value, basestring):
            add_type = {"dataType": "string"}
            set_type = {"type": "string"}
        elif isinstance(value, int):
            add_type = {"attributeType": "long"}
            set_type = {"keyable": False, "channelBox": True}
        elif isinstance(value, float):
            add_type = {"attributeType": "double"}
            set_type = {"keyable": False, "channelBox": True}
        else:
            raise TypeError("Unsupported type: %r" % type(value))

        cmds.addAttr(node, longName=key, **add_type)
        cmds.setAttr(node + "." + key, value, **set_type)
zbw_rig.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 27 收藏 0 点赞 0 评论 0
def createMessage(host="none", attr="none", target="none", *args):
    """creates a message attr on object with target as value. Args are: 'host'-some object to hold the message attr, 'attr'-the name of the message attribute to create, and 'target'-the host to be the value of the message attr"""
    cmds.addAttr(host, at='message', ln=attr)
    cmds.connectAttr("%s.message"%target, "%s.%s"%(host, attr))
    return("%s.%s"%(host, attr))
zbw_wireRig.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 26 收藏 0 点赞 0 评论 0
def createWireDef(*args):
  #clusterList = []
  #rebuiltCrv = ""
  #get geo and curve
  geo = cmds.ls(sl=True)[0]
  crv = cmds.ls(sl=True)[1]
  rebuiltCrv = rebuildCrv(crv)
  name = cmds.textFieldGrp(widgets["nameTFG"],q=True, tx=True)
  defName = "wire_"+ name
  wireDef = cmds.wire(geo, w = rebuiltCrv, n= defName, gw=True)
  wireGroup = wireDef[1] + "Group"
  cmds.setAttr(wireGroup + ".v", 0)

  clusterList = clstrOnCurve(rebuiltCrv)
  #print clusterList
  ctrlGrp = createControls(clusterList)

  masterGrp = cmds.group(n=name+"_GRP", em=True)
  cmds.parent(ctrlGrp, masterGrp)
  cmds.parent(wireGroup, masterGrp)

  cmds.addAttr(masterGrp, ln="xxWireDeformerCtrlsXX", at="bool", k=True)
  cmds.setAttr(masterGrp + ".xxWireDeformerCtrlsXX", l=True)
  cmds.addAttr(masterGrp, ln = 'envelope', at = "float", dv = 1, min=0, max=1, k=True)
  cmds.addAttr(masterGrp, ln = 'DropoffDistance', at = 'float', dv = 1, min = 0, max = 15, k = True)
  cmds.addAttr(masterGrp, ln = 'tension', at = 'float', dv = 1, min = -10, max = 10, k = True)
  cmds.addAttr(masterGrp, ln = 'rot', at = 'float', min = 0, max = 1, k =True)
  cmds.addAttr(masterGrp, ln = 'scl', at = 'float', dv = 1, min = 0, max = 3, k = True)

  cmds.connectAttr(masterGrp + ".envelope", wireDef[0] + ".envelope")
  cmds.connectAttr(masterGrp + ".DropoffDistance", wireDef[0] + ".dropoffDistance[0]")
  cmds.connectAttr(masterGrp + ".tension", wireDef[0] + ".tension")
  cmds.connectAttr(masterGrp + ".rot", wireDef[0] + ".rotation")
  cmds.connectAttr(masterGrp + ".scl", wireDef[0] + ".scale[0]")

  cmds.select(masterGrp, r = True)

  incrementName()
zbw_attributes.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 26 收藏 0 点赞 0 评论 0
def transfer_attrs(*args):
    """
    transfers attrs and connections from second obj to first object selected 
    """
    tgt, src = get_source_and_targets()
    if not tgt or len(src) > 1:
        cmds.warning("Select only one target then one source obj to transfer the attributes and connections!")
        return ()

    attrs = cmds.channelBox('mainChannelBox', q=True, selectedMainAttributes=True)
    if not attrs:
        cmds.warning("You have to select at least one attr on last object selected to transfer!")
        return ()
    for attr in attrs:
        attrType, hasMin, attrMin, hasMax, attrMax, value, inConnection, outConnection, locked = get_channel_attributes(
            src[0], attr)
        if not attrType == "enum":
            # create attribute
            if not cmds.attributeQuery(attr, node=tgt, exists=True):
                if hasMin and not hasMax:
                    cmds.addAttr(tgt, ln=attr, at=attrType, min=attrMin[0], dv=value, k=True)
                elif hasMax and not hasMin:
                    cmds.addAttr(tgt, ln=attr, at=attrType, max=attrMax[0], dv=value, k=True)
                elif hasMin and hasMax:
                    cmds.addAttr(tgt, ln=attr, at=attrType, min=attrMin[0], max=attrMax[0], dv=value, k=True)
                else:
                    cmds.addAttr(tgt, ln=attr, at=attrType, dv=value, k=True)
            else:
                cmds.warning("The attribute: {0} already exists. Skipping creation!".format(attr))
            # lock
            if locked:
                cmds.setAttr("{0}.{1}".format(tgt, attr), l=True)
        else:
            cmds.warning("I don't do enums at the moment!")

        # connect tgt attr to connection, forced
        if inConnection:
            cmds.connectAttr(inConnection[0], "{0}.{1}".format(tgt, attr))
        if outConnection:
            for conn in outConnection:
                cmds.connectAttr("{0}.{1}".format(tgt, attr), conn, force=True)
maya_tools.py 文件源码 项目:gozbruh 作者: LumaPictures 项目源码 文件源码 阅读 26 收藏 0 点赞 0 评论 0
def load(file_path, obj_name, parent_name):
    """Import a file exported from ZBrush.

    This is the command sent over the Maya command port from ZBrush.

    Parameters
    ----------
    file_path : str
        Path to the file that we are importing
    obj_name : str
        Name of the object being imported
    parent_name : str
        Name of the parent for the object being imported
    """
    file_name = utils.split_file_name(file_path)
    _cleanup(file_name)
    cmds.file(file_path, i=True,
              usingNamespaces=False,
              removeDuplicateNetworks=True)

    # Set smoothing options if necessary
    if cmds.optionVar(ex='gozbruh_smooth') and not cmds.optionVar(q='gozbruh_smooth'):
        cmds.displaySmoothness(obj_name, du=0, dv=0, pw=4, ps=1, po=1)

    if not cmds.attributeQuery("gozbruhParent", n=obj_name, ex=True):
        cmds.addAttr(obj_name, longName='gozbruhParent', dataType='string')
    cmds.setAttr(obj_name + '.gozbruhParent', parent_name, type='string')
ml_pivot.py 文件源码 项目:ml_tools 作者: morganloomis 项目源码 文件源码 阅读 27 收藏 0 点赞 0 评论 0
def editPivotHandle(self):

        qt_maya_window.installEventFilter(self.keypressFilter)        

        #create transform
        self.pivotHandle = mc.group(em=True, name='Adjust_Pivot')
        mc.setAttr(self.pivotHandle+'.rotate', lock=True)
        mc.setAttr(self.pivotHandle+'.rx', keyable=False)
        mc.setAttr(self.pivotHandle+'.ry', keyable=False)
        mc.setAttr(self.pivotHandle+'.rz', keyable=False)
        mc.setAttr(self.pivotHandle+'.scale', lock=True)
        mc.setAttr(self.pivotHandle+'.sx', keyable=False)
        mc.setAttr(self.pivotHandle+'.sy', keyable=False)
        mc.setAttr(self.pivotHandle+'.sz', keyable=False)
        mc.setAttr(self.pivotHandle+'.visibility', lock=True, keyable=False)
        mc.setAttr(self.pivotHandle+'.displayHandle', True)

        self.pivotHandle = mc.parent(self.pivotHandle, self.node)[0]

        mc.addAttr(self.pivotHandle, ln='ml_pivot_handle', at='bool', keyable=False)

        #set initial position
        mc.setAttr(self.pivotHandle+'.translate', *mc.getAttr(self.node+'.rotatePivot')[0])

        #lock it so you don't delete it or something.
        mc.lockNode(self.pivotHandle, lock=True)

        self.scriptJob = mc.scriptJob(event=['SelectionChanged', self.cleanup], runOnce=True)

        mc.setToolTo('Move')

        mc.inViewMessage( amg='After moving the pivot, press <hl>Return</hl> to bake or <hl>Esc</hl> to cancel.', pos='midCenterTop', fade=True, fadeStayTime=4000, dragKill=True)
BlendTransforms.py 文件源码 项目:BlendTransforms 作者: duncanskertchly 项目源码 文件源码 阅读 21 收藏 0 点赞 0 评论 0
def BT_AddPose(set = None, poseName = '', index = None):

    prefixedPoseName = 'BT_' +poseName

    if not set:
        return False

    if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
        return False

    if BT_IsSetupConnected(set = set):
        cmds.warning('Disconnect setup first!')
        return False

    blendNode = cmds.getAttr(set +'.Blend_Node')

    if not cmds.objExists(blendNode) or not cmds.objExists(set):
        return False

    if cmds.attributeQuery(prefixedPoseName, ex = True, n = set):
        return False

    transforms = cmds.listConnections(set +'.dagSetMembers')

    numTransforms = len(transforms)
    poseIndex = cmds.getAttr(blendNode +'.transforms[0].poses', size = True) 

    if index is not None:
        poseIndex = index

    if index is None:
        cmds.addAttr(set, ln = prefixedPoseName, nn = poseName,  k = True, min = 0, max = 1.0, at = 'double')

    # print ('Num poses = ' +str(numPoses))
    for i in range(0, numTransforms):
        #get the base matrix
        baseScale = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseScale')[0]
        baseMatrix = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseMatrix')

        #store the scale and set it 
        transformScale = cmds.getAttr(transforms[i] +'.scale')[0]

        #set the scale back to 1.0
        cmds.setAttr(transforms[i] +'.scale', 1.0, 1.0, 1.0, type = 'double3')
        transformMatrix = cmds.xform(transforms[i], q = True, m = True)

        poseMatrix = [x-y for x, y in zip(transformMatrix, baseMatrix)]
        poseScale = [x-y for x, y in zip(transformScale, baseScale)]

        #set the scale back to what the user had it at
        cmds.setAttr(transforms[i] +'.scale', transformScale[0], transformScale[1], transformScale[2], type = 'double3')
        cmds.setAttr(blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].matrix', poseMatrix, type = 'matrix')
        BT_Double3ValuesToNode(values = poseScale, node = blendNode, attr = 'transforms[' +str(i) +'].poses[' +str(poseIndex) +'].scale' )

        if index is None:
            cmds.connectAttr(set +'.' +prefixedPoseName, blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].weight')

    return True
BlendTransforms.py 文件源码 项目:BlendTransforms 作者: duncanskertchly 项目源码 文件源码 阅读 25 收藏 0 点赞 0 评论 0
def BT_AddPose(set = None, poseName = '', index = None):

    prefixedPoseName = 'BT_' +poseName

    if not set:
        return False

    if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
        return False

    if BT_IsSetupConnected(set = set):
        cmds.warning('Disconnect setup first!')
        return False

    blendNode = cmds.getAttr(set +'.Blend_Node')

    if not cmds.objExists(blendNode) or not cmds.objExists(set):
        return False

    if cmds.attributeQuery(prefixedPoseName, ex = True, n = set):
        return False

    transforms = cmds.listConnections(set +'.dagSetMembers')

    numTransforms = len(transforms)
    poseIndex = cmds.getAttr(blendNode +'.transforms[0].poses', size = True) 

    if index is not None:
        poseIndex = index

    if index is None:
        cmds.addAttr(set, ln = prefixedPoseName, nn = poseName,  k = True, min = 0, max = 1.0, at = 'double')

    # print ('Num poses = ' +str(numPoses))
    for i in range(0, numTransforms):
        #get the base matrix
        baseScale = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseScale')[0]
        baseMatrix = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseMatrix')

        #store the scale and set it 
        transformScale = cmds.getAttr(transforms[i] +'.scale')[0]

        #set the scale back to 1.0
        cmds.setAttr(transforms[i] +'.scale', 1.0, 1.0, 1.0, type = 'double3')
        transformMatrix = cmds.xform(transforms[i], q = True, m = True)

        poseMatrix = [x-y for x, y in zip(transformMatrix, baseMatrix)]
        poseScale = [x-y for x, y in zip(transformScale, baseScale)]

        #set the scale back to what the user had it at
        cmds.setAttr(transforms[i] +'.scale', transformScale[0], transformScale[1], transformScale[2], type = 'double3')
        cmds.setAttr(blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].matrix', poseMatrix, type = 'matrix')
        BT_Double3ValuesToNode(values = poseScale, node = blendNode, attr = 'transforms[' +str(i) +'].poses[' +str(poseIndex) +'].scale' )

        if index is None:
            cmds.connectAttr(set +'.' +prefixedPoseName, blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].weight')

    return True
BlendTransforms.py 文件源码 项目:BlendTransforms 作者: duncanskertchly 项目源码 文件源码 阅读 24 收藏 0 点赞 0 评论 0
def BT_AddPose(set = None, poseName = '', index = None):

    prefixedPoseName = 'BT_' +poseName

    if not set:
        return False

    if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
        return False

    if BT_IsSetupConnected(set = set):
        cmds.warning('Disconnect setup first!')
        return False

    blendNode = cmds.getAttr(set +'.Blend_Node')

    if not cmds.objExists(blendNode) or not cmds.objExists(set):
        return False

    if cmds.attributeQuery(prefixedPoseName, ex = True, n = set):
        return False

    transforms = cmds.listConnections(set +'.dagSetMembers')

    numTransforms = len(transforms)
    poseIndex = cmds.getAttr(blendNode +'.transforms[0].poses', size = True) 

    if index is not None:
        poseIndex = index

    if index is None:
        cmds.addAttr(set, ln = prefixedPoseName, nn = poseName,  k = True, min = 0, max = 1.0, at = 'double')

    # print ('Num poses = ' +str(numPoses))
    for i in range(0, numTransforms):
        #get the base matrix
        baseScale = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseScale')[0]
        baseMatrix = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseMatrix')

        #store the scale and set it 
        transformScale = cmds.getAttr(transforms[i] +'.scale')[0]

        #set the scale back to 1.0
        cmds.setAttr(transforms[i] +'.scale', 1.0, 1.0, 1.0, type = 'double3')
        transformMatrix = cmds.xform(transforms[i], q = True, m = True)

        poseMatrix = [x-y for x, y in zip(transformMatrix, baseMatrix)]
        poseScale = [x-y for x, y in zip(transformScale, baseScale)]

        #set the scale back to what the user had it at
        cmds.setAttr(transforms[i] +'.scale', transformScale[0], transformScale[1], transformScale[2], type = 'double3')
        cmds.setAttr(blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].matrix', poseMatrix, type = 'matrix')
        BT_Double3ValuesToNode(values = poseScale, node = blendNode, attr = 'transforms[' +str(i) +'].poses[' +str(poseIndex) +'].scale' )

        if index is None:
            cmds.connectAttr(set +'.' +prefixedPoseName, blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].weight')

    return True
zbw_curveJntRig.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 24 收藏 0 点赞 0 评论 0
def smartClose(*args):
    name = cmds.textFieldGrp(widgets["nameTFG"], q=True, tx=True)
    upSuf = cmds.textFieldGrp(widgets["upNameTFG"], q=True, tx=True)
    dwnSuf = cmds.textFieldGrp(widgets["downNameTFG"], q=True, tx=True)
    topMidCtrl = ctrlsUp[len(ctrlsUp)/2]
    downMidCtrl = ctrlsUp[len(ctrlsDown)/2]

    if len(lowResCurves)==2 and len(highResCurves)==2:
        tmpCloseLow = cmds.duplicate(lowResCurves[0], n="{0}_closeLowTmpCrv".format(name))[0]
        cmds.parent(tmpCloseLow, w=True)

        tmpLowBS = cmds.blendShape(lowResCurves[0], lowResCurves[1], tmpCloseLow)[0]
        tmpLowUpAttr = "{0}.{1}".format(tmpLowBS, lowResCurves[0])
        tmpLowDwnAttr = "{0}.{1}".format(tmpLowBS, lowResCurves[1])
        cmds.setAttr(tmpLowUpAttr, 0.5)
        cmds.setAttr(tmpLowDwnAttr, 0.5)
        closeLow = cmds.duplicate(tmpCloseLow, n="{0}_CLOSE_LOW_CRV".format(name))[0]
        cmds.delete([tmpCloseLow, tmpLowBS])
        lowBS = cmds.blendShape(lowResCurves[0], lowResCurves[1], closeLow)[0]
        lowUpAttr = "{0}.{1}".format(lowBS, lowResCurves[0])
        lowDwnAttr = "{0}.{1}".format(lowBS, lowResCurves[1])

#---------------- connect up down into reverse setup that drives lowclosecrv to go up/down
        cmds.addAttr(topMidCtrl, ln="__xtraAttrs__", )

        cmds.setAttr(lowUpAttr, 1)
        cmds.setAttr(lowDwnAttr, 0)
        closeUpHigh = cmds.duplicate(highResCurves[0], n="{0}_HI_{1}_CLOSE_CRV".format(name, upSuf.upper() ))[0]
        cmds.parent(closeUpHigh, w=True)
        upHighWire = cmds.wire(closeUpHigh, en=1, gw=True, ce=0, li=0, w=closeLow, name = "{0}_CLS_UP_WIRE".format(name))[0]
        wireUpBaseCrv = "{0}BaseWire".format(closeLow)
        cmds.setAttr("{0}.scale[0]".format(upHighWire), 0)
#---------------- set up blend shape on high res curve (drive high res with wire driven curve)
#---------------- set up the center ctrl to drive this BS

        cmds.setAttr(lowUpAttr, 0)
        cmds.setAttr(lowDwnAttr, 1)
        closeDwnHigh = cmds.duplicate(highResCurves[1], n="{0}_HI_{1}_CLOSE_CRV".format(name, dwnSuf.upper() ))[0]
        cmds.parent(closeDwnHigh, w=True)
        dwnHighWire = cmds.wire(closeDwnHigh, en=1, gw=True, ce=0, li=0, w=closeLow, name = "{0}_CLS_DWN_WIRE".format(name))[0]
        wireDwnBase = "{0}BaseWire".format(closeLow)
        cmds.setAttr("{0}.scale[0]".format(dwnHighWire), 0)
#---------------- set up blend shape on high res curve (drive high res with wire driven curve)
#---------------- set up the center ctrl to drive this BS
zbw_curveCVControls.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 27 收藏 0 点赞 0 评论 0
def curve_CV_controls_execute(crv, *args):
    """
    takes given curve and makes a ctrl for each cv. Then connects the matrix of the control directly to the point
    position of the cv. Basically hijacking the shape node, more or less. If there's a parent to the curve,
    will put whole rig under that and turn off inherit transforms for the crv itself.
    puts an attr called 'controlScale' on the group controls are under to scale size of controls
    Args:
        crv: string - name of given curve
        *args:

    Returns:
        Void
    """

    par = cmds.listRelatives(crv, p=True)

    ctrlGrps = []
    cvs = cmds.ls("{0}.cv[*]".format(crv), fl=True)
    xformGrp = cmds.group(empty=True, name="{0}_ctrl_GRP".format(crv))
    cmds.addAttr(xformGrp, ln="controlScale", at="float", min=0.01, max=100, dv=1.0, k=True)
    for x in range(0, len(cvs)):
        pos = cmds.pointPosition(cvs[x])
        shp = cmds.listRelatives(crv, s=True)[0]
        ctrl = rig.createControl(type="sphere", name="{0}_{1}_CTRL".format(crv, x), color="red")
        grp = rig.groupFreeze(ctrl)
        cmds.connectAttr("{0}.controlScale".format(xformGrp), "{0}.sx".format(ctrl))
        cmds.connectAttr("{0}.controlScale".format(xformGrp), "{0}.sy".format(ctrl))
        cmds.connectAttr("{0}.controlScale".format(xformGrp), "{0}.sz".format(ctrl))
        cmds.setAttr("{0}.scale".format(ctrl), l=True, k=False)
        cmds.xform(grp, ws=True, t=pos)

        dm = cmds.shadingNode("decomposeMatrix", asUtility=True,name="{0}_{1}_DM".format(crv, x))
        cmds.connectAttr("{0}.worldMatrix[0]".format(ctrl), "{0}.inputMatrix".format(dm))
        cmds.connectAttr("{0}.outputTranslate".format(dm), "{0}.controlPoints[{1}]".format(shp, x))
        ctrlGrps.append(grp)

    cmds.xform(xformGrp, ws=True, t=(cmds.xform(crv, ws=True, q=True, rp=True)))
    cmds.xform(xformGrp, ws=True, ro=(cmds.xform(crv, ws=True, q=True, ro=True)))
    cmds.xform(xformGrp, s=(cmds.xform(crv, q=True, r=True, s=True)))

    if par:
        inhGrp = cmds.group(empty=True, name="noInherit_{0}_GRP".format(crv))
        cmds.parent(xformGrp, par[0])
        cmds.parent(inhGrp, par[0])
        cmds.parent(crv, inhGrp)
        cmds.setAttr("{0}.inheritsTransform".format(inhGrp), 0)

    cmds.parent(ctrlGrps, xformGrp)
    cmds.xform(crv, ws=True, t=(0,0,0))
    cmds.xform(crv, ws=True, ro=(0,0,0))
    cmds.xform(crv, a=True, s=(1,1,1))
zbw_messageMapper.py 文件源码 项目:zTools 作者: zethwillie 项目源码 文件源码 阅读 26 收藏 0 点赞 0 评论 0
def zbw_mmConnectM(*args):
    """
    uses the items from the textFields to create message attrs in the base obj, and connects to those the objs from the rightmost fields of the UI
    """
    #check there's a base obj
    if (cmds.textFieldButtonGrp("zbw_tfbg_baseObj", q=True, tx=True)):
        #check there are any fields created
        if (cmds.rowColumnLayout("mmRCLayout", q=True, ca=True)):

            children = cmds.rowColumnLayout("mmRCLayout", q=True, ca=True)
            numObj = (len(children)/2)

            if numObj:
                for num in range(1, numObj+1):
                    attrTFG =  "attr" + str(num)
                    objTFBG = "obj" + str(num)
                    baseObj = cmds.textFieldButtonGrp("zbw_tfbg_baseObj", q=True, tx=True)
                    targetObj = cmds.textFieldButtonGrp(objTFBG, q=True, tx=True)
                    baseAttr = cmds.textFieldGrp(attrTFG, q=True, tx=True)
                    baseMAttr = baseObj + "." + baseAttr
                    objMAttr = targetObj + ".message"
                    #check to make sure there's something in each field, otherwise skip
                    if baseAttr and targetObj:
                        #check that attr doesnt' already exist with connection
                        if (cmds.attributeQuery(baseAttr, n=baseObj, ex=True)):
                            #delete the attr that exists, print note about it
                            cmds.deleteAttr(baseMAttr)
                            cmds.warning(baseMAttr + " already exists! Deleting for overwrite and reconnection")
                        cmds.addAttr(baseObj, at="message", ln=baseAttr)
                        cmds.connectAttr(objMAttr, baseMAttr, f=True)
                        #print confirmation of connection
                        print("Connected: "+ objMAttr +"--->"+ baseMAttr)

                    else:
                        cmds.warning("Line # " + str(num) + " was empty! Skipped that attr")
                #leave a text field saying that it's done
                zbw_mmDeleteConfirm()
                cmds.separator("mmConfirmSep", h=20, st="single", p="mmAddNewConnections")
                cmds.text("mmTextConfirm", l="MESSAGES MAPPED!", p="mmAddNewConnections")
        else:
            cmds.warning("Please create some attrs and objs to connect to base obj!")
    else:
        cmds.warning("Please choose a base object to add attrs to!")
pipeline.py 文件源码 项目:core 作者: getavalon 项目源码 文件源码 阅读 36 收藏 0 点赞 0 评论 0
def containerise(name,
                 namespace,
                 nodes,
                 context,
                 loader=None,
                 suffix="CON"):
    """Bundle `nodes` into an assembly and imprint it with metadata

    Containerisation enables a tracking of version, author and origin
    for loaded assets.

    Arguments:
        name (str): Name of resulting assembly
        namespace (str): Namespace under which to host container
        nodes (list): Long names of nodes to containerise
        context (dict): Asset information
        loader (str, optional): Name of loader used to produce this container.
        suffix (str, optional): Suffix of container, defaults to `_CON`.

    Returns:
        container (str): Name of container assembly

    """
    container = cmds.sets(nodes, name="%s_%s_%s" % (namespace, name, suffix))

    data = [
        ("schema", "avalon-core:container-2.0"),
        ("id", "pyblish.avalon.container"),
        ("name", name),
        ("namespace", namespace),
        ("loader", str(loader)),
        ("representation", context["representation"]["_id"]),
    ]

    for key, value in data:
        if not value:
            continue

        if isinstance(value, (int, float)):
            cmds.addAttr(container, longName=key, attributeType="short")
            cmds.setAttr(container + "." + key, value)

        else:
            cmds.addAttr(container, longName=key, dataType="string")
            cmds.setAttr(container + "." + key, value, type="string")

    main_container = cmds.ls(AVALON_CONTAINERS, type="objectSet")
    if not main_container:
        main_container = cmds.sets(empty=True, name=AVALON_CONTAINERS)
    else:
        main_container = main_container[0]

    cmds.sets(container, addElement=main_container)

    return container
lib.py 文件源码 项目:core 作者: getavalon 项目源码 文件源码 阅读 27 收藏 0 点赞 0 评论 0
def imprint(node, data):
    """Write `data` to `node` as userDefined attributes

    Arguments:
        node (str): Long name of node
        data (dict): Dictionary of key/value pairs

    Example:
        >>> from maya import cmds
        >>> def compute():
        ...   return 6
        ...
        >>> cube, generator = cmds.polyCube()
        >>> imprint(cube, {
        ...   "regularString": "myFamily",
        ...   "computedValue": lambda: compute()
        ... })
        ...
        >>> cmds.getAttr(cube + ".computedValue")
        6

    """

    for key, value in data.items():

        if callable(value):
            # Support values evaluated at imprint
            value = value()

        if isinstance(value, bool):
            add_type = {"attributeType": "bool"}
            set_type = {"keyable": False, "channelBox": True}
        elif isinstance(value, basestring):
            add_type = {"dataType": "string"}
            set_type = {"type": "string"}
        elif isinstance(value, int):
            add_type = {"attributeType": "long"}
            set_type = {"keyable": False, "channelBox": True}
        elif isinstance(value, float):
            add_type = {"attributeType": "double"}
            set_type = {"keyable": False, "channelBox": True}
        else:
            raise TypeError("Unsupported type: %r" % type(value))

        cmds.addAttr(node, longName=key, **add_type)
        cmds.setAttr(node + "." + key, value, **set_type)


问题


面经


文章

微信
公众号

扫码关注公众号