Created
May 2, 2025 18:50
-
-
Save Pakmanv/6b55a686a0c54b773fba06c63a459b3d to your computer and use it in GitHub Desktop.
vvgeoshade
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 | |
| import random | |
| import os | |
| from datetime import datetime | |
| # Updated list of default shaders that should not be modified | |
| DEFAULT_SHADERS = ["lambert1", "particleCloud1", "shaderGlow1", "standardSurface1"] | |
| # Global variable to store hidden objects | |
| hidden_objects = [] | |
| def toggle_isolate_view(*args): | |
| global hidden_objects | |
| isolate_state = cmds.checkBox(isolate_checkbox, query=True, value=True) | |
| if isolate_state: | |
| selected_shaders = cmds.textScrollList(shader_list, query=True, selectItem=True) | |
| selected_geometry = cmds.textScrollList(geometry_list, query=True, selectItem=True) | |
| if selected_shaders: | |
| select_shader_objects() | |
| elif selected_geometry: | |
| select_geometry_objects() | |
| else: | |
| if hidden_objects: | |
| cmds.showHidden(hidden_objects) | |
| hidden_objects.clear() | |
| print("Disabled isolate view and showed all hidden objects.") | |
| def create_blinn_shader(shader_name): | |
| blinn_shader = cmds.shadingNode('blinn', asShader=True, name=shader_name) | |
| blinn_shaderSG = cmds.sets(renderable=True, noSurfaceShader=True, empty=True, name=blinn_shader + 'SG') | |
| cmds.connectAttr(blinn_shader + '.outColor', blinn_shaderSG + '.surfaceShader', force=True) | |
| cmds.setAttr(blinn_shader + '.eccentricity', 0) | |
| random_color = [random.random(), random.random(), random.random()] | |
| cmds.setAttr(blinn_shader + '.color', random_color[0], random_color[1], random_color[2], type='double3') | |
| return blinn_shader, blinn_shaderSG | |
| def reassign_all_shaders(*args): | |
| shaders = cmds.ls(mat=True) | |
| for shader in shaders: | |
| if shader in DEFAULT_SHADERS: | |
| print(f"Skipping default shader: {shader}") | |
| continue | |
| blinn_shader, blinn_shaderSG = create_blinn_shader(shader) | |
| shading_groups = cmds.listConnections(shader, type='shadingEngine') | |
| if shading_groups: | |
| for sg in shading_groups: | |
| objects = cmds.sets(sg, query=True) | |
| if objects: | |
| cmds.sets(objects, edit=True, forceElement= personally) | |
| cmds.delete(shader) | |
| refresh_shader_list() | |
| print("All non-default shaders reassigned to Blinn with random colors.") | |
| def refresh_shader_list(search_term=None): | |
| shaders = cmds.ls(mat=True) | |
| cmds.textScrollList(shader_list, edit=True, removeAll=True) | |
| if shaders: | |
| for shader in shaders: | |
| if search_term and search_term.lower() not in shader.lower(): | |
| continue | |
| shading_groups = cmds.listConnections(shader, type='shadingEngine') | |
| has_face_assignments = False | |
| if shading_groups: | |
| for sg in shading_groups: | |
| objects = cmds.sets(sg, query=True) | |
| if objects and any("." in obj for obj in objects): | |
| has_face_assignments = True | |
| break | |
| if has_face_assignments: | |
| cmds.textScrollList(shader_list, edit=True, append=f"{shader} *") | |
| else: | |
| cmds.textScrollList(shader_list, edit=True, append=shader) | |
| cmds.scriptEditorInfo(clearHistory=True) | |
| def search_shaders(*args): | |
| search_term = cmds.textField(search_field_shader, query=True, text=True) | |
| refresh_shader_list(search_term) | |
| def rename_shader(*args): | |
| selected_shaders = cmds.textScrollList(shader_list, query=True, selectItem=True) | |
| if selected_shaders: | |
| for selected_shader in selected_shaders: | |
| selected_shader = selected_shader.replace(" *", "") | |
| if selected_shader in DEFAULT_SHADERS: | |
| cmds.warning(f"Cannot rename default shader: {selected_shader}") | |
| continue | |
| new_name = cmds.promptDialog(title="Rename Shader", message=f"Enter New Name for {selected_shader}:", button=["OK", "Cancel"], defaultButton="OK", cancelButton="Cancel", dismissString="Cancel") | |
| if new_name == "OK": | |
| new_name = cmds.promptDialog(query=True, text=True) | |
| cmds.rename(selected_shader, new_name) | |
| refresh_shader_list() | |
| def apply_prefix_suffix_to_all(*args): | |
| prefix = cmds.textField(prefix_field, query=True, text=True) | |
| suffix = cmds.textField(suffix_field, query=True, text=True) | |
| if prefix and not prefix.endswith("_"): | |
| prefix += "_" | |
| shaders = cmds.ls(mat=True) | |
| for shader in shaders: | |
| if shader in DEFAULT_SHADERS: | |
| print(f"Skipping default shader: {shader}") | |
| continue | |
| current_name = shader | |
| if prefix and current_name.startswith(prefix): | |
| current_name = current_name[len(prefix):] | |
| if suffix and current_name.endswith(suffix): | |
| current_name = current_name[:-len(suffix)] | |
| if current_name.endswith("_shader"): | |
| current_name = current_name[:-len("_shader")] | |
| new_name = f"{prefix}{current_name}{suffix}_shader" | |
| cmds.rename(shader, new_name) | |
| refresh_shader_list() | |
| print(f"Applied prefix '{prefix}' and suffix '{suffix}' to all non-default shaders.") | |
| def conform_shader_names(*args): | |
| shaders = cmds.ls(mat=True) | |
| for shader in shaders: | |
| if shader in DEFAULT_SHADERS: | |
| print(f"Skipping default shader: {shader}") | |
| continue | |
| base_name = shader.replace("_shader", "") | |
| if not shader.endswith("_shader"): | |
| new_material_name = f"{base_name}_shader" | |
| cmds.rename(shader, new_material_name) | |
| else: | |
| new_material_name = shader | |
| shader_engine = cmds.listConnections(new_material_name, type='shadingEngine') | |
| if shader_engine and not shader_engine[0].endswith("_sg"): | |
| new_shader_engine_name = f"{base_name}_sg" | |
| cmds.rename(shader_engine[0], new_shader_engine_name) | |
| materialinfo = cmds.listConnections(new_material_name, type='materialInfo') | |
| if materialinfo and not materialinfo[0].endswith("_materialinfo"): | |
| new_materialinfo_name = f"{base_name}_materialinfo" | |
| cmds.rename(materialinfo[0], new_materialinfo_name) | |
| refresh_shader_list() | |
| print("Conformed shader names with '_shader', '_sg', and '_materialinfo' suffixes for non-default shaders.") | |
| def delete_unused_nodes(*args): | |
| cmds.hyperShade(removeUnusedNodes=True) | |
| print("Deleted all unused nodes in the scene.") | |
| def unlock_normals(*args): | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| for geo in all_geometry: | |
| try: | |
| if cmds.polyNormalPerVertex(geo, query=True, freezeNormal=True)[0]: | |
| cmds.polyNormalPerVertex(geo, unFreezeNormal=True) | |
| print(f"Unlocked normals for: {geo}") | |
| else: | |
| print(f"Normals already unlocked for: {geo}") | |
| except Exception as e: | |
| print(f"Error unlocking normals for {geo}: {e}. Skipping...") | |
| def unlock_all_transforms(*args): | |
| all_transforms = cmds.ls(type="transform", long=True) | |
| for transform in all_transforms: | |
| for attr in ["translateX", "translateY", "translateZ", "rotateX", "rotateY", "rotateZ", "scaleX", "scaleY", "scaleZ"]: | |
| if cmds.getAttr(f"{transform}.{attr}", lock=True): | |
| cmds.setAttr(f"{transform}.{attr}", lock=False) | |
| print(f"Unlocked {attr} for: {transform}") | |
| else: | |
| print(f"{attr} already unlocked for: {transform}") | |
| def break_all_animation_keys(*args): | |
| all_anim_curves = cmds.ls(type="animCurve") | |
| if all_anim_curves: | |
| cmds.delete(all_anim_curves) | |
| print("Broke all animation keys in the scene.") | |
| else: | |
| print("No animation keys found in the scene.") | |
| def reset_all_transforms(*args): | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| for geo in all_geometry: | |
| transform = cmds.listRelatives(geo, parent=True, fullPath=True)[0] | |
| translate = cmds.getAttr(f"{transform}.translate")[0] | |
| rotate = cmds.getAttr(f"{transform}.rotate")[0] | |
| scale = cmds.getAttr(f"{transform}.scale")[0] | |
| if translate != [0, 0, 0] or rotate != [0, 0, 0] or scale != [1, 1, 1]: | |
| cmds.setAttr(f"{transform}.translate", 0, 0, 0) | |
| cmds.setAttr(f"{transform}.rotate", 0, 0, 0) | |
| cmds.setAttr(f"{transform}.scale", 1, 1, 1) | |
| print(f"Reset transforms for: {transform}") | |
| else: | |
| print(f"Transforms already reset for: {transform}") | |
| def delete_all_history(*args): | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| if not all_geometry: | |
| print("No geometry found in the scene.") | |
| return | |
| all_transforms = list(set(cmds.listRelatives(all_geometry, parent=True, fullPath=True) or [])) | |
| if not all_transforms: | |
| print("No transform nodes found for geometry.") | |
| return | |
| cmds.select(all_transforms, replace=True) | |
| try: | |
| cmds.delete(all=True, constructionHistory=True) | |
| print("Deleted all history for all geometry in the scene.") | |
| except Exception as e: | |
| print(f"Error deleting history: {e}") | |
| def freeze_all_transforms(*args): | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| for geo in all_geometry: | |
| transform = cmds.listRelatives(geo, parent=True, fullPath=True)[0] | |
| translate = cmds.getAttr(f"{transform}.translate")[0] | |
| rotate = cmds.getAttr(f"{transform}.rotate")[0] | |
| scale = cmds.getAttr(f"{transform}.scale")[0] | |
| if translate != [0, 0, 0] or rotate != [0, 0, 0] or scale != [1, 1, 1]: | |
| cmds.makeIdentity(transform, apply=True, translate=True, rotate=True, scale=True) | |
| print(f"Froze transforms for: {transform}") | |
| else: | |
| print(f"Transforms already frozen for: {transform}") | |
| def move_all_geometry_to_root(*args): | |
| try: | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| if all_geometry: | |
| all_transforms = list(set(cmds.listRelatives(all_geometry, parent=True, fullPath=True) or [])) | |
| cmds.select(all_transforms, replace=True) | |
| cmds.parent(world=True) | |
| print("Moved all geometry to the root level.") | |
| else: | |
| print("No geometry found in the scene.") | |
| except Exception as e: | |
| print(f"Error in Move All Geometry to Root: {e}") | |
| def delete_all_skeletons(*args): | |
| all_joints = cmds.ls(type="joint", long=True) | |
| if all_joints: | |
| cmds.delete(all_joints) | |
| print("Deleted all skeletons (joints) in the scene.") | |
| else: | |
| print("No skeletons (joints) found in the scene.") | |
| def delete_all_display_layers(*args): | |
| display_layers = cmds.ls(type="displayLayer") | |
| if display_layers: | |
| for layer in display_layers: | |
| if layer != "defaultLayer": | |
| cmds.delete(layer) | |
| print("Deleted all display layers in the scene.") | |
| else: | |
| print("No display layers found in the scene.") | |
| def carpet_bomb(*args): | |
| print("Carpet Bombing this MFuker...") | |
| unlock_normals() | |
| unlock_all_transforms() | |
| break_all_animation_keys() | |
| delete_all_history() | |
| move_all_geometry_to_root() | |
| freeze_all_transforms() | |
| reset_all_transforms() | |
| delete_all_display_layers() | |
| optimize_scene() | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| if all_geometry: | |
| file_path = cmds.file(query=True, sceneName=True) | |
| asset_name = os.path.splitext(os.path.basename(file_path))[0] | |
| group_name = cmds.group(empty=True, name=asset_name) | |
| for geo in all_geometry: | |
| transform = cmds.listRelatives(geo, parent=True, fullPath=True)[0] | |
| cmds.parent(transform, group_name) | |
| current_date = datetime.now().strftime("%Y-%m-%d") | |
| cmds.addAttr(group_name, longName="note", dataType="string") | |
| cmds.setAttr(f"{group_name}.note", f"Date: {current_date}, VV, file was carpet bombed", type="string") | |
| all_locators = cmds.ls(type="locator", long=True) | |
| if all_locators: | |
| cmds.delete(all_locators) | |
| print("Deleted all locators in the scene.") | |
| if cmds.checkBox(delete_textures_checkbox, query=True, value=True): | |
| delete_all_texture_files() | |
| cmds.evalDeferred("create_vv_geo_shade_ui()") | |
| cmds.confirmDialog(title="Carpet Bomb Complete", message="I just saved you $$$$", button=["OK"], defaultButton="OK") | |
| print("Carpet Bombing complete.") | |
| def nuke_this_mfuker(*args): | |
| print("Nuking this MFuker...") | |
| unlock_normals() | |
| unlock_all_transforms() | |
| break_all_animation_keys() | |
| delete_all_history() | |
| move_all_geometry_to_root() | |
| freeze_all_transforms() | |
| reset_all_transforms() | |
| reset_geometry_naming() | |
| delete_all_skeletons() | |
| delete_all_display_layers() | |
| optimize_scene() | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| if all_geometry: | |
| file_path = cmds.file(query=True, sceneName=True) | |
| asset_name = os.path.splitext(os.path.basename(file_path))[0] | |
| group_name = cmds.group(empty=True, name=asset_name) | |
| for geo in all_geometry: | |
| transform = cmds.listRelatives(geo, parent=True, fullPath=True)[0] | |
| cmds.parent(transform, group_name) | |
| current_date = datetime.now().strftime("%Y-%m-%d") | |
| cmds.addAttr(group_name, longName="note", dataType="string") | |
| cmds.setAttr(f"{group_name}.note", f"Date: {current_date}, VV, file was nuked", type="string") | |
| all_locators = cmds.ls(type="locator", long=True) | |
| if all_locators: | |
| cmds.delete(all_locators) | |
| print("Deleted all locators in the scene.") | |
| if cmds.checkBox(delete_textures_checkbox, query=True, value=True): | |
| delete_all_texture_files() | |
| cmds.evalDeferred("create_vv_geo_shade_ui()") | |
| cmds.confirmDialog(title="Nuke Complete", message="I just saved you $$$$", button=["OK"], defaultButton="OK") | |
| print("Nuking complete.") | |
| def delete_all_texture_files(*args): | |
| all_file_nodes = cmds.ls(type="file") | |
| if all_file_nodes: | |
| for file_node in all_file_nodes: | |
| texture_path = cmds.getAttr(f"{file_node}.fileTextureName") | |
| if os.path.exists(texture_path): | |
| try: | |
| os.remove(texture_path) | |
| print(f"Deleted texture file: {texture_path}") | |
| except Exception as e: | |
| print(f"Error deleting texture file {texture_path}: {e}") | |
| else: | |
| print("No texture files found in the scene.") | |
| def optimize_scene(*args): | |
| cmds.OptimizeScene() | |
| print("Optimized scene using OptimizeScene.") | |
| refresh_tool() | |
| def select_shader_objects(*args): | |
| global hidden_objects | |
| cmds.select(clear=True) | |
| selected_shaders = cmds.textScrollList(shader_list, query=True, selectItem=True) | |
| if selected_shaders: | |
| for selected_shader in selected_shaders: | |
| selected_shader = selected_shader.replace(" *", "") | |
| shading_groups = cmds.listConnections(selected_shader, type='shadingEngine') | |
| if shading_groups: | |
| connected_objects = [] | |
| for sg in shading_groups: | |
| objects = cmds.sets(sg, query=True) | |
| if objects: | |
| connected_objects.extend(objects) | |
| connected_objects = cmds.ls(connected_objects, objectsOnly=True, long=True) | |
| connected_objects = list(set(cmds.listRelatives(connected_objects, parent=True, fullPath=True) or connected_objects)) | |
| if connected_objects: | |
| cmds.select(connected_objects, add=True) | |
| print(f"Selected objects connected to shader: {selected_shader}") | |
| if cmds.checkBox(isolate_checkbox, query=True, value=True): | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| all_geometry_transforms = list(set(cmds.listRelatives(all_geometry, parent=True, fullPath=True) or [])) | |
| hidden_objects = [obj for obj in all_geometry_transforms if obj not in connected_objects] | |
| cmds.hide(hidden_objects) | |
| cmds.showHidden(connected_objects) | |
| else: | |
| cmds.warning(f"No objects connected to shader: {selected_shader}") | |
| else: | |
| cmds.warning(f"No shading groups found for shader: {selected_shader}") | |
| cmds.refresh() | |
| else: | |
| cmds.warning("No shader selected in the list.") | |
| def select_geometry_objects(*args): | |
| global hidden_objects | |
| cmds.select(clear=True) | |
| selected_geometry = cmds.textScrollList(geometry_list, query=True, selectItem=True) | |
| if selected_geometry: | |
| cmds.select(selected_geometry, replace=True) | |
| print(f"Selected geometry: {', '.join(selected_geometry)}") | |
| if cmds.checkBox(isolate_checkbox, query=True, value=True): | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| all_geometry_transforms = list(set(cmds.listRelatives(all_geometry, parent=True, fullPath=True) or [])) | |
| hidden_objects = [obj for obj in all_geometry_transforms if obj not in selected_geometry] | |
| cmds.hide(hidden_objects) | |
| cmds.showHidden(selected_geometry) | |
| else: | |
| cmds.warning("No geometry selected in the list.") | |
| def reset_geometry_naming(*args): | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| for i, geo in enumerate(all_geometry): | |
| transform = cmds.listRelatives(geo, parent=True, fullPath=True)[0] | |
| new_name = f"part_{i + 1}" | |
| cmds.rename(transform, new_name) | |
| print("Reset all geometry names to 'part_#'.") | |
| refresh_geometry_list() | |
| def refresh_tool(*args): | |
| refresh_shader_list() | |
| refresh_geometry_list() | |
| print("Refreshed shader and geometry lists.") | |
| def rename_geometry(*args): | |
| selected_geometry = cmds.textScrollList(geometry_list, query=True, selectItem=True) | |
| if selected_geometry: | |
| for geo in selected_geometry: | |
| new_name = cmds.promptDialog(title="Rename Geometry", message=f"Enter New Name for {geo}:", button=["OK", "Cancel"], defaultButton="OK", cancelButton="Cancel", dismissString="Cancel") | |
| if new_name == "OK": | |
| new_name = cmds.promptDialog(query=True, text=True) | |
| cmds.rename(geo, new_name) | |
| refresh_geometry_list() | |
| def refresh_geometry_list(search_term=None): | |
| all_geometry = cmds.ls(type="mesh", long=True) | |
| cmds.textScrollList(geometry_list, edit=True, removeAll=True) | |
| for geo in all_geometry: | |
| transform = cmds.listRelatives(geo, parent=True, fullPath=True)[0] | |
| if search_term and search_term.lower() not in transform.lower(): | |
| continue | |
| cmds.textScrollList(geometry_list, edit=True, append=transform) | |
| def search_geometry(*args): | |
| search_term = cmds.textField(search_field_geometry, query=True, text=True) | |
| refresh_geometry_list(search_term) | |
| def create_vv_geo_shade_ui(): | |
| global shader_list, isolate_checkbox, prefix_field, suffix_field, geometry_list, delete_textures_checkbox | |
| global search_field_shader, search_field_geometry | |
| window_name = "vvGeoShadeUI" | |
| if cmds.window(window_name, exists=True): | |
| cmds.deleteUI(window_name) | |
| cmds.window(window_name, title="VV Geo Shade", widthHeight=(1000, 800)) | |
| cmds.rowLayout(numberOfColumns=2, adjustableColumn=2) | |
| # Shader List Column | |
| cmds.columnLayout(adjustableColumn=True) | |
| cmds.text(label="Shader List:") | |
| shader_list = cmds.textScrollList(numberOfRows=30, allowMultiSelection=True, selectCommand=select_shader_objects, doubleClickCommand=rename_shader, height=600, width=500) | |
| refresh_shader_list() | |
| isolate_checkbox = cmds.checkBox(label="Isolate View", value=False, changeCommand=toggle_isolate_view) | |
| cmds.rowLayout(numberOfColumns=3, adjustableColumn=2) | |
| cmds.text(label="Search:") | |
| search_field_shader = cmds.textField() | |
| cmds.button(label="Search", command=search_shaders) | |
| cmds.setParent("..") | |
| cmds.rowLayout(numberOfColumns=3, adjustableColumn=2) | |
| cmds.text(label="Prefix:") | |
| prefix_field = cmds.textField() | |
| cmds.button(label="Commit Prefix", command=lambda *_: apply_prefix_suffix_to_all()) | |
| cmds.setParent("..") | |
| cmds.rowLayout(numberOfColumns=3, adjustableColumn=2) | |
| cmds.text(label="Suffix:") | |
| suffix_field = cmds.textField() | |
| cmds.button(label="Commit Suffix", command=lambda *_: apply_prefix_suffix_to_all()) | |
| cmds.setParent("..") | |
| cmds.button(label="Optimize Scene", command=optimize_scene) | |
| cmds.button(label="Delete Unused Nodes", command=delete_unused_nodes) | |
| cmds.button(label="Reassign All Shaders", command=reassign_all_shaders) | |
| cmds.button(label="Conform Shader Names", command=conform_shader_names) | |
| cmds.button(label="Refresh", command=refresh_tool) | |
| cmds.setParent("..") | |
| # Geometry List Column | |
| cmds.columnLayout(adjustableColumn=True) | |
| cmds.text(label="Geometry List:") | |
| geometry_list = cmds.textScrollList(numberOfRows=30, allowMultiSelection=True, selectCommand=select_geometry_objects, doubleClickCommand=rename_geometry, height=600, width=500) | |
| cmds.rowLayout(numberOfColumns=3, adjustableColumn=2) | |
| cmds.text(label="Search:") | |
| search_field_geometry = cmds.textField() | |
| cmds.button(label="Search", command=search_geometry) | |
| cmds.setParent("..") | |
| cmds.button(label="Unlock Normals", command=unlock_normals) | |
| cmds.button(label="Unlock All Transforms", command=unlock_all_transforms) | |
| cmds.button(label="Break All Animation Keys", command=break_all_animation_keys) | |
| cmds.button(label="Delete All History", command=delete_all_history) | |
| cmds.button(label="Move All Geometry to Root", command=move_all_geometry_to_root) | |
| cmds.button(label="Freeze All Transforms", command=freeze_all_transforms) | |
| cmds.button(label="Delete All Skeletons", command=delete_all_skeletons) | |
| cmds.button(label="Reset All Transforms", command=reset_all_transforms) | |
| cmds.button(label="Reset Geometry Naming", command=reset_geometry_naming) | |
| cmds.button(label="Carpet Bomb", command=carpet_bomb, backgroundColor=(1, 0.5, 0)) | |
| cmds.button(label="Nuke this MFuker", command=nuke_this_mfuker, backgroundColor=(1, 0, 0)) | |
| delete_textures_checkbox = cmds.checkBox(label="Delete All Texture Files", value=False) | |
| cmds.text(label="Disclaimer: This tool is destructive and should not be used if you intend to keep any skinCluster or deformers.", align="left") | |
| cmds.text(label="If you optimize the scene, please refresh the tool.", align="left") | |
| refresh_geometry_list() | |
| cmds.setParent("..") | |
| file_path = cmds.file(query=True, sceneName=True) | |
| if file_path: | |
| file_name = os.path.splitext(os.path.basename(file_path))[0] | |
| cmds.textField(prefix_field, edit=True, text=f"{file_name}_") | |
| cmds.showWindow(window_name) | |
| create_vv_geo_shade_ui() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment