Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! python 2.7
- """
- Copies all the textures which are not in the source images into the source images directory and sets the correct path on the
- file nodes.
- """
- import os
- import shutil
- import re
- from maya import cmds
- from maya.api import OpenMaya as om2
- from maya import OpenMayaUI as omui
- from PySide2.QtWidgets import QWidget, QPushButton, QProgressBar, QVBoxLayout, QMessageBox
- from PySide2.QtCore import Qt
- from shiboken2 import wrapInstance
- def mobFromName(name):
- """
- Gets a MObject from a Maya name
- :param name: [str], maya object name
- :return: [MObject]
- """
- sel = om2.MSelectionList()
- sel.add(name)
- mob = sel.getDependNode(0)
- return mob
- def getFileNodes():
- """
- Get all the fileTexture nodes in the scene
- :return: [MObject] the MObject of the file texture node
- """
- for mName in cmds.ls(dep = True):
- mob = mobFromName(mName)
- if mob.hasFn(om2.MFn.kFileTexture):
- yield mob
- def inSourceImages(path):
- """
- :param path: [string] path to be checked
- :return [boolean] if the path is in the project source images directory
- """
- sourcePath = os.path.join(cmds.workspace(q = True, rd = True), "sourceimages")
- if sourcePath in path:
- return True
- else:
- return False
- def getFileTextureData(mob):
- """
- :param [MObject] from which to get the file texture data
- :return [dict] containing colorSpace and uvTilingMode value
- """
- data = {}
- mfn_dep = om2.MFnDependencyNode(mob)
- colorSpace = mfn_dep.findPlug("colorSpace",False).asString()
- uvTilingMode = mfn_dep.findPlug("uvTilingMode",False).asInt()
- data["uvTilingMode"] = uvTilingMode
- data["colorSpace"] = colorSpace
- return data
- def iterUdimPaths(path):
- """
- :param path: [string] udim path
- :return [string] yield the udim file paths
- """
- raw_name = os.path.basename(path).split(".")[0]
- dirName = os.path.dirname(path)
- udimRegex = re.compile(raw_name + r'.(\d\d\d\d).(\w*)')
- for baseName in os.listdir(dirName):
- if udimRegex.search(baseName):
- yield os.path.join(dirName, baseName)
- def allocateFileJobs():
- """
- :return: [int] the amount of file nodes in the scene which have to be worked on
- """
- jobs = set()
- for i, mob in enumerate(getFileNodes()):
- mfn_dep = om2.MFnDependencyNode(mob)
- path = mfn_dep.findPlug("fileTextureName", False).asString()
- if not os.path.exists(path):
- continue
- if not inSourceImages(path):
- jobs.add(i)
- return len(jobs)
- def doIt(prgBar):
- """
- :param prgBar: [QProgressBar] to update the current status
- :return: [None]
- """
- jobs = {}
- for mob in getFileNodes():
- mfn_dep = om2.MFnDependencyNode(mob)
- path = mfn_dep.findPlug("fileTextureName",False).asString()
- if not os.path.exists(path):
- continue
- if not inSourceImages(path):
- jobs[path] = om2.MObjectHandle(mob)
- v = 1
- for path, handle in jobs.iteritems():
- mob = handle.object()
- data = getFileTextureData(mob)
- sourcePath = os.path.join(cmds.workspace(q = True, rd = True), "sourceimages")
- baseName = os.path.basename(path)
- if data["uvTilingMode"] == 3:
- for x in iterUdimPaths(path):
- shutil.copy(x, os.path.join(sourcePath, os.path.basename(x)))
- prgBar.setValue(v)
- else:
- shutil.copy(path, os.path.join(sourcePath, baseName))
- prgBar.setValue(v)
- v += 1
- # set the values back of the file texture node
- mfn_dep = om2.MFnDependencyNode(mob)
- mfn_dep.findPlug("fileTextureName", False).setString(os.path.join(sourcePath, baseName))
- mfn_dep.findPlug("colorSpace", False).setString(data["colorSpace"])
- mfn_dep.findPlug("uvTilingMode", False).setInt(data["uvTilingMode"])
- """
- UI
- """
- def getMayaWindow():
- mayaMainWindowPtr = omui.MQtUtil.mainWindow()
- return wrapInstance(long(mayaMainWindowPtr), QWidget)
- class Compiler(QWidget):
- def __init__(self, parent = None):
- super(Compiler, self).__init__(parent)
- self.setWindowTitle("Image Compiler 0.1")
- self.setWindowFlags(Qt.Window)
- layout = QVBoxLayout()
- btn = QPushButton("Compile")
- self.prgBar = QProgressBar()
- btn.clicked.connect(self.main)
- layout.addWidget(btn)
- layout.addWidget(self.prgBar)
- self.setMinimumWidth(280)
- self.setMaximumHeight(75)
- self.setLayout(layout)
- self.show()
- def main(self):
- qm = QMessageBox
- ret = qm.question(self, "Undoable action", "Action is undoable. Proceed anyways?")
- if ret == qm.No:
- return
- self.prgBar.setMaximum(allocateFileJobs())
- doIt(self.prgBar)
- QMessageBox.information(self, "Job done", "Successfully finished the job.")
- self.close()
- def main():
- window = Compiler(getMayaWindow())
- if __name__ == "__main__":
- main()
Add Comment
Please, Sign In to add comment