Last active
January 10, 2023 02:18
-
-
Save DrHaze/b0e6a5fc1b4d8daa748448764e3e639a to your computer and use it in GitHub Desktop.
Remove useless requires on a bunch of Maya scenes
This file contains 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
# 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