示例#1
0
def update_transformed_shape(source, target, hold_transform):
    """ Updates the target shape with the given source shape content

    :param source: maya shape node
    :type source: str

    :param target: maya shape node
    :type target: str

    :param hold_transform: keeps the transform node position values
    :type hold_transform: bool
    """

    deform_origin = get_shape_orig(target)

    if deform_origin:
        return

    logger.debug("Transformed shape found: {}".format(target))

    # maintain transform on target
    if hold_transform:
        update_shape(source, target)

    # update target transform
    else:
        update_transform(source, target)
def filter_shape_orig(shape, intermediate):
    """ Filters whether the intermediate shape provided should be used or not

    if an intermediate isn't provided then

    :param shape: the shape node name
    :type shape: str

    :param intermediate: the intermediate shape name
    :type intermediate: str

    :return: the valid intermediate shape
    :rtype: str
    """

    # gets source intermediate shape if any
    orig = get_shape_orig(shape)

    # return the orig shape if no intermediate was provided and one is found
    if not intermediate and orig:
        return orig[0]

    # return the provided intermediate shape
    elif intermediate:
        return intermediate

    # return the shape if no intermediate was given and no orig shape was found
    else:
        return shape
示例#3
0
def update_deformed_shape(source, target, mismatching_topology=True):
    """ Updates the target shape with the given source shape content

    :param source: maya shape node
    :type source: str

    :param target: maya shape node
    :type target: str

    :param mismatching_topology: ignore or not mismatching topologies
    :type mismatching_topology: bool
    """

    # gets orig shape
    deform_origin = get_shape_orig(target)

    # returns as target is not a deformed shape
    if not deform_origin:
        return

    logger.debug("Deformed shape found: {}".format(target))

    # returns if source and target shapes don't match
    if not is_matching_type(source, target):
        logger.warning(
            "{} and {} don't have same shape type. passing...".format(
                source, target))
        return

    # returns if vertices count isn't equal and mismatching isn't requested
    if not mismatching_topology and not is_matching_count(source, target):
        logger.warning("{} and {} don't have same shape vertices count."
                       "passing...".format(source, target))
        return

    deform_origin = deform_origin[0]

    # updates map1 name
    copy_map1_name(source, deform_origin)

    # updates on mismatching topology
    if mismatching_topology and not is_matching_count(source, target):
        update_deformed_mismatching_shape(source, target, deform_origin)
        return

    # update the shape
    update_shape(source, deform_origin)

    # update uvs set on target
    update_uvs_sets(target)
def create_blendshapes_backup(source, target, nodes):
    """ Creates an updated backup for the given blendshapes nodes on source

    .. important:: This method does not work as the other source/target type
                   of methods in flex. The source is the current geometry
                   before topology update containing the blendshape nodes.
                   We use it in order to create a wrap to the newer target
                   geometry topology.

    :param source: current shape node
    :type source: str

    :param target: new shape node
    :type target: str

    :return: backup blendshape nodes
    :rtype: list
    """

    logger.debug("Creating blendshapes backup")

    # gets simpler shape name
    shape_name = get_prefix_less_name(target)

    # get attributes types
    attrs = get_shape_type_attributes(target)

    # creates source duplicate
    intermediate = get_shape_orig(source)[0]
    source_duplicate = create_duplicate(intermediate, "{}_flex_bs_sourceShape"
                                        .format(shape_name))

    # first loops to create a clean copy of the blendshape nodes
    nodes_copy = []
    for node in nodes:
        duplicate = copy_blendshape_node(node, source_duplicate)
        if duplicate:
            nodes_copy.append(duplicate)

    # creates wrapped target shape
    warp_target = create_duplicate(target, "{}_flex_bs_warpShape"
                                   .format(shape_name))

    # wraps the duplicate to the source
    create_wrap(source_duplicate, warp_target)

    # creates blendshape target shape
    target_duplicate = create_duplicate(target, "{}_flex_bs_targetShape"
                                        .format(shape_name))

    return_nodes = []

    # loops on the blendshape nodes
    for node in nodes_copy:
        # creates transfer blendshape
        transfer_node = cmds.deformer(target_duplicate, type="blendShape",
                                      name="flex_transfer_{}".format(node))[0]

        # get blendshape targets indices. We skip verification because at this
        # stage the copied blendshapes nodes will always have targets
        targets_idx = cmds.getAttr("{}.weight".format(node), multiIndices=True)

        # loop on blendshape targets indices
        for idx in targets_idx or []:
            # input target group attribute
            attr_name = (BLENDSHAPE_TARGET.format(node, idx))

            # blendshape target name
            target_name = cmds.aliasAttr("{}.weight[{}]".format(node, idx),
                                         query=True)

            # loop on actual targets and in-between targets
            for target in cmds.getAttr(attr_name, multiIndices=True):

                # gets and sets the blendshape weight value
                weight = float((target - 5000) / 1000.0)
                cmds.setAttr("{}.weight[{}]".format(node, idx), weight)

                # geometry target attribute
                geometry_target_attr = "{}[{}].inputGeomTarget".format(
                    attr_name, target)

                shape_target = geometry_target_attr.replace(
                    geometry_target_attr.split(".")[0], transfer_node)

                # updates the target
                cmds.connectAttr("{}.{}".format(warp_target, attrs["output"]),
                                 shape_target, force=True)

                cmds.disconnectAttr("{}.{}"
                                    .format(warp_target, attrs["output"]),
                                    shape_target)

                cmds.setAttr("{}.weight[{}]".format(node, idx), 0)

            cmds.setAttr("{}.weight[{}]".format(transfer_node, idx), 0)

            if target_name:
                cmds.aliasAttr(target_name, "{}.weight[{}]".format(
                    transfer_node, idx))

        # adds blendshape node to nodes to return
        return_nodes.append("{}".format(transfer_node))

    # deletes backup process shapes
    cmds.delete(cmds.listRelatives(source_duplicate, parent=True),
                cmds.listRelatives(warp_target, parent=True))

    # forces refresh
    cmds.refresh()

    return return_nodes