Files
2025-09-29 00:52:08 +02:00

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()