Created
May 2, 2025 23:53
-
-
Save Pakmanv/edb98935e0f061a325ae40232419334f to your computer and use it in GitHub Desktop.
vvjointalignx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import maya.cmds as cmds | |
| # Global list to store all created joints | |
| created_joints_list = [] | |
| # Function to get the hierarchy of the selected joints | |
| def get_joint_hierarchy(joint, indent_level=0): | |
| """ | |
| Recursively get the joint hierarchy with indentation for children. | |
| :param joint: The joint to start from. | |
| :param indent_level: The level of indentation (for children). | |
| :return: A list of strings representing the hierarchy. | |
| """ | |
| hierarchy = [] | |
| hierarchy.append(" " * indent_level + joint) | |
| children = cmds.listRelatives(joint, children=True, type="joint") or [] | |
| for child in children: | |
| hierarchy.extend(get_joint_hierarchy(child, indent_level + 1)) | |
| return hierarchy | |
| # Function to update the UI with the current joint selection | |
| def update_joint_hierarchy_ui(*args): | |
| cmds.textScrollList("jointHierarchyList", edit=True, removeAll=True) | |
| selection = cmds.ls(selection=True, type="joint") | |
| if not selection: | |
| cmds.textScrollList("jointHierarchyList", edit=True, append="No joints selected!") | |
| cmds.text("jointHierarchyCount", edit=True, label="Entries: 0") | |
| return | |
| for joint in selection: | |
| joint_hierarchy = get_joint_hierarchy(joint) | |
| for line in joint_hierarchy: | |
| cmds.textScrollList("jointHierarchyList", edit=True, append=line) | |
| entry_count = cmds.textScrollList("jointHierarchyList", query=True, numberOfItems=True) | |
| cmds.text("jointHierarchyCount", edit=True, label=f"Entries: {entry_count}") | |
| # Function to create joints at the pivot of objects in the first list | |
| def create_joints_from_first_list(*args): | |
| global created_joints_list | |
| cmds.textScrollList("thirdList", edit=True, removeAll=True) | |
| first_list_items = cmds.textScrollList("jointHierarchyList", query=True, allItems=True) | |
| if not first_list_items: | |
| cmds.warning("No items in the first list to create joints from!") | |
| return | |
| if not cmds.objExists("assetname"): | |
| locator = cmds.spaceLocator(name="assetname")[0] | |
| else: | |
| locator = "assetname" | |
| if not cmds.objExists("locator_group"): | |
| locator_group = cmds.group(empty=True, name="locator_group") | |
| else: | |
| locator_group = "locator_group" | |
| for item in first_list_items: | |
| item_name = item.strip() | |
| if not cmds.objExists(item_name): | |
| cmds.warning(f"Object '{item_name}' does not exist in the scene. Skipping...") | |
| continue | |
| pivot_position = cmds.xform(item_name, query=True, worldSpace=True, rotatePivot=True) | |
| joint_matrix = cmds.xform(item_name, query=True, worldSpace=True, matrix=True) | |
| joint_locator = cmds.spaceLocator(name=f"{item_name}_locator")[0] | |
| cmds.xform(joint_locator, translation=pivot_position, worldSpace=True) | |
| cmds.xform(joint_locator, matrix=joint_matrix, worldSpace=True) | |
| cmds.setAttr(f"{joint_locator}.overrideEnabled", 1) | |
| cmds.setAttr(f"{joint_locator}.overrideColor", 17) | |
| cmds.parent(joint_locator, locator_group) | |
| cmds.select(clear=True) | |
| joint = cmds.joint(position=pivot_position) | |
| cmds.delete(cmds.orientConstraint(joint_locator, joint)) | |
| rotation = cmds.getAttr(f"{joint}.rotate")[0] | |
| cmds.setAttr(f"{joint}.jointOrientX", rotation[0]) | |
| cmds.setAttr(f"{joint}.jointOrientY", rotation[1]) | |
| cmds.setAttr(f"{joint}.jointOrientZ", rotation[2]) | |
| cmds.setAttr(f"{joint}.rotateX", 0) | |
| cmds.setAttr(f"{joint}.rotateY", 0) | |
| cmds.setAttr(f"{joint}.rotateZ", 0) | |
| cmds.setAttr(f"{joint}.radius", 100) | |
| cmds.setAttr(f"{joint}.overrideEnabled", 1) | |
| cmds.setAttr(f"{joint}.overrideColor", 30) | |
| base_name = f"{item_name}_joint" | |
| joint_name = base_name | |
| version = 1 | |
| while cmds.objExists(joint_name): | |
| joint_name = f"{base_name}{version}" | |
| version += 1 | |
| joint = cmds.rename(joint, joint_name) | |
| created_joints_list.append(joint) | |
| cmds.parent(joint, locator) | |
| update_created_joints_ui() | |
| update_third_list() | |
| # Function to update the created joints list in the UI | |
| def update_created_joints_ui(*args): | |
| global created_joints_list | |
| cmds.textScrollList("createdJointsList", edit=True, removeAll=True) | |
| for joint in created_joints_list: | |
| cmds.textScrollList("createdJointsList", edit=True, append=joint) | |
| entry_count = cmds.textScrollList("createdJointsList", query=True, numberOfItems=True) | |
| cmds.text("createdJointsCount", edit=True, label=f"Entries: {entry_count}") | |
| # Function to update the third list (new hierarchy) | |
| def update_third_list(*args): | |
| cmds.textScrollList("thirdList", edit=True, removeAll=True) | |
| new_joints = cmds.listRelatives("assetname", children=True, type="joint") or [] | |
| if not new_joints: | |
| cmds.textScrollList("thirdList", edit=True, append="No joints under 'assetname' locator.") | |
| return | |
| for joint in new_joints: | |
| joint_hierarchy = get_joint_hierarchy(joint) | |
| for line in joint_hierarchy: | |
| cmds.textScrollList("thirdList", edit=True, append=line) | |
| entry_count = cmds.textScrollList("thirdList", query=True, numberOfItems=True) | |
| cmds.text("thirdCount", edit=True, label=f"Entries: {entry_count}") | |
| # Function to select objects from the lists | |
| def select_from_list(list_name, *args): | |
| selected_items = cmds.textScrollList(list_name, query=True, selectItem=True) or [] | |
| if selected_items: | |
| cmds.select(selected_items) | |
| # Function to reconstruct the hierarchy of created joints | |
| def reconstruct_hierarchy(*args): | |
| first_list_items = cmds.textScrollList("jointHierarchyList", query=True, allItems=True) or [] | |
| first_list_items = [item.strip() for item in first_list_items] | |
| new_joints = cmds.listRelatives("assetname", children=True, type="joint") or [] | |
| for item in first_list_items: | |
| joint_name = f"{item}_joint" | |
| if joint_name in new_joints: | |
| parent_item = cmds.listRelatives(item, parent=True) or [] | |
| if parent_item: | |
| parent_joint = f"{parent_item[0]}_joint" | |
| if parent_joint in new_joints: | |
| cmds.parent(joint_name, parent_joint) | |
| update_third_list() | |
| # Function to compare naming differences between List One and List Three | |
| def compare_naming_differences(): | |
| first_list_items = cmds.textScrollList("jointHierarchyList", query=True, allItems=True) or [] | |
| third_list_items = cmds.textScrollList("thirdList", query=True, allItems=True) or [] | |
| first_list_names = [item.strip() for item in first_list_items] | |
| third_list_names = [item.strip().replace("_joint", "") for item in third_list_items] | |
| naming_differences = [] | |
| for name in first_list_names: | |
| if name not in third_list_names: | |
| naming_differences.append(f"'{name}' in List One but not in List Three") | |
| for name in third_list_names: | |
| if name not in first_list_names: | |
| naming_differences.append(f"'{name}' in List Three but not in List One") | |
| return naming_differences | |
| # Function to compare hierarchies side by side | |
| def compare_hierarchies(): | |
| first_list_items = cmds.textScrollList("jointHierarchyList", query=True, allItems=True) or [] | |
| third_list_items = cmds.textScrollList("thirdList", query=True, allItems=True) or [] | |
| first_list_hierarchy = "\n".join(first_list_items) | |
| third_list_hierarchy = "\n".join(third_list_items) | |
| return first_list_hierarchy, third_list_hierarchy | |
| # Function to rename items in the lists | |
| def conform_joints(*args): | |
| cmds.textScrollList("fourthList", edit=True, removeAll=True) | |
| first_list_items = cmds.textScrollList("jointHierarchyList", query=True, allItems=True) or [] | |
| naming_conflicts = [] | |
| for item in first_list_items: | |
| item_name = item.strip() | |
| if cmds.objExists(item_name): | |
| new_name = f"{item_name}_old" | |
| version = 1 | |
| while cmds.objExists(new_name): | |
| new_name = f"{item_name}_old{version}" | |
| version += 1 | |
| if version > 1: | |
| naming_conflicts.append(f"Renamed '{item_name}' to '{new_name}' due to conflict.") | |
| cmds.rename(item_name, new_name) | |
| third_list_items = cmds.textScrollList("thirdList", query=True, allItems=True) or [] | |
| for item in third_list_items: | |
| item_name = item.strip() | |
| if cmds.objExists(item_name): | |
| new_name = item_name.replace("_joint", "") | |
| version = 1 | |
| while cmds.objExists(new_name): | |
| new_name = f"{new_name}{version}" | |
| version += 1 | |
| if version > 1: | |
| naming_conflicts.append(f"Renamed '{item_name}' to '{new_name}' due to conflict.") | |
| cmds.rename(item_name, new_name) | |
| rotation_issues = [] | |
| tolerance = 0.001 | |
| for joint in cmds.listRelatives("assetname", children=True, type="joint") or []: | |
| rotation = cmds.getAttr(f"{joint}.rotate")[0] | |
| if any(abs(val) > tolerance for val in rotation): | |
| rotation_issues.append(f"Joint '{joint}' has non-zero rotation: {rotation}") | |
| naming_differences = compare_naming_differences() | |
| first_list_hierarchy, third_list_hierarchy = compare_hierarchies() | |
| if naming_conflicts: | |
| cmds.textScrollList("fourthList", edit=True, append="Naming Conflicts:") | |
| for conflict in naming_conflicts: | |
| cmds.textScrollList("fourthList", edit=True, append=conflict) | |
| if rotation_issues: | |
| cmds.textScrollList("fourthList", edit=True, append="Rotation Issues:") | |
| for issue in rotation_issues: | |
| cmds.textScrollList("fourthList", edit=True, append=issue) | |
| else: | |
| cmds.textScrollList("fourthList", edit=True, append="Joint placements completed and fucken solid. Refresh all.") | |
| if naming_differences: | |
| cmds.textScrollList("fourthList", edit=True, append="Naming Differences:") | |
| for difference in naming_differences: | |
| cmds.textScrollList("fourthList", edit=True, append=difference) | |
| cmds.textScrollList("fourthList", edit=True, append="Hierarchy Comparison:") | |
| cmds.textScrollList("fourthList", edit=True, append="List One Hierarchy:") | |
| cmds.textScrollList("fourthList", edit=True, append=first_list_hierarchy) | |
| cmds.textScrollList("fourthList", edit=True, append="List Three Hierarchy:") | |
| cmds.textScrollList("fourthList", edit=True, append=third_list_hierarchy) | |
| cmds.textScrollList("fourthList", edit=True, append="Disclaimer:") | |
| cmds.textScrollList("fourthList", edit=True, append="If the rig is broken, it's not my fault. I'm just matching what you inputted and cleaning your shit.") | |
| if cmds.objExists("locator_group"): | |
| cmds.delete("locator_group") | |
| cmds.textScrollList("jointHierarchyList", edit=True, removeAll=True) | |
| cmds.text("jointHierarchyCount", edit=True, label="Entries: 0") | |
| update_joint_hierarchy_ui() | |
| update_third_list() | |
| # Function to refresh the UI | |
| def refresh_ui(*args): | |
| cmds.textScrollList("jointHierarchyList", edit=True, removeAll=True) | |
| cmds.textScrollList("createdJointsList", edit=True, removeAll=True) | |
| cmds.textScrollList("thirdList", edit=True, removeAll=True) | |
| cmds.textScrollList("fourthList", edit=True, removeAll=True) | |
| cmds.text("jointHierarchyCount", edit=True, label="Entries: 0") | |
| cmds.text("createdJointsCount", edit=True, label="Entries: 0") | |
| cmds.text("thirdCount", edit=True, label="Entries: 0") | |
| cmds.text("fourthCount", edit=True, label="Entries: 0") | |
| # Function to create the UI | |
| def create_vv_joint_align_ui(): | |
| if cmds.window("vvJointAlignWindow", exists=True): | |
| cmds.deleteUI("vvJointAlignWindow") | |
| cmds.window("vvJointAlignWindow", title="VV JointAlignX", widthHeight=(1250, 1000)) | |
| cmds.formLayout("mainFormLayout") | |
| hierarchy_label = cmds.text(label="Selection Hierarchy", align="left", parent="mainFormLayout") | |
| joint_hierarchy_count = cmds.text("jointHierarchyCount", label="Entries: 0", align="left", parent="mainFormLayout") | |
| joint_list = cmds.textScrollList("jointHierarchyList", allowMultiSelection=True, height=800, width=300, parent="mainFormLayout") | |
| created_joints_label = cmds.text(label="Created Joints", align="left", parent="mainFormLayout") | |
| created_joints_count = cmds.text("createdJointsCount", label="Entries: 0", align="left", parent="mainFormLayout") | |
| created_joints_list_ui = cmds.textScrollList("createdJointsList", allowMultiSelection=True, height=800, width=300, parent="mainFormLayout") | |
| third_label = cmds.text(label="New Hierarchy", align="left", parent="mainFormLayout") | |
| third_count = cmds.text("thirdCount", label="Entries: 0", align="left", parent="mainFormLayout") | |
| third_list = cmds.textScrollList("thirdList", allowMultiSelection=True, height=800, width=300, parent="mainFormLayout") | |
| fourth_label = cmds.text(label="Additional Info", align="left", parent="mainFormLayout") | |
| fourth_count = cmds.text("fourthCount", label="Entries: 0", align="left", parent="mainFormLayout") | |
| fourth_list = cmds.textScrollList("fourthList", allowMultiSelection=True, height=800, width=400, parent="mainFormLayout") | |
| bottom_window = cmds.scrollField("bottomWindow", wordWrap=True, height=100, width=1200, parent="mainFormLayout") | |
| update_button = cmds.button(label="Update Selection", command=update_joint_hierarchy_ui, parent="mainFormLayout") | |
| create_joints_button = cmds.button(label="Create Joints", command=create_joints_from_first_list, parent="mainFormLayout") | |
| reconstruct_button = cmds.button(label="Reconstruct Hierarchy", command=reconstruct_hierarchy, parent="mainFormLayout") | |
| conform_button = cmds.button(label="Conform", command=conform_joints, parent="mainFormLayout") | |
| refresh_button = cmds.button(label="Refresh All", command=refresh_ui, parent="mainFormLayout") | |
| cmds.formLayout( | |
| "mainFormLayout", | |
| edit=True, | |
| attachForm=[ | |
| (hierarchy_label, "top", 5), (hierarchy_label, "left", 5), | |
| (joint_hierarchy_count, "top", 30), (joint_hierarchy_count, "left", 5), | |
| (joint_list, "top", 60), (joint_list, "left", 5), | |
| (created_joints_label, "top", 5), (created_joints_label, "left", 315), | |
| (created_joints_count, "top", 30), (created_joints_count, "left", 315), | |
| (created_joints_list_ui, "top", 60), (created_joints_list_ui, "left", 315), | |
| (third_label, "top", 5), (third_label, "left", 625), | |
| (third_count, "top", 30), (third_count, "left", 625), | |
| (third_list, "top", 60), (third_list, "left", 625), | |
| (fourth_label, "top", 5), (fourth_label, "left", 935), | |
| (fourth_count, "top", 30), (fourth_count, "left", 935), | |
| (fourth_list, "top", 60), (fourth_list, "left", 935), | |
| (bottom_window, "left", 5), (bottom_window, "right", 5), (bottom_window, "bottom", 40), | |
| (update_button, "left", 5), (update_button, "bottom", 5), | |
| (create_joints_button, "left", 315), (create_joints_button, "bottom", 5), | |
| (reconstruct_button, "left", 625), (reconstruct_button, "bottom", 5), | |
| (conform_button, "left", 935), (conform_button, "bottom", 5), | |
| (refresh_button, "left", 5), (refresh_button, "bottom", 35), | |
| ], | |
| attachControl=[ | |
| (joint_list, "bottom", 5, update_button), | |
| (created_joints_list_ui, "bottom", 5, create_joints_button), | |
| (third_list, "bottom", 5, reconstruct_button), | |
| (fourth_list, "bottom", 5, refresh_button), | |
| (bottom_window, "top", 5, fourth_list), | |
| ], | |
| ) | |
| cmds.textScrollList("jointHierarchyList", edit=True, selectCommand=lambda *args: select_from_list("jointHierarchyList")) | |
| cmds.textScrollList("createdJointsList", edit=True, selectCommand=lambda *args: select_from_list("createdJointsList")) | |
| cmds.textScrollList("thirdList", edit=True, selectCommand=lambda *args: select_from_list("thirdList")) | |
| cmds.textScrollList("fourthList", edit=True, selectCommand=lambda *args: select_from_list("fourthList")) | |
| cmds.showWindow("vvJointAlignWindow") | |
| # Run the function to create the UI | |
| create_vv_joint_align_ui() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment