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
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