192 lines
8.0 KiB
Python
Executable File
192 lines
8.0 KiB
Python
Executable File
import os
|
|
import sys
|
|
import time
|
|
import subprocess
|
|
import crapQueueTools
|
|
import crapLogger
|
|
|
|
# Import FileTools and XmlTools from the MB folder
|
|
drivePath = os.path.splitdrive(os.getcwd())[0] + os.path.sep
|
|
mbframeCapPath = os.path.join(drivePath, "wildwest", "dcc", "motionbuilder2014", "python",
|
|
"RS", "Core", "Automation", "FrameCapture")
|
|
sys.path.append(mbframeCapPath)
|
|
import CaptureModel as CaptureModel
|
|
import FileTools
|
|
import XmlTools
|
|
|
|
|
|
# Set Constants
|
|
NETWORKROOT = "N:" + os.path.sep
|
|
PROJECTNAME = os.environ.get('RS_PROJECT').upper()
|
|
CAPTUREROOT = os.path.join(NETWORKROOT, "RSGNYC", "Production", "CaptureRenders")
|
|
REFRESHTIME = 10
|
|
JOBTIMEOUT = 3600
|
|
|
|
|
|
def SyncPathFromP4(p4Path):
|
|
# Detect Folders and Update Path Accordingly
|
|
if p4Path.endswith("/"):
|
|
p4Path = p4Path[:-1]
|
|
if "." not in p4Path.split("/")[-1]:
|
|
p4Path += "/..."
|
|
|
|
# Run Terminal Sync Command
|
|
commandText = "p4 sync -f " + p4Path
|
|
proc = subprocess.Popen(commandText, stdout=subprocess.PIPE)
|
|
output, error = proc.communicate()
|
|
|
|
|
|
def ProcessExportJob(jobXmlPath):
|
|
|
|
# Create capObj Instance
|
|
capObj = CaptureModel.MobuCaptureModel(jobXmlPath)
|
|
capObj.UpdateTag("queueStartTime", str(os.path.getctime(jobXmlPath)))
|
|
capObj.UpdateTime("prepStartTime")
|
|
|
|
# Create Log
|
|
logPath = os.path.split(jobXmlPath)[0] + os.path.sep + "exportJob.ulog"
|
|
jobLog = crapLogger.Clog(capObj.projectName, logPath, appendToFile=False)
|
|
jobLog.LogMessage("Capture initialized and log created.")
|
|
|
|
# Set Standard Paths
|
|
capObj.UpdateTag("fbxPath", os.path.normpath(capObj.perforceFbxPath))
|
|
capObj.UpdateTag("fbxName", os.path.splitext(os.path.split(capObj.fbxPath)[1])[0].upper())
|
|
capObj.UpdateTag("p4FbxPath", ("/" + capObj.fbxPath.replace("\\", "/")[2:]).replace("//gta5/", "//depot/gta5/"))
|
|
capObj.UpdateTag("projectRoot", capObj.fbxPath.split("{0}{1}{0}".format(os.path.sep, "art"))[0])
|
|
capObj.UpdateTag("localCutsPath", os.path.join(capObj.projectRoot, "assets", "cuts", capObj.fbxName))
|
|
capObj.UpdateTag("perforceCutsPath",
|
|
"/".join([capObj.p4FbxPath.split("/art/")[0], "assets", "cuts", capObj.fbxName]))
|
|
capObj.UpdateTag("networkCutsPath",
|
|
os.path.join(CAPTUREROOT, "ExportQueue", capObj.projectName, "cuts", capObj.fbxName))
|
|
|
|
# Old Tags - need to get removed/updated (along with fixing perforceFbxPath)
|
|
capObj.UpdateTag("baseFolder", CAPTUREROOT + os.path.sep)
|
|
capObj.UpdateTag("exportDataFolder", os.path.join(capObj.projectRoot, "build", "dev", "preview") + os.path.sep)
|
|
capObj.UpdateTag("exportType", "Script Export")
|
|
capObj.UpdateTag("cutFolder", capObj.localCutsPath + os.path.sep)
|
|
|
|
# Sync / Setup Fbx and Cut Folders
|
|
jobLog.LogMessage("Capture Type: " + capObj.captureType)
|
|
if capObj.captureType != "FAST":
|
|
jobLog.LogMessage("Syncing FBX from perforce.")
|
|
SyncPathFromP4(capObj.p4FbxPath)
|
|
# SyncPathFromP4(capObj.perforceCutsPath)
|
|
else:
|
|
jobLog.LogMessage("Verifying FBX folder for fast cap.")
|
|
FileTools.CreateParentFolders(capObj.fbxPath)
|
|
|
|
# Sync Latest Plugins
|
|
jobLog.LogMessage("Syncing latest plugins from perforce.")
|
|
perforceProjectRoot = capObj.p4FbxPath.split("/art/")[0]
|
|
pluginsRoot = "/".join([perforceProjectRoot, "tools", "dcc", "current", "motionbuilder2014", "plugins", "x64"])
|
|
SyncPathFromP4("/".join([pluginsRoot, "3rdParty"]))
|
|
SyncPathFromP4("/".join([pluginsRoot, "expressions"]))
|
|
|
|
# Update mbStartTime and Status
|
|
jobLog.LogMessage("Opening Motionbuilder and launching MB script.")
|
|
capObj.UpdateTime("mbStartTime")
|
|
capObj.UpdateTag("status", "LOAD FBX")
|
|
|
|
# Open Up Motionbuilder and Run MB Script
|
|
mobuExePath = r'C:\Program Files\Autodesk\MotionBuilder 2014\bin\x64\motionbuilder.exe'
|
|
crapMbScriptPath = "X:\\wildwest\\script\\python\\standalone\\CaptureRender\\crapMBScript.py"
|
|
mbAppFolder = "C:\\Program Files\\Autodesk\\MotionBuilder 2014\\"
|
|
proc = subprocess.Popen('{0} -suspendMessages {1}'.format(mobuExePath, crapMbScriptPath), cwd=mbAppFolder)
|
|
|
|
# Read Status / Wait for Timeout
|
|
previousStatus = ""
|
|
while True:
|
|
status = XmlTools.ReadTagValueFromXmlPath(jobXmlPath, "status")
|
|
if status != previousStatus:
|
|
jobLog.LogMessage("MB Script Status: " + str(status))
|
|
previousStatus = status
|
|
if status == "EXPORT SUCCESS" or status.startswith("EXPORT ERROR"):
|
|
break
|
|
if (time.time() - os.path.getmtime(jobXmlPath)) > JOBTIMEOUT:
|
|
status = "EXPORT ERROR: Timeout during " + status.lower()
|
|
jobLog.LogMessage("MB Script Status: " + str(status))
|
|
break
|
|
time.sleep(5)
|
|
|
|
# Detect Export Data Actually Built
|
|
if (not os.path.exists(capObj.exportDataFolder)) or (
|
|
os.path.getmtime(capObj.exportDataFolder) < float(capObj.mbStartTime)):
|
|
status = "EXPORT ERROR: No export data built."
|
|
|
|
# Notify 'Operator' of Errors
|
|
if status.startswith("EXPORT ERROR"):
|
|
print "\n\n**** {} ****".format(status)
|
|
issueMessage = "Fix the issue, rebuild, and press enter to continue. Otherwise close this window to exit."
|
|
issuePause = raw_input(issueMessage + "\n")
|
|
jobLog.LogMessage("Continuing after build issue pause.")
|
|
|
|
# Create New capObj and Add exportFinishTime
|
|
capObj = CaptureModel.MobuCaptureModel(jobXmlPath)
|
|
capObj.UpdateTime("exportFinishTime")
|
|
|
|
# More Old Tags - can't wait to get rid of these
|
|
capObj.UpdateTag("exportStartRange", "0")
|
|
capObj.UpdateTag("exportEndRange", capObj.endFrame)
|
|
|
|
# Close Motionbuilder and Logs
|
|
jobLog.LogMessage("Closing MB, Logs, and Build Monitor.")
|
|
processList = ["motionbuilder.exe", "UniversalLogViewer.exe", "BuildMonitor.exe"]
|
|
for eachProcess in processList:
|
|
commandText = "taskkill /f /im " + eachProcess
|
|
proc = subprocess.Popen(commandText, shell=True, stdout=subprocess.PIPE)
|
|
time.sleep(5)
|
|
|
|
# Delete Previous Capture Jobs
|
|
jobLog.LogMessage("Deleting any matched capture job files.")
|
|
capQueueFolder = os.path.join(CAPTUREROOT, "CaptureQueue", capObj.projectName)
|
|
capJobXml = os.path.join(capQueueFolder, capObj.fbxName + ".xml")
|
|
capJobData = os.path.join(capQueueFolder, capObj.fbxName)
|
|
capCutData = os.path.join(capJobData, "cutData")
|
|
FileTools.DeletePath(capJobXml)
|
|
FileTools.DeletePath(capJobData)
|
|
|
|
# Copy Export Data Folder
|
|
jobLog.LogMessage("Copying export data to captureQueue.")
|
|
FileTools.CopyFolderContents(capObj.exportDataFolder, capJobData)
|
|
|
|
# Move TempCuts to Regular Cuts for Fast Caps
|
|
if capObj.captureType == "FAST":
|
|
cutsRoot = os.path.split(capObj.localCutsPath)[0]
|
|
tempCutFolder = os.path.join(cutsRoot, "tempCuts", capObj.fbxName)
|
|
FileTools.DeletePath(capObj.localCutsPath)
|
|
FileTools.CopyPath(tempCutFolder, cutsRoot)
|
|
|
|
# Copy Cut Folder
|
|
jobLog.LogMessage("Copying cut data to captureQueue.")
|
|
FileTools.CopyFolderContents(capObj.localCutsPath, capCutData)
|
|
|
|
# Copy Log File
|
|
jobLog.LogMessage("Copying log and xml file - job finished.")
|
|
FileTools.CopyPath(logPath, capJobData)
|
|
|
|
# Copy Xml File
|
|
FileTools.CopyPath(jobXmlPath, capQueueFolder)
|
|
|
|
|
|
def MonitorQueue():
|
|
queueFolder = os.path.join(CAPTUREROOT, "ExportQueue", PROJECTNAME)
|
|
QueueManager = crapQueueTools.QueueManager(queueFolder)
|
|
|
|
while True:
|
|
jobXmlPath = QueueManager.SearchForJobs()
|
|
|
|
# No Valid Jobs Found
|
|
if jobXmlPath is None:
|
|
print "\nNO QUEUE FILES FOUND"
|
|
print "WAITING {} SECONDS".format(str(REFRESHTIME))
|
|
time.sleep(REFRESHTIME)
|
|
continue
|
|
|
|
# Valid Job Found
|
|
print "\n\n==================================================="
|
|
print "NOW Exporting: " + os.path.split(jobXmlPath)[1]
|
|
print "==================================================="
|
|
ProcessExportJob(jobXmlPath)
|
|
|
|
|
|
MonitorQueue() |