Skip to content

Instantly share code, notes, and snippets.

@Pakmanv
Created May 2, 2025 18:50
Show Gist options
  • Select an option

  • Save Pakmanv/6b55a686a0c54b773fba06c63a459b3d to your computer and use it in GitHub Desktop.

Select an option

Save Pakmanv/6b55a686a0c54b773fba06c63a459b3d to your computer and use it in GitHub Desktop.
vvgeoshade
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