Example #1
0
def print_stats():
    print '.' * 70
    # Checks naming
    print '\nPlese, rename:'
    bad = get_bad_naming(meshes + grps)
    if bad:
        for item, bad_data in bad.iteritems():
            print '{:.<40} {}'.format(item, ', '.join([b for b in bad_data]))
    # Checks skin on meshes
    # Checks saved skin
    print '\nCheck skin cluster on meshes:'

    for mesh in meshes:
        if f.get_skin_cluster(mesh):
            continue
        elif os.path.exists(skin_data_path + mesh + txt_ext):
            print '{:.<40} {}'.format(mesh, 'no skin cluster, but saved skin')
        else:
            print '{:.<40} {}'.format(mesh, 'no skin cluster')

    # Checks scale in non keyed
    print '\nFix scale on objects greater than 1:'
    over_scaled = check_over_scale(meshes + jnts + grps)
    if over_scaled:
        for item, attrs in over_scaled.iteritems():
            print '{:.<40} {}'.format(item, ', '.join(str(at) for at in attrs))

    print '\n', '.' * 70, '\n'
Example #2
0
def create_div_mesh(source='', target=''):
    if not cmds.objExists(target):
        cmds.duplicate(source, name=target)
    if not f.get_skin_cluster(target):
        cmds.select(target)
        sie.create_bones = True
        sie.import_weights_sp()
Example #3
0
def get_bad_joints_distance_based(mesh, fit_len=11, infl_limit=0.2):
    # Gets vertices under every joint in skin cluster
    sc = f.get_skin_cluster(mesh)
    jnts = cmds.skinCluster(sc, query=True, inf=True)
    jnts_vtxs_infl = f.get_sc_multi(mesh)
    jnt_vtx_data = {}
    zero_infl_jnts = get_zero_weight_jnts(mesh)
    infl_jnts = [jnt for jnt in jnts if jnt not in zero_infl_jnts]

    for jnt in infl_jnts:
        vtxs_infl = jnts_vtxs_infl[jnt]
        cmds.select(clear=True)
        cmds.skinCluster(sc, e=True, selectInfluenceVerts=jnt)
        jnt_vtxs = cmds.ls(sl=True, fl=True)
        # Filters anything else except vtxs
        jnt_vtxs = [i for i in jnt_vtxs if cmds.objectType(i) == 'mesh']
        # Gets out vertex digit id only
        jnt_vtxs = [
            ''.join(c for c in vtx_id.split('.')[-1] if c.isdigit())
            for vtx_id in jnt_vtxs
        ]
        jnt_vtxs = [int(vtx_id) for vtx_id in jnt_vtxs]
        # Removes low infl vertex from the list
        jnt_vtxs = [
            vtx_id for vtx_id in jnt_vtxs
            if vtxs_infl[str(vtx_id)] > infl_limit
        ]
        if jnt_vtxs:
            jnt_vtx_data[jnt] = jnt_vtxs
        else:
            zero_infl_jnts.append(jnt)

    # pprint.pprint(jnt_vtx_data)
    jnt_vtxs_length = {}

    for jnt, vtxs in jnt_vtx_data.iteritems():
        vtxs_pos = [f.get_pos('%s.vtx[%s]' % (mesh, vtx)) for vtx in vtxs]
        jnt_pos = f.get_pos(jnt)
        jnt_vtx_len = [f.get_length(jnt_pos, vtx_pos) for vtx_pos in vtxs_pos]
        # print jnt, jnt_vtx_len
        av_len = average(jnt_vtx_len)
        jnt_vtxs_length[jnt] = av_len

    # pprint.pprint(jnt_vtxs_length)
    '''
    for jnt, av in jnt_vtxs_length.iteritems():
        if av >= fit_len:
            print jnt, av
    '''
    cmds.select(clear=True)
    return [jnt for jnt, av in jnt_vtxs_length.iteritems() if av >= fit_len
            ] + zero_infl_jnts
    '''
Example #4
0
def get_zero_weight_jnts(mesh):
    sc = f.get_skin_cluster(mesh)
    jnts = cmds.skinCluster(sc, query=True, inf=True)
    bad_sc_jnts = []

    for jnt in jnts:
        infl = cmds.skinPercent(sc,
                                '%s.vtx[*]' % mesh,
                                transform=jnt,
                                query=True)
        if infl < 0.001:
            bad_sc_jnts.append(jnt)

    return bad_sc_jnts
Example #5
0
def setup_head(head_mesh, teeth_mesh, gender='male', skeleton='new'):
    '''Gets or set bone mapping for a character, bone per vertex correspondance.
        Since bones are constrained to vertices.
        And vertices are driven with a blendshapes.

    Args:
        folder (str): path to bone mapping files that contain dictionary,
            dumped with a pickle 
        set_mapping (bool, optional): used with cubes and mapping params.
            Defaults to False
            Sets custom mapping for a character
        cubes (list, optional): used with set and mapping params.
            Cubes that visualize joint placement
        mapping (dict, optional): used with set and cubes params.
            Bone per vertex correspondance

    Returns:
        dict: default or custom bone per vertex correspondance for a '*_head' mesh

    Examples:
        >>> print([i for i in example_generator(4)])
        [0, 1, 2, 3]

    '''
    bls_suffix = '_bls'
    combined_bls_grp = head_mesh + bls_suffix
    complex_template = '%s_head_complex' % gender
    simple_template = '%s_head_simple' % gender
    tmp_bones = 'tmp_bones'
    facefx_combined_meshes = [
        u'anger', u'disgust', u'fear', u'happiness', u'jaw_open',
        u'low_lip_down', u'phoneme_CH', u'phoneme_CH_delta', u'phoneme_F',
        u'phoneme_F_delta', u'phoneme_P', u'phoneme_P_delta', u'phoneme_U',
        u'phoneme_U_delta', u'phoneme_W', u'phoneme_W_delta', u'phoneme_Y',
        u'phoneme_Y_delta', u'smile', u'sadness', u'surprise', u'up_lip_up',
        u'wide_pose'
    ]
    teeth_bls = [
        'Teeth_Backwards', 'Teeth_Forwards', 'Teeth_Left', 'Teeth_Open',
        'Teeth_Right', 'Tongue_Down', 'Tongue_In', 'Tongue_Narrow',
        'Tongue_Out', 'Tongue_Pressed_Upwards', 'Tongue_Rolled_Down',
        'Tongue_Rolled_Up', 'Tongue_Up', 'Tongue_Wide'
    ]
    solved_suffix = '_solved'
    divided_suffix = '*_divided'
    root_meshes = '*_root'
    not_all = False
    divided_bls = 'divided_bls'
    cm_rig = 'cm_rig'
    jnts_grp = '_jnt_grp'

    # Checks all meshes in scene

    for f_mesh in facefx_combined_meshes + [combined_bls_grp] + teeth_bls:
        if not cmds.objExists(f_mesh):
            print f_mesh
            not_all = True

    if not_all:
        sys.exit('Not all objects for facefx division present in scene.')

    # Creates complex and simple meshes from head
    # Adds skin for complex and simple
    create_div_mesh(source=head_mesh, target=complex_template)
    create_div_mesh(source=head_mesh, target=simple_template)

    spl = split_blendshapes.SplitBlendshapes(gender=gender)
    spl.blendshapes_in_scene()
    spl.prepare_blendshapes()
    spl.elements_in_scene(select=False)

    # For now dir stores not used meshes.
    cmds.delete(simple_template)
    cmds.select(facefx_combined_meshes + [complex_template])

    for f_mesh in facefx_combined_meshes:
        f.split_blendshape(complex_template, f_mesh)

    cmds.group(divided_suffix, name=divided_bls)
    cmds.delete(root_meshes)
    cmds.delete(complex_template)
    cmds.delete(combined_bls_grp)
    cmds.delete(tmp_bones)
    # Checks for neutral head duplicates in scene
    cmds.select(head_mesh)
    f.find_static_blendshapes(rounded=0)
    static_meshes = cmds.ls(sl=True)
    static_meshes.remove(head_mesh)
    cmds.delete(static_meshes)
    # Collects all suitable head topology meshes
    blendshape_meshes = f.find_identical_meshes('.*', vtxs_check=True)
    blendshape_meshes.remove(head_mesh)
    cmds.blendShape(sorted(blendshape_meshes), head_mesh)
    # Keys blendshapes
    f.key_blendshapes(head_mesh, start=0)
    # Skin computation
    f.dls(head_mesh, num_jnts=220, infls=4, iters=10)
    # Checks if solved mesh created
    bad_meshes = select_bad_joints_distance_based.get_bad_joints_distance_based(
        head_mesh + solved_suffix, fit_len=11, infl_limit=0.2)
    cmds.delete(bad_meshes)
    # Second pass on deleing useless joints
    # cmds.skinCluster(f.get_skin_cluster(head_mesh), unbind=True, edit=True)
    left_jnts = cmds.skinCluster(f.get_skin_cluster(head_mesh + solved_suffix),
                                 inf=True,
                                 q=True)
    root_jnt = cmds.duplicate(left_jnts[0])[0]
    left_jnts.append(root_jnt)
    sc = cmds.skinCluster(left_jnts, head_mesh, tsb=True)[0]
    cmds.setAttr("%s.envelope" % sc, 0)
    f.dls(head_mesh, num_jnts=220, infls=4, iters=10)
    bad_meshes = select_bad_joints_distance_based.get_bad_joints_distance_based(
        head_mesh, fit_len=11, infl_limit=0.2)
    cmds.delete(bad_meshes)
    set_fxgraph.set_fxgraph(head_mesh=head_mesh,
                            teeth_mesh=teeth_mesh,
                            sex=gender,
                            skeleton=skeleton)
    # Cleanup
    # Add export combined meshes and teeth to "bls" directory
    cmds.delete(head_mesh + solved_suffix)
    cmds.delete(divided_bls)
    cmds.delete(cm_rig)
    cmds.delete(head_mesh + solved_suffix + jnts_grp)
    # Scene cleanup
    try:
        execfile(r'u:\face\scripts\scene_check.py')
    except:
        print 'Scene check failed. Skipped'