Skip to content

Instantly share code, notes, and snippets.

@DrHaze
Last active January 10, 2023 02:18
Show Gist options
  • Save DrHaze/b0e6a5fc1b4d8daa748448764e3e639a to your computer and use it in GitHub Desktop.
Save DrHaze/b0e6a5fc1b4d8daa748448764e3e639a to your computer and use it in GitHub Desktop.
Remove useless requires on a bunch of Maya scenes
# coding: utf8
"""
This script searches Maya scenes in a folder then parses every scene and tries to remove unwanted "requires"
ONLY WORKS ON PYTHON 3.5+
Tested on windows only
This script uses the cgLogging module avaiable here: https://github.com/asisudai/cg-logging
"""
#The fundamentals for working with python
import glob
import os
import sys
import time
from multiprocessing import Pool, Process, current_process
sys.dont_write_bytecode = True
######################################################################
# Configuration
######################################################################
PROJECT_NAME = "Your_Project_Name"
PROJECT_PATH = r"C:\Users\DrHaze\Documents\maya\projects\Your_Project_Name"
# Logging related variables
WRITE_LOGS = True
LOGS_FOLDER = os.path.join( os.getcwd(), "Logs" )
LOGS_FILE = os.path.join( LOGS_FOLDER, PROJECT_NAME+".txt")
# Process related variables
POOL_SIZE = 8
CHUNK_SIZE = 30
# How many line do we want to check?
# Parsing the scenes entirelly is useless and can be reaaaaally long
NB_LINES_CHECK = 200
# What are we looking for?
REQUIRES_LIST = [
'requires "mayall_maya70" "0.9.1(Beta)";\n' ,
'requires "elastikSolver" "0.991";\n' ,
'requires "RenderMan_for_Maya" "3.0.1";\n' ,
'requires "maxwell" "2.6.17";\n' ,
'requires "maxwell" "2.7.11";\n' ,
'requires "tfbUVanim2013" "1.0";\n' ,
'requires "smoothCmd" "1.0";\n' ,
'requires "mglLockSet" "2013.0";\n' ,
'requires "mgDispDeformer" "1.0";\n' ,
'requires "mgComponentLocator" "1.0";\n' ,
'requires "mgAbcReader" "1.0";\n' ,
'requires "igMaya80RenderStates" "1.0";\n' ,
'requires "igMaya80FxShader" "0.1";\n' ,
'requires "igMaya2013RenderStates" "1.0";\n' ,
'requires "mgHCDeformer" "1.0";\n' ,
'requires "igMaya2013FxShader" "0.1";\n' ,
'requires "vrayformaya" "2.20.01";\n' ,
'requires "mgRayIntersect" "1.1";\n' ,
'requires "hctMayaSceneExport" "2013.1.0.1 (2013.1 r1)";\n' ,
'requires "tfbMaterialAnim2013" "1.0";\n' ,
'requires "fStretch" "1.0.1";\n' ,
'requires "mglClosestPointOnMeshNode" "3.0";\n' ,
'requires "shaveNode" "1.1";\n' ,
'requires "closestPointOnMesh" "4.0";\n' ,
'requires "VertexChameleon80" "1.6.0, Sep 10 2010 @ 17:15:14";\n' ,
'requires "TfbUtilities" "1.0";\n' ,
'requires "benMatrixArrayOperator" "1.0";\n' ,
'requires "tfbUVanim" "1.0";\n' ,
'requires "imst" "3.6";\n' ,
'requires "TurtleForMaya80" "4.1.0.5";\n' ,
'requires "DisplaceD" "1.12";\n' ,
'requires "mgCustomLocator" "1.0";\n' ,
'requires "ASTeK" "2.45";\n' ,
'requires "ngSkinTools" "1.0beta.875";\n' ,
'requires "dynSolver" "1.01";\n' ,
'requires "AMutility" "6.5";\n' ,
'requires "mgNurbsSurfShaper.py" "1.0";\n' ,
'requires "AMdeformers" "6.5";\n' ,
'requires "AMconstraints" "6.5";\n' ,
'requires "syflex" "3.01";\n' ,
'requires "mgHair" "9.0";\n' ,
'requires "AMarmIkSolver" "6.5";\n' ,
'requires "mgStereoView" "8.0";\n' ,
'requires "AMsmoothSkinProxy" "6.0";\n' ,
'requires "ALK_TankNode.py" "1.0";\n' ,
'requires "MtoA" "2.1.0";\n' ,
'requires "AT_MPView" "RC 1";\n'
]
######################################################################
# Logging module detection
######################################################################
try:
#Custom Imports
import cgLogging
except ImportError:
WRITE_LOGS=False
######################################################################
# Main Script
######################################################################
PROJECT_PATH = PROJECT_PATH.replace("\\", "/")
def processMayaScene( maya_scene ):
"""This function removes unwanted requires from a Maya scene
Input:
maya_scene : str containing the full path to a Maya scene
Output:
"""
# I used to have folder ending with .ma ... so we perform a quick check to ensure this is a file.
if not os.path.isdir( maya_scene ):
#Don't bother with file permissions
os.chmod( maya_scene, 0o777 )
# Retrieves the NB_LINES_CHECK first lines of the scene
with open(maya_scene, "r", encoding="latin1") as input:
maya_scene_content = [next(input) for x in range(NB_LINES_CHECK)]
# Performs an intersect betweeen maya_scene_content and REQUIRES_LIST, if there isn't any match exit function
if len(set(maya_scene_content).intersection( REQUIRES_LIST ) ) == 0:
return maya_scene, None
removed_requires = []
#If there is any match, open scene in read mode and a buffer one in write mode
with open(maya_scene, 'r') as reader:
with open(maya_scene+'.tmp', 'w') as writer:
for line in reader:
if line not in REQUIRES_LIST:
writer.write( line )
else:
removed_requires.append(line)
# Let's be careful...
# http://stackoverflow.com/questions/7127075/what-exactly-the-pythons-file-flush-is-doing
writer.flush() # A remove?
os.fsync(writer.fileno())
# If everything is ok, replace original scene by buffer
os.remove(maya_scene)
# On Unix, if dst exists and is a file, it will be replaced silently if the user has permission.
# The operation may fail on some Unix flavors if src and dst are on different filesystems.
# If successful, the renaming will be an atomic operation (this is a POSIX requirement).
# On Windows, if dst already exists, OSError will be raised even if it is a file;
# there may be no way to implement an atomic rename when dst names an existing file.
# http://docs.python.org/library/os.html#os.rename
os.rename(maya_scene+'.tmp', maya_scene) # Non atomic operation (Windows Style)
return maya_scene, removed_requires
else:
return maya_scene, "Folder"
if __name__=='__main__':
# Start timer for logger
start_time = time.time()
if WRITE_LOGS:
if not os.path.exists( LOGS_FOLDER ):
os.makedirs( LOGS_FOLDER )
log = cgLogging.getLogger( "Results", shell=False, file=LOGS_FILE )
# Create the pool of workers
pool = Pool(processes=POOL_SIZE) # start 8 worker processes
# Assign a job for them
results = pool.imap(processMayaScene, \
glob.iglob( os.path.join(PROJECT_PATH, "**", "*.ma"), recursive=True), \
chunksize=CHUNK_SIZE)
#Printing and logging results
for maya_scene, removed_requires in results:
if removed_requires != None:
print(maya_scene)
if WRITE_LOGS: log.info("Cleaned: "+ maya_scene)
for require in removed_requires:
print("\t", require)
if WRITE_LOGS: log.info("\t " + require)
elif removed_requires == "Folder":
print("This is a folder:", maya_scene)
if WRITE_LOGS: log.info("This is a folder: "+ maya_scene)
print("Time : %s seconds" % (time.time() - start_time))
if WRITE_LOGS: log.info( "Time : %s seconds" % (time.time() - start_time) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment