def _set_channel_edit_target(chn, edit=True):
    """Set the blendshape target of a channel editable or not editable

    Args:
        chn (PyNode): Attribute channel to edit
        edit (bool, optional): Set ON or OFF the channel edit status
    """
    attrs = chn.listConnections(d=True, s=False, p=True)
    for a in attrs:
        if edit:
            pm.sculptTarget(a.node(), e=True, t=a.index())
            pm.inViewMessage(amg="{}: Edit mode is ON".format(chn.name()),
                             pos='midCenterBot',
                             fade=True)
        else:
            a.node().inputTarget[a.index()].sculptTargetIndex.set(-1)
            pm.mel.eval("updateBlendShapeEditHUD;")
            pm.inViewMessage(amg="{}: Edit mode is OFF".format(chn.name()),
                             pos='midCenterBot',
                             fade=True)
Example #2
0
    def rebuild_BS(self, main_index, bsNode='', inBetArray=[]):

        BS_targets = {}
        inBetweens = []
        to_parent = []

        target = pm.sculptTarget(bsNode,
                                 target=main_index,
                                 edit=True,
                                 regenerate=True)

        if target is not None:
            py_targ = pm.PyNode(target[0])
            pm.addAttr(py_targ, ln='value', at='float', defaultValue=1.000)
            to_parent.append(py_targ)

            if len(inBetArray) > 0:
                for value in inBetArray:
                    inBet = pm.sculptTarget(bsNode,
                                            target=main_index,
                                            edit=True,
                                            regenerate=True,
                                            ibw=value)
                    py_inBet = pm.PyNode(inBet[0])
                    newInBet = pm.rename(
                        py_inBet,
                        str(py_targ.name() +
                            '_InBet_%s' % ''.join(str(value).split('.'))))
                    inBetweens.append([newInBet, value])
                    to_parent.append(py_inBet)
                    self.tag_for_inbetween(py_targ, py_inBet, value)
                    # print(py_inBet)

            #
            BS_targets[py_targ] = inBetweens

            # parent to main group
            pm.parent(to_parent, self.mainGroup)

        return
Example #3
0
def getRebuildTargetFromShapeEditor():
    '''
    쉐입 에디터에서 선택된 타겟 목록 얻어옴.
    
    Result: [u'blendShape1.2', u'blendShape1.3']
    [블렌드쉐입노드.타겟ID] 형식으로 리턴됨.
    split(".")으로 블렌드쉐입 노드와, 타겟 ID를 얻어옴.
    
    getShapeEditorTreeviewSelection() 명령어는 
    C:\Program Files\Autodesk\Maya2017\scripts\others\createShapePanelMenu.mel 파일에 있는 스크립트 임.
    '''

    # 쉐입 에디터에서 선택한 타겟 목록 리턴
    selectedTargetL = pm.mel.getShapeEditorTreeviewSelection(
        24)  # @UndefinedVariable
    # selectedTargetL = [u'blendShape2.0', u'blendShape2.1']      # 이런 형식으로 들어옴.

    resultMesh = []
    for item in selectedTargetL:
        # .으로 분리
        blendShapeNode, targetID = item.split(
            '.')  # blendShape1.1 => blendShape1 1

        # int형으로 변환
        targetID = int(targetID)

        # pynode로 변환
        blendShapeNode = pm.PyNode(blendShapeNode)

        # 타겟명을 알아야 함.
        attrs = blendShapeNode.listAliases()
        targetName = attrs[targetID][0]

        # sculptTarget명령어는 타겟이름과 같은 이름의 오브젝트가 존재하면 작동 안함.
        # 타겟이름과 같은 오브젝트가 씬에 있는지 체크
        if pm.objExists(targetName):
            print u' "%s" 타겟과 같은이름의 오브젝트가 이미 존재합니다.' % targetName
            continue

        # 타겟 분리
        mesh = pm.sculptTarget(blendShapeNode,
                               e=True,
                               regenerate=True,
                               target=targetID)

        # 분리된 메쉬
        resultMesh.append(mesh)

    return resultMesh
def rebuild_targets(obj):
    """Simple rebuild targets using pymel builtin function"""
    if len(obj) == 0:
        pymel.warning('Nothing in selection')
        return None
    blend_shape_node = obj[0].listHistory(type='blendShape')
    if len(blend_shape_node) == 0:
        pymel.warning('Could not find Blendshape node on selected mesh')
        return None
    blend_aliases = blend_shape_node[0].listAliases()

    for alias in blend_aliases:
        target_name = alias[0]
        target = pymel.sculptTarget(blend_shape_node,
                                    e=True,
                                    r=True,
                                    t=alias[1].index())
        pymel.rename(target, target_name)
Example #5
0
def add_frame_sculpt(layer_node, anim=False, keyf=[1, 0, 0, 1]):
    """Add a sculpt frame to each selected layer

    Args:
        layer_node (dagNode list):  ist of Crank layer node to add the
            sculpt frame
        anim (bool, optional): if True, will keyframe the sculpt frame in the
        specified range.
        keyf (list, optional):  Keyframe range configuration. EaseIn, pre hold,
        post hold and ease out
    """
    objs = layer_node.layer_objects.inputs()
    bs_node = layer_node.layer_blendshape_node.inputs()

    # ensure other targets are set to false the edit flag

    # get current frame
    cframe = int(pm.currentTime(query=True))

    # get valid name. Check if frame is ducplicated in layer
    frame_name = "frame_{}".format(str(cframe))
    i = 1
    while layer_node.hasAttr(frame_name):
        frame_name = "frame_{}_v{}".format(str(cframe), str(i))
        i += 1

    # create frame master channel
    master_chn = attribute.addAttribute(layer_node,
                                        frame_name,
                                        "float",
                                        value=1,
                                        minValue=0,
                                        maxValue=1)

    # keyframe in range the master channel
    if anim:
        # current frame
        pm.setKeyframe(master_chn,
                       t=[cframe],
                       v=1,
                       inTangentType="linear",
                       outTangentType="linear")

        # pre and post hold
        pre_hold = keyf[1]
        if pre_hold:
            pm.setKeyframe(master_chn,
                           t=[cframe - pre_hold],
                           v=1,
                           inTangentType="linear",
                           outTangentType="linear")

        post_hold = keyf[2]
        if post_hold:
            pm.setKeyframe(master_chn,
                           t=[cframe + post_hold],
                           v=1,
                           inTangentType="linear",
                           outTangentType="linear")

        # ease in and out
        if keyf[0]:
            ei = pre_hold + keyf[0]
            pm.setKeyframe(master_chn,
                           t=[cframe - ei],
                           v=0,
                           inTangentType="linear",
                           outTangentType="linear")
        if keyf[3]:
            eo = post_hold + keyf[3]
            pm.setKeyframe(master_chn,
                           t=[cframe + eo],
                           v=0,
                           inTangentType="linear",
                           outTangentType="linear")

    for obj, bsn in zip(objs, bs_node):
        dup = pm.duplicate(obj)[0]
        bst_name = "_".join([obj.name(), frame_name])
        pm.rename(dup, bst_name)
        indx = bsn.weight.getNumElements()
        pm.blendShape(bsn,
                      edit=True,
                      t=(obj, indx, dup, 1.0),
                      ts=True,
                      tc=True,
                      w=(indx, 1))
        pm.delete(dup)
        pm.blendShape(bsn, e=True, rtd=(0, indx))
        # is same as: bs.inputTarget[0].sculptTargetIndex.set(3)
        pm.sculptTarget(bsn, e=True, t=indx)

        # connect target to master channel
        pm.connectAttr(master_chn, bsn.attr(bst_name))
def rebuild_targets_match(obj):
    """
    Regenerate Blendshape targets with deformers masks applied. If you have masked out a portion of a blendshape
    that mask will now be baked into the generated target.
    :param obj: Node that has blendshapes applied.
    :return: Regenerated targets.
    """

    # Disable skin an tweak nodes.
    if not obj:
        print "Need to select object with blendshape"
        return
    try:
        skin_node = obj.listHistory(type='skinCluster')[0]
    except:
        skin_node = None
        pass

    try:
        tweak_node = obj.listHistory(type='tweak')[0]
    except:
        tweak_node = None
        pass

    if skin_node:
        skin_node.envelope.set(0)

    if tweak_node:
        tweak_node.envelope.set(0)

    # Get blendshape
    blend_shape_node = obj.listHistory(type='blendShape')[0]
    blend_aliases = blend_shape_node.listAliases()
    connection_dict = {}

    # Store connections, going to break them and reconnect later.
    for alias in blend_aliases:

        attribute = '{}.{}'.format(blend_shape_node, alias[0])
        connection = pymel.listConnections(attribute,
                                           destination=True,
                                           plugs=True)

        if connection:
            connection_dict[attribute] = connection[0]
            pymel.disconnectAttr(connection[0], attribute)
        pymel.setAttr(attribute, 0)

    for alias in blend_aliases:
        target_name = alias[0]
        target = pymel.sculptTarget(blend_shape_node,
                                    e=True,
                                    r=True,
                                    t=alias[1].index())
        pymel.rename(target, target_name)

        # Set blendshape value to 1
        attribute = '{}.{}'.format(blend_shape_node, alias[0])
        pymel.setAttr(attribute, 1)

        # todo: forget why this is re finding the pynode and not just using target.
        pynode_target = pymel.PyNode(target_name)

        print target
        print pynode_target

        # Baking vertex position from masking
        pos = match_vertex_position.get_vtx_pos(obj)
        match_vertex_position.set_vtx_pos(pynode_target, pos)

        # Set blendshape value to 0
        pymel.setAttr(attribute, 0)
        if attribute in connection_dict.keys():
            pymel.connectAttr(connection_dict[attribute], attribute)

    # Re-enable skin and tweak nodes
    if skin_node:
        skin_node.envelope.set(1)

    if tweak_node:
        tweak_node.envelope.set(1)
 def rebuild_target(self, target_index):
     return pm.sculptTarget(self.bs_node, e=1, r=1, t=target_index) or []