Guest User

Untitled

a guest
Mar 19th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.97 KB | None | 0 0
  1. #! python 2.7
  2.  
  3. """
  4. Copies all the textures which are not in the source images into the source images directory and sets the correct path on the
  5. file nodes.
  6. """
  7.  
  8. import os
  9. import shutil
  10. import re
  11.  
  12. from maya import cmds
  13. from maya.api import OpenMaya as om2
  14. from maya import OpenMayaUI as omui
  15.  
  16. from PySide2.QtWidgets import QWidget, QPushButton, QProgressBar, QVBoxLayout, QMessageBox
  17. from PySide2.QtCore import Qt
  18. from shiboken2 import wrapInstance
  19.  
  20.  
  21. def mobFromName(name):
  22.  
  23. """
  24. Gets a MObject from a Maya name
  25. :param name: [str], maya object name
  26. :return: [MObject]
  27. """
  28.  
  29. sel = om2.MSelectionList()
  30. sel.add(name)
  31. mob = sel.getDependNode(0)
  32. return mob
  33.  
  34.  
  35. def getFileNodes():
  36.  
  37. """
  38. Get all the fileTexture nodes in the scene
  39. :return: [MObject] the MObject of the file texture node
  40. """
  41.  
  42. for mName in cmds.ls(dep = True):
  43. mob = mobFromName(mName)
  44. if mob.hasFn(om2.MFn.kFileTexture):
  45. yield mob
  46.  
  47.  
  48. def inSourceImages(path):
  49.  
  50. """
  51. :param path: [string] path to be checked
  52. :return [boolean] if the path is in the project source images directory
  53. """
  54.  
  55. sourcePath = os.path.join(cmds.workspace(q = True, rd = True), "sourceimages")
  56. if sourcePath in path:
  57. return True
  58. else:
  59. return False
  60.  
  61.  
  62. def getFileTextureData(mob):
  63.  
  64. """
  65. :param [MObject] from which to get the file texture data
  66. :return [dict] containing colorSpace and uvTilingMode value
  67. """
  68.  
  69. data = {}
  70. mfn_dep = om2.MFnDependencyNode(mob)
  71. colorSpace = mfn_dep.findPlug("colorSpace",False).asString()
  72. uvTilingMode = mfn_dep.findPlug("uvTilingMode",False).asInt()
  73.  
  74. data["uvTilingMode"] = uvTilingMode
  75. data["colorSpace"] = colorSpace
  76. return data
  77.  
  78.  
  79. def iterUdimPaths(path):
  80.  
  81. """
  82. :param path: [string] udim path
  83. :return [string] yield the udim file paths
  84. """
  85.  
  86. raw_name = os.path.basename(path).split(".")[0]
  87. dirName = os.path.dirname(path)
  88. udimRegex = re.compile(raw_name + r'.(\d\d\d\d).(\w*)')
  89.  
  90. for baseName in os.listdir(dirName):
  91. if udimRegex.search(baseName):
  92. yield os.path.join(dirName, baseName)
  93.  
  94.  
  95. def allocateFileJobs():
  96.  
  97. """
  98. :return: [int] the amount of file nodes in the scene which have to be worked on
  99. """
  100.  
  101. jobs = set()
  102. for i, mob in enumerate(getFileNodes()):
  103. mfn_dep = om2.MFnDependencyNode(mob)
  104. path = mfn_dep.findPlug("fileTextureName", False).asString()
  105. if not os.path.exists(path):
  106. continue
  107. if not inSourceImages(path):
  108. jobs.add(i)
  109.  
  110. return len(jobs)
  111.  
  112.  
  113. def doIt(prgBar):
  114.  
  115. """
  116. :param prgBar: [QProgressBar] to update the current status
  117. :return: [None]
  118. """
  119.  
  120. jobs = {}
  121. for mob in getFileNodes():
  122. mfn_dep = om2.MFnDependencyNode(mob)
  123. path = mfn_dep.findPlug("fileTextureName",False).asString()
  124. if not os.path.exists(path):
  125. continue
  126. if not inSourceImages(path):
  127. jobs[path] = om2.MObjectHandle(mob)
  128.  
  129. v = 1
  130. for path, handle in jobs.iteritems():
  131.  
  132. mob = handle.object()
  133. data = getFileTextureData(mob)
  134.  
  135. sourcePath = os.path.join(cmds.workspace(q = True, rd = True), "sourceimages")
  136. baseName = os.path.basename(path)
  137.  
  138. if data["uvTilingMode"] == 3:
  139. for x in iterUdimPaths(path):
  140. shutil.copy(x, os.path.join(sourcePath, os.path.basename(x)))
  141. prgBar.setValue(v)
  142. else:
  143. shutil.copy(path, os.path.join(sourcePath, baseName))
  144. prgBar.setValue(v)
  145. v += 1
  146.  
  147. # set the values back of the file texture node
  148. mfn_dep = om2.MFnDependencyNode(mob)
  149. mfn_dep.findPlug("fileTextureName", False).setString(os.path.join(sourcePath, baseName))
  150. mfn_dep.findPlug("colorSpace", False).setString(data["colorSpace"])
  151. mfn_dep.findPlug("uvTilingMode", False).setInt(data["uvTilingMode"])
  152.  
  153. """
  154. UI
  155. """
  156.  
  157.  
  158. def getMayaWindow():
  159. mayaMainWindowPtr = omui.MQtUtil.mainWindow()
  160. return wrapInstance(long(mayaMainWindowPtr), QWidget)
  161.  
  162.  
  163. class Compiler(QWidget):
  164.  
  165. def __init__(self, parent = None):
  166. super(Compiler, self).__init__(parent)
  167.  
  168. self.setWindowTitle("Image Compiler 0.1")
  169. self.setWindowFlags(Qt.Window)
  170.  
  171. layout = QVBoxLayout()
  172.  
  173. btn = QPushButton("Compile")
  174. self.prgBar = QProgressBar()
  175.  
  176. btn.clicked.connect(self.main)
  177.  
  178. layout.addWidget(btn)
  179. layout.addWidget(self.prgBar)
  180.  
  181. self.setMinimumWidth(280)
  182. self.setMaximumHeight(75)
  183.  
  184. self.setLayout(layout)
  185. self.show()
  186.  
  187.  
  188. def main(self):
  189.  
  190. qm = QMessageBox
  191. ret = qm.question(self, "Undoable action", "Action is undoable. Proceed anyways?")
  192. if ret == qm.No:
  193. return
  194.  
  195. self.prgBar.setMaximum(allocateFileJobs())
  196. doIt(self.prgBar)
  197.  
  198. QMessageBox.information(self, "Job done", "Successfully finished the job.")
  199. self.close()
  200.  
  201.  
  202. def main():
  203. window = Compiler(getMayaWindow())
  204.  
  205. if __name__ == "__main__":
  206. main()
Add Comment
Please, Sign In to add comment