Update
This commit is contained in:
396
plug-ins/ARTv2/Core/Scripts/System/ART_FbxExport.py
Normal file
396
plug-ins/ARTv2/Core/Scripts/System/ART_FbxExport.py
Normal file
@@ -0,0 +1,396 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import maya.standalone as std
|
||||
import maya.cmds as cmds
|
||||
|
||||
|
||||
std.initialize(name='python')
|
||||
|
||||
# set up axis to z
|
||||
cmds.upAxis(ax='z')
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def fbx_export():
|
||||
|
||||
# log some basic info about incoming data
|
||||
sys.stdout.write("Opening File:\n")
|
||||
sys.stdout.write(str(sys.argv[1]))
|
||||
sys.stdout.write("Export Data File:\n\n")
|
||||
sys.stdout.write(str(sys.argv[2]))
|
||||
sys.stdout.write("\n\n")
|
||||
|
||||
# open the maya file
|
||||
cmds.file(str(sys.argv[1]), open=True, ignoreVersion=True, force=True, prompt=False)
|
||||
|
||||
# load data back into dict format
|
||||
f = open(str(sys.argv[2]), 'r')
|
||||
sys.stdout.write(str(f))
|
||||
data = json.load(f)
|
||||
f.close()
|
||||
|
||||
# the data is a dictionary of characters and their export information. That data might look like:
|
||||
# character: [[seq1 data], [seq2 data]]
|
||||
# we need to go through each character's data, go through each sequence, and export that sequence out
|
||||
for character in data:
|
||||
sequences = data.get(character)
|
||||
sys.stdout.write("\n\n")
|
||||
sys.stdout.write(str(sequences))
|
||||
sys.stdout.write("\n")
|
||||
sys.stdout.write(str(len(sequences)))
|
||||
sys.stdout.write("\n")
|
||||
|
||||
# sequence data as follows [0-6]:
|
||||
# Export Meshes? Export Morphs? Export Attrs? Which Morphs? Which Attrs? Pre Script? Path? Post Script? Path?
|
||||
# Sequence data [7] as follows:
|
||||
# [character, export?, fbxPath, start, end, fps, rotation interp, sample rate, root export]
|
||||
|
||||
# loop through each sequence in the sequence data
|
||||
for sequence in sequences:
|
||||
exportMesh = sequence[0]
|
||||
exportMorphs = sequence[1]
|
||||
exportAttrs = sequence[2]
|
||||
morphTargets = sequence[3]
|
||||
customAttrs = sequence[4]
|
||||
preScript = sequence[5]
|
||||
postScript = sequence[6]
|
||||
sequenceInfo = sequence[7]
|
||||
|
||||
# PRE-SCRIPT
|
||||
if preScript[0]:
|
||||
sys.stdout.write("\nExecuting Pre-Script...\n")
|
||||
status = executeScript(preScript[1])
|
||||
|
||||
if status:
|
||||
sys.stdout.write("\nPre-Script successfully executed!\n")
|
||||
else:
|
||||
sys.stdout.write("\nPre-Script NOT successfully executed :( \n")
|
||||
|
||||
# if this sequence is marked for export
|
||||
if sequenceInfo[1] == True:
|
||||
|
||||
euler = False
|
||||
quat = True
|
||||
|
||||
# get the outputPath
|
||||
filePath = sequenceInfo[2]
|
||||
|
||||
# get the start and end frame
|
||||
startFrame = sequenceInfo[3]
|
||||
endFrame = sequenceInfo[4]
|
||||
|
||||
# get the fps
|
||||
fps = sequenceInfo[5]
|
||||
sys.stdout.write("\n\n" + str(fps) + "\n\n")
|
||||
cmds.currentUnit(time=str(fps))
|
||||
cmds.refresh()
|
||||
|
||||
# get the rotation interpolation
|
||||
interp = sequenceInfo[6]
|
||||
if interp == "Quaternion Slerp":
|
||||
euler = False
|
||||
quat = True
|
||||
if interp == "Independent Euler-Angle":
|
||||
euler = True
|
||||
quat = False
|
||||
|
||||
# set the fbx export flags
|
||||
setExportFlags(startFrame, endFrame, euler, quat)
|
||||
|
||||
# get the sample rate
|
||||
sample = sequenceInfo[7]
|
||||
|
||||
# get the root export option
|
||||
rootExport = sequenceInfo[8]
|
||||
|
||||
# build selection of what to export
|
||||
toExport = []
|
||||
|
||||
# EXPORT MESHES
|
||||
if exportMesh:
|
||||
# get meshes
|
||||
if cmds.objExists(character + ":ART_RIG_ROOT"):
|
||||
if cmds.objExists(character + ":ART_RIG_ROOT.LOD_0_Meshes"):
|
||||
meshes = cmds.listConnections(character + ":ART_RIG_ROOT.LOD_0_Meshes")
|
||||
|
||||
for mesh in meshes:
|
||||
toExport.append(mesh)
|
||||
|
||||
# EXPORT MORPHS
|
||||
if exportMorphs:
|
||||
for each in morphTargets:
|
||||
if cmds.objExists(each):
|
||||
if (each.partition(":")[0]) == character:
|
||||
conns = cmds.listConnections(each, type="mesh")
|
||||
if conns is not None:
|
||||
toExport.extend(conns)
|
||||
|
||||
# SKELETON
|
||||
skeleton = [character + ":root"]
|
||||
skeleton.extend(reversed(cmds.listRelatives(character + ":root", type='joint', allDescendents=True)))
|
||||
toExport.append(skeleton[0])
|
||||
|
||||
# bake skeleton and blendshapes (using sample rate)
|
||||
cmds.select(skeleton)
|
||||
if exportMorphs:
|
||||
cmds.select(morphTargets, add=True)
|
||||
|
||||
# bake down animation onto skeleton and blendshapes
|
||||
cmds.bakeResults(simulation=True, sb=sample, time=(startFrame, endFrame))
|
||||
|
||||
# run euler filter and fix tangents
|
||||
cmds.select(skeleton)
|
||||
cmds.filterCurve()
|
||||
cmds.selectKey()
|
||||
cmds.keyTangent(itt="linear", ott="linear")
|
||||
|
||||
# deal with custom attrs (deleting if user chose not to export)
|
||||
standardAttrs = ["translateX", "translateY", "translateZ", "rotateX", "rotateY", "rotateZ",
|
||||
"scaleX", "scaleY", "scaleZ", "visibility"]
|
||||
if exportAttrs:
|
||||
available_attrs = cmds.listAttr(skeleton[0], keyable=True)
|
||||
for attr in available_attrs:
|
||||
if attr not in standardAttrs:
|
||||
if (character + ":" + attr) not in customAttrs:
|
||||
sys.stdout.write("\n\n")
|
||||
sys.stdout.write("Removing Attr:")
|
||||
sys.stdout.write(str(attr))
|
||||
sys.stdout.write("\n\n")
|
||||
|
||||
# remove the attribute from the root
|
||||
cmds.deleteAttr(skeleton[0], at=attr)
|
||||
|
||||
# Root Export Options
|
||||
sys.stdout.write("\n\n" + str(rootExport) + "\n\n")
|
||||
if rootExport != "Export Root Animation":
|
||||
if rootExport == "Zero Root":
|
||||
sys.stdout.write("\nZeroing Out Root Animation\n")
|
||||
cmds.cutKey(skeleton[0])
|
||||
attrs = ["translate", "rotate", "scale"]
|
||||
for attr in attrs:
|
||||
try:
|
||||
cmds.disconnectAttr(character + ":driver_root." + attr, character + ":root." + attr)
|
||||
except Exception as e:
|
||||
sys.stdout.write("\n" + str(e) + "\n")
|
||||
|
||||
for zeroAttr in [".tx", ".ty", ".tz", ".rx", ".ry", ".rz"]:
|
||||
cmds.setAttr(character + ":root" + zeroAttr, 0)
|
||||
|
||||
if rootExport == "Zero Root, Keep World Space":
|
||||
sys.stdout.write("\nZeroing Out Root Animation, Keeping World Space on rest of rig\n")
|
||||
# first, find children that need to be locked in place and create a locator for each
|
||||
rootConnections = cmds.listRelatives(skeleton[0], children=True, type="joint")
|
||||
lockNodes = []
|
||||
locators = []
|
||||
|
||||
for conn in rootConnections:
|
||||
lockNodes.append(conn)
|
||||
constraints = []
|
||||
|
||||
for lockNode in lockNodes:
|
||||
loc = cmds.spaceLocator(name=lockNode + "_loc")[0]
|
||||
locators.append(loc)
|
||||
constraint = cmds.parentConstraint(lockNode, loc)[0]
|
||||
constraints.append(constraint)
|
||||
|
||||
sys.stdout.write("Locking down " + lockNode + " to zero out root.")
|
||||
sys.stdout.write("\n")
|
||||
|
||||
# then bake the locators
|
||||
cmds.select(clear=True)
|
||||
for lockNode in lockNodes:
|
||||
cmds.select(lockNode + "_loc", add=True)
|
||||
|
||||
cmds.bakeResults(simulation=True, sb=sample, time=(float(startFrame), float(endFrame)))
|
||||
cmds.delete(constraints)
|
||||
|
||||
# reverse the constraints so the bones are constrained to the locator
|
||||
boneConstraints = []
|
||||
for lockNode in lockNodes:
|
||||
con = cmds.parentConstraint(lockNode + "_loc", lockNode)[0]
|
||||
boneConstraints.append(con)
|
||||
|
||||
# disconnect attrs on root bone
|
||||
attrs = ["translate", "rotate", "scale"]
|
||||
for attr in attrs:
|
||||
try:
|
||||
cmds.disconnectAttr(character + ":driver_root." + attr, character + ":root." + attr)
|
||||
except Exception as e:
|
||||
sys.stdout.write("\n" + str(e) + "\n")
|
||||
|
||||
# cut keys on the root bone
|
||||
cmds.cutKey(skeleton[0])
|
||||
cmds.setAttr(skeleton[0] + ".tx", 0)
|
||||
cmds.setAttr(skeleton[0] + ".ty", 0)
|
||||
cmds.setAttr(skeleton[0] + ".tz", 0)
|
||||
cmds.setAttr(skeleton[0] + ".rx", 0)
|
||||
cmds.setAttr(skeleton[0] + ".ry", 0)
|
||||
cmds.setAttr(skeleton[0] + ".rz", 0)
|
||||
|
||||
# bake bones now in world space
|
||||
cmds.select(clear=True)
|
||||
for lockNode in lockNodes:
|
||||
cmds.select(lockNode, add=True)
|
||||
|
||||
cmds.bakeResults(simulation=True, sb=sample, time=(float(startFrame), float(endFrame)))
|
||||
cmds.delete(boneConstraints)
|
||||
|
||||
# run an euler filter
|
||||
cmds.select(skeleton)
|
||||
cmds.filterCurve()
|
||||
|
||||
# POST - SCRIPT
|
||||
if postScript[0]:
|
||||
sys.stdout.write("\nExecuting Post Script...\n")
|
||||
|
||||
status = executeScript(postScript[1])
|
||||
|
||||
if status:
|
||||
sys.stdout.write("\nPost-Script successfully executed!\n")
|
||||
else:
|
||||
sys.stdout.write("\nPost-Script NOT successfully executed :( \n")
|
||||
|
||||
# EXPORT FBX
|
||||
cmds.select(toExport)
|
||||
|
||||
try:
|
||||
mel.eval("FBXExport -f \"" + filePath + "\" -s")
|
||||
except:
|
||||
cmds.warning("no path specified..")
|
||||
|
||||
# close mayapy
|
||||
os.remove(str(sys.argv[2]))
|
||||
std.uninitialize()
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def setExportFlags(startFrame, endFrame, euler=False, quat=True):
|
||||
|
||||
# in 2015, if oneClick isn't loaded, it will throw up an error
|
||||
try:
|
||||
cmds.loadPlugin("OneClick.mll")
|
||||
sys.stdout.write("Loaded OneClick plugin.")
|
||||
sys.stdout.write("\n")
|
||||
except Exception as e:
|
||||
sys.stderr.write("unable to load OneClick plugin.")
|
||||
sys.stderr.write("\n")
|
||||
|
||||
try:
|
||||
cmds.loadPlugin("fbxmaya.mll")
|
||||
sys.stdout.write("Loaded FBX plugin.")
|
||||
sys.stdout.write("\n")
|
||||
except Exception as e:
|
||||
sys.stderr.write("unable to load FBX plugin.")
|
||||
sys.stderr.write("\n")
|
||||
|
||||
# Mesh
|
||||
mel.eval("FBXExportSmoothingGroups -v true")
|
||||
mel.eval("FBXExportHardEdges -v false")
|
||||
mel.eval("FBXExportTangents -v false")
|
||||
mel.eval("FBXExportInstances -v false")
|
||||
mel.eval("FBXExportInAscii -v true")
|
||||
mel.eval("FBXExportSmoothMesh -v false")
|
||||
|
||||
# Animation
|
||||
mel.eval("FBXExportBakeComplexAnimation -v true")
|
||||
mel.eval("FBXExportBakeComplexStart -v " + str(startFrame))
|
||||
mel.eval("FBXExportBakeComplexEnd -v " + str(endFrame))
|
||||
mel.eval("FBXExportReferencedAssetsContent -v true")
|
||||
mel.eval("FBXExportBakeComplexStep -v 1")
|
||||
mel.eval("FBXExportUseSceneName -v false")
|
||||
mel.eval("FBXExportFileVersion -v FBX201400")
|
||||
|
||||
if euler:
|
||||
mel.eval("FBXExportQuaternion -v euler")
|
||||
|
||||
if quat:
|
||||
mel.eval("FBXExportQuaternion -v quaternion")
|
||||
|
||||
mel.eval("FBXExportShapes -v true")
|
||||
mel.eval("FBXExportSkins -v true")
|
||||
mel.eval("FBXExportUpAxis z")
|
||||
|
||||
# garbage we don't want
|
||||
# Constraints
|
||||
mel.eval("FBXExportConstraints -v false")
|
||||
|
||||
# Cameras
|
||||
mel.eval("FBXExportCameras -v false")
|
||||
|
||||
# Lights
|
||||
mel.eval("FBXExportLights -v false")
|
||||
|
||||
# Embed Media
|
||||
mel.eval("FBXExportEmbeddedTextures -v false")
|
||||
|
||||
# Connections
|
||||
mel.eval("FBXExportInputConnections -v false")
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
def executeScript(scriptPath):
|
||||
|
||||
sourceType = ""
|
||||
status = False
|
||||
|
||||
if scriptPath.find(".py") != -1:
|
||||
sourceType = "python"
|
||||
|
||||
if scriptPath.find(".mel") != -1:
|
||||
sourceType = "mel"
|
||||
|
||||
# MEL
|
||||
if sourceType == "mel":
|
||||
try:
|
||||
command = ""
|
||||
# open the file, and for each line in the file, add it to our command string.
|
||||
f = open(scriptPath, 'r')
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
command += line
|
||||
|
||||
import maya.mel as mel
|
||||
mel.eval(command)
|
||||
|
||||
# save the file
|
||||
cmds.file(save=True, type="mayaAscii")
|
||||
status = True
|
||||
except:
|
||||
pass
|
||||
|
||||
# PYTHON
|
||||
if sourceType == "python":
|
||||
try:
|
||||
# Python 2/3 compatible way to execute a file
|
||||
with open(scriptPath, 'r') as f:
|
||||
exec(f.read())
|
||||
|
||||
# save the file
|
||||
cmds.file(save=True, type="mayaAscii")
|
||||
status = True
|
||||
except:
|
||||
pass
|
||||
|
||||
return status
|
||||
|
||||
|
||||
fbx_export()
|
||||
246
plug-ins/ARTv2/Core/Scripts/System/ART_Reporter.py
Normal file
246
plug-ins/ARTv2/Core/Scripts/System/ART_Reporter.py
Normal file
@@ -0,0 +1,246 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from ThirdParty.Qt import QtGui, QtCore, QtWidgets
|
||||
import importlib
|
||||
import maya.cmds as cmds
|
||||
import utils
|
||||
import System.interfaceUtils as interfaceUtils
|
||||
import System.git_utils as git
|
||||
importlib.reload(git)
|
||||
|
||||
|
||||
|
||||
windowTitle = "ARTv2: Report an Issue"
|
||||
windowObject = "pyArtReporterWin"
|
||||
|
||||
|
||||
class ART_Reporter(QtWidgets.QMainWindow):
|
||||
|
||||
def __init__(self, parent = None):
|
||||
|
||||
super(ART_Reporter, self).__init__(parent)
|
||||
|
||||
#get the directory path of the tools
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
self.toolsPath = settings.value("toolsPath")
|
||||
self.iconsPath = settings.value("iconPath")
|
||||
self.scriptPath = settings.value("scriptPath")
|
||||
self.projPath = settings.value("projectPath")
|
||||
|
||||
|
||||
#build the UI
|
||||
self.buildSettingsUi()
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def buildSettingsUi(self):
|
||||
|
||||
#fonts
|
||||
self.font = QtGui.QFont()
|
||||
self.font.setPointSize(10)
|
||||
self.font.setBold(False)
|
||||
|
||||
self.fontSmall = QtGui.QFont()
|
||||
self.fontSmall .setPointSize(9)
|
||||
self.fontSmall .setBold(False)
|
||||
|
||||
self.titleFont = QtGui.QFont()
|
||||
self.titleFont.setPointSize(40)
|
||||
self.titleFont.setBold(True)
|
||||
|
||||
|
||||
#load stylesheet
|
||||
styleSheetFile = utils.returnNicePath(self.toolsPath, "Core/Scripts/Interfaces/StyleSheets/mainScheme.qss")
|
||||
f = open(styleSheetFile, "r")
|
||||
self.style = f.read()
|
||||
f.close()
|
||||
|
||||
|
||||
self.setStyleSheet(self.style)
|
||||
|
||||
#size policies
|
||||
mainSizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
|
||||
#create the main widget
|
||||
self.mainWidget = QtWidgets.QWidget()
|
||||
self.mainWidget.setStyleSheet(self.style)
|
||||
self.mainWidget.setStyleSheet("background-color: rgb(0, 0, 0);, color: rgb(0,0,0);")
|
||||
self.setCentralWidget(self.mainWidget)
|
||||
|
||||
#set qt object name
|
||||
self.setObjectName(windowObject)
|
||||
self.setWindowTitle(windowTitle)
|
||||
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||
|
||||
#create the mainLayout for the rig creator UI
|
||||
self.layout = QtWidgets.QVBoxLayout(self.mainWidget)
|
||||
|
||||
self.resize(300, 600)
|
||||
self.setSizePolicy(mainSizePolicy)
|
||||
self.setMinimumSize(QtCore.QSize( 300, 600 ))
|
||||
self.setMaximumSize(QtCore.QSize( 300, 600 ))
|
||||
|
||||
#create the QFrame
|
||||
self.frame = QtWidgets.QFrame()
|
||||
self.frame.setObjectName("epic")
|
||||
self.layout.addWidget(self.frame)
|
||||
self.widgetLayout = QtWidgets.QVBoxLayout(self.frame)
|
||||
|
||||
|
||||
#Title of Issue
|
||||
self.titleLayout = QtWidgets.QHBoxLayout()
|
||||
self.widgetLayout.addLayout(self.titleLayout)
|
||||
|
||||
titleLabel = QtWidgets.QLabel("Title: ")
|
||||
self.titleLayout.addWidget(titleLabel)
|
||||
|
||||
self.issueTitle = QtWidgets.QLineEdit()
|
||||
self.issueTitle.setPlaceholderText("Title of Issue")
|
||||
self.titleLayout.addWidget(self.issueTitle)
|
||||
self.issueTitle.setMinimumWidth(200)
|
||||
self.issueTitle.setMaximumWidth(200)
|
||||
|
||||
#Type of Issue (from labels)
|
||||
self.labelLayout = QtWidgets.QHBoxLayout()
|
||||
self.widgetLayout.addLayout(self.labelLayout)
|
||||
|
||||
typeLabel = QtWidgets.QLabel("Issue Type: ")
|
||||
self.labelLayout.addWidget(typeLabel)
|
||||
|
||||
self.issueType = QtWidgets.QComboBox()
|
||||
self.labelLayout.addWidget(self.issueType)
|
||||
self.issueType.setMinimumWidth(200)
|
||||
self.issueType.setMaximumWidth(200)
|
||||
|
||||
|
||||
|
||||
#Information
|
||||
summaryLabel = QtWidgets.QLabel("Summary: ")
|
||||
self.widgetLayout.addWidget(summaryLabel)
|
||||
|
||||
infoText = QtWidgets.QTextEdit()
|
||||
infoText.setReadOnly(True)
|
||||
infoText.setEnabled(False)
|
||||
self.widgetLayout.addWidget(infoText)
|
||||
infoText.setMinimumHeight(60)
|
||||
infoText.setMaximumHeight(60)
|
||||
infoText.setTextColor(QtGui.QColor(120,120,120))
|
||||
infoText.append("(Please include any errors and stacktrace if applicable. Also include any reproduction steps if possible.)")
|
||||
|
||||
self.issueInfo = QtWidgets.QTextEdit()
|
||||
self.widgetLayout.addWidget(self.issueInfo)
|
||||
self.issueInfo.setObjectName("light")
|
||||
#Create Issue
|
||||
self.createIssueBtn = QtWidgets.QPushButton("Create Issue")
|
||||
self.createIssueBtn.setObjectName("blueButton")
|
||||
self.widgetLayout.addWidget(self.createIssueBtn)
|
||||
self.createIssueBtn.clicked.connect(self.createIssue)
|
||||
|
||||
self.credentials = git.getGitCreds()
|
||||
if self.credentials == None:
|
||||
git.gitCredsUI(self)
|
||||
self.credentials = git.getGitCreds()
|
||||
|
||||
self.getLabels()
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def getLabels(self):
|
||||
|
||||
labels = self.githubInfo("label")
|
||||
ignoreLabel = ["wontfix", "duplicate", "invalid"]
|
||||
if labels != None:
|
||||
for label in labels:
|
||||
if label.name not in ignoreLabel:
|
||||
self.issueType.addItem(label.name)
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def createIssue(self):
|
||||
|
||||
title = self.issueTitle.text()
|
||||
issueType = self.issueType.currentText()
|
||||
|
||||
body = "User: " + str(self.credentials[0]) + "\n"
|
||||
body += "Maya Version: " + str(cmds.about(iv = True)) + "\n"
|
||||
body += "OS: " + str(cmds.about(os = True)) + "\n" + "\n"
|
||||
body += self.issueInfo.toPlainText()
|
||||
|
||||
repo = self.githubInfo("repo")
|
||||
issueCreated = False
|
||||
try:
|
||||
issue = repo.create_issue(title, body)
|
||||
issue.set_labels(issueType)
|
||||
issueCreated = True
|
||||
|
||||
except Exception as e:
|
||||
cmds.warning(f"unable to create issue. Error: {str(e)}")
|
||||
self.close()
|
||||
return
|
||||
|
||||
if issueCreated:
|
||||
msgBox = QtWidgets.QMessageBox()
|
||||
msgBox.setText("Your issue has been created")
|
||||
msgBox.setDetailedText("To view your issue, please visit:\nhttps://github.com/epicernst/Test/issues")
|
||||
ret = msgBox.exec_()
|
||||
self.close()
|
||||
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def githubInfo(self, type):
|
||||
|
||||
#github section
|
||||
# try:
|
||||
from ThirdParty.github import Github
|
||||
# except:
|
||||
# cmds.warning("unable to import github module. You will not be able to create an issue")
|
||||
# self.close()
|
||||
# return
|
||||
|
||||
repoOwner = "epicernst"
|
||||
try:
|
||||
g = Github(self.credentials[0], self.credentials[1])
|
||||
repo = g.get_user(repoOwner).get_repo("Test")
|
||||
labels = repo.get_labels()
|
||||
|
||||
if type == "repo":
|
||||
return repo
|
||||
if type == "label":
|
||||
return labels
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def run():
|
||||
|
||||
if cmds.window("pyArtReporterWin", exists = True):
|
||||
cmds.deleteUI("pyArtReporterWin", wnd = True)
|
||||
|
||||
gui = ART_Reporter(interfaceUtils.getMainWindow())
|
||||
gui.show()
|
||||
3022
plug-ins/ARTv2/Core/Scripts/System/ART_RigModule.py
Normal file
3022
plug-ins/ARTv2/Core/Scripts/System/ART_RigModule.py
Normal file
File diff suppressed because it is too large
Load Diff
292
plug-ins/ARTv2/Core/Scripts/System/ART_Settings.py
Normal file
292
plug-ins/ARTv2/Core/Scripts/System/ART_Settings.py
Normal file
@@ -0,0 +1,292 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from ThirdParty.Qt import QtGui, QtCore, QtWidgets, QtCompat
|
||||
|
||||
# Use shiboken from Qt.py for compatibility
|
||||
from functools import partial
|
||||
import maya.cmds as cmds
|
||||
import os, json
|
||||
import System.utils as utils
|
||||
|
||||
|
||||
|
||||
|
||||
def getMainWindow():
|
||||
import maya.OpenMayaUI as mui
|
||||
pointer = mui.MQtUtil.mainWindow()
|
||||
#pyside QMainWindow takes in a QWidget rather than QObject
|
||||
return QtCompat.wrapInstance(int(pointer), QtWidgets.QWidget)
|
||||
|
||||
|
||||
|
||||
windowTitle = "ART_Settings"
|
||||
windowObject = "pyArtSettingsWin"
|
||||
|
||||
|
||||
|
||||
class ART_Settings(QtWidgets.QMainWindow):
|
||||
|
||||
def __init__(self, parent = None):
|
||||
|
||||
super(ART_Settings, self).__init__(parent)
|
||||
|
||||
#get the directory path of the tools
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
self.toolsPath = settings.value("toolsPath")
|
||||
self.scriptPath = settings.value("scriptPath")
|
||||
self.iconsPath = settings.value("iconPath")
|
||||
self.projPath = settings.value("projectPath")
|
||||
|
||||
#build the UI
|
||||
self.buildSettingsUi()
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def buildSettingsUi(self):
|
||||
|
||||
#fonts
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(True)
|
||||
|
||||
fontSmall = QtGui.QFont()
|
||||
fontSmall.setPointSize(9)
|
||||
fontSmall.setBold(True)
|
||||
|
||||
|
||||
#images
|
||||
frameBackground = os.path.normcase(os.path.join(self.iconsPath, "System/field_background.png"))
|
||||
if frameBackground.partition("\\")[2] != "":
|
||||
frameBackground = frameBackground.replace("\\", "/")
|
||||
|
||||
imageBkgrd = os.path.normcase(os.path.join(self.iconsPath, "System/toolbar_background.png"))
|
||||
if imageBkgrd.partition("\\")[2] != "":
|
||||
imageBkgrd = imageBkgrd.replace("\\", "/")
|
||||
|
||||
imageBtnBkrd = os.path.normcase(os.path.join(self.iconsPath, "System/blue_field_background.png"))
|
||||
if imageBtnBkrd.partition("\\")[2] != "":
|
||||
imageBtnBkrd = imageBtnBkrd.replace("\\", "/")
|
||||
|
||||
|
||||
|
||||
#size policies
|
||||
mainSizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
|
||||
#create the main widget
|
||||
self.mainWidget = QtWidgets.QWidget()
|
||||
self.mainWidget.setStyleSheet("background-color: rgb(0, 0, 0);, color: rgb(0,0,0);")
|
||||
self.setCentralWidget(self.mainWidget)
|
||||
|
||||
#set qt object name
|
||||
self.setObjectName(windowObject)
|
||||
self.setWindowTitle(windowTitle)
|
||||
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||
|
||||
#create the mainLayout for the rig creator UI
|
||||
self.layout = QtWidgets.QVBoxLayout(self.mainWidget)
|
||||
|
||||
self.resize(600, 260)
|
||||
self.setSizePolicy(mainSizePolicy)
|
||||
self.setMinimumSize(QtCore.QSize( 600, 260 ))
|
||||
self.setMaximumSize(QtCore.QSize( 600, 260 ))
|
||||
|
||||
#create the QFrame
|
||||
self.frame = QtWidgets.QFrame()
|
||||
self.layout.addWidget(self.frame)
|
||||
self.widgetLayout = QtWidgets.QVBoxLayout(self.frame)
|
||||
|
||||
#info page styling
|
||||
self.frame.setStyleSheet("background-image: url(" + imageBkgrd + ");")
|
||||
|
||||
|
||||
#MayaTools/Core : Sccipts, icons, jointmover, etc
|
||||
#MayaTools/Projects: actual project files (animation rigs, thumbnails, poses, etc)
|
||||
|
||||
#location
|
||||
self.locationLayout = QtWidgets.QHBoxLayout()
|
||||
self.widgetLayout.addLayout(self.locationLayout)
|
||||
|
||||
#location -> label
|
||||
label = QtWidgets.QLabel("Tools Location: ")
|
||||
self.locationLayout.addWidget(label)
|
||||
label.setFont(font)
|
||||
label.setMinimumWidth(150)
|
||||
|
||||
#location -> line edit
|
||||
path = utils.returnFriendlyPath(self.toolsPath)
|
||||
self.locationPath = QtWidgets.QLineEdit(path)
|
||||
self.locationLayout.addWidget(self.locationPath)
|
||||
|
||||
|
||||
|
||||
self.locationPath.setStyleSheet("background-image: url(" + frameBackground + "); background-color: rgb(25,175,255);")
|
||||
self.locationPath.setMinimumHeight(35)
|
||||
|
||||
#location -> browse button
|
||||
self.locationBrowse = QtWidgets.QPushButton()
|
||||
self.locationLayout.addWidget(self.locationBrowse)
|
||||
|
||||
self.locationBrowse.setMinimumSize(35,35)
|
||||
self.locationBrowse.setMaximumSize(35, 35)
|
||||
btnBackground = utils.returnNicePath(self.iconsPath, "System/fileBrowse.png")
|
||||
self.locationBrowse.setStyleSheet("background-image: url(" + btnBackground + ");")
|
||||
self.locationBrowse.clicked.connect(partial(self.browse, self.locationPath))
|
||||
|
||||
|
||||
#scripts folder
|
||||
self.scriptsLayout = QtWidgets.QHBoxLayout()
|
||||
self.widgetLayout.addLayout(self.scriptsLayout)
|
||||
|
||||
#scripts -> label
|
||||
label = QtWidgets.QLabel("Scripts: ")
|
||||
self.scriptsLayout.addWidget(label)
|
||||
label.setFont(fontSmall)
|
||||
label.setMinimumWidth(150)
|
||||
|
||||
#scripts -> line edit
|
||||
path = utils.returnFriendlyPath(self.scriptPath)
|
||||
self.scriptsPath = QtWidgets.QLineEdit(path)
|
||||
self.scriptsLayout.addWidget(self.scriptsPath)
|
||||
|
||||
self.scriptsPath.setStyleSheet("background-image: url(" + frameBackground + "); background-color: rgb(25,175,255);")
|
||||
self.scriptsPath.setMinimumHeight(35)
|
||||
|
||||
#scripts -> browse button
|
||||
self.scriptsBrowse = QtWidgets.QPushButton()
|
||||
self.scriptsLayout.addWidget(self.scriptsBrowse)
|
||||
|
||||
self.scriptsBrowse.setMinimumSize(35,35)
|
||||
self.scriptsBrowse.setMaximumSize(35, 35)
|
||||
self.scriptsBrowse.setStyleSheet("background-image: url(" + btnBackground + ");")
|
||||
self.scriptsBrowse.clicked.connect(partial(self.browse, self.scriptsPath))
|
||||
|
||||
#icons folder
|
||||
self.iconsLayout = QtWidgets.QHBoxLayout()
|
||||
self.widgetLayout.addLayout(self.iconsLayout)
|
||||
|
||||
#icons -> label
|
||||
label = QtWidgets.QLabel("Icons: ")
|
||||
self.iconsLayout.addWidget(label)
|
||||
label.setFont(fontSmall)
|
||||
label.setMinimumWidth(150)
|
||||
|
||||
#icons -> line edit
|
||||
path = utils.returnFriendlyPath(self.iconsPath)
|
||||
self.iconPath = QtWidgets.QLineEdit(path)
|
||||
self.iconsLayout.addWidget(self.iconPath)
|
||||
|
||||
self.iconPath.setStyleSheet("background-image: url(" + frameBackground + "); background-color: rgb(25,175,255);")
|
||||
self.iconPath.setMinimumHeight(35)
|
||||
|
||||
#icons -> browse button
|
||||
self.iconsBrowse = QtWidgets.QPushButton()
|
||||
self.iconsLayout.addWidget(self.iconsBrowse)
|
||||
|
||||
self.iconsBrowse.setMinimumSize(35,35)
|
||||
self.iconsBrowse.setMaximumSize(35, 35)
|
||||
self.iconsBrowse.setStyleSheet("background-image: url(" + btnBackground + ");")
|
||||
self.iconsBrowse.clicked.connect(partial(self.browse, self.iconsPath))
|
||||
|
||||
#projects folder
|
||||
self.projectsLayout = QtWidgets.QHBoxLayout()
|
||||
self.widgetLayout.addLayout(self.projectsLayout)
|
||||
|
||||
#projects -> label
|
||||
label = QtWidgets.QLabel("Projects: ")
|
||||
self.projectsLayout.addWidget(label)
|
||||
label.setFont(fontSmall)
|
||||
label.setMinimumWidth(150)
|
||||
|
||||
#projects -> line edit
|
||||
path = utils.returnFriendlyPath(self.projPath)
|
||||
self.projectsPath = QtWidgets.QLineEdit(path)
|
||||
self.projectsLayout.addWidget(self.projectsPath)
|
||||
|
||||
self.projectsPath.setStyleSheet("background-image: url(" + frameBackground + "); background-color: rgb(25,175,255);")
|
||||
self.projectsPath.setMinimumHeight(35)
|
||||
|
||||
#projects -> browse button
|
||||
self.projectsBrowse = QtWidgets.QPushButton()
|
||||
self.projectsLayout.addWidget(self.projectsBrowse)
|
||||
|
||||
self.projectsBrowse.setMinimumSize(35,35)
|
||||
self.projectsBrowse.setMaximumSize(35, 35)
|
||||
self.projectsBrowse.setStyleSheet("background-image: url(" + btnBackground + ");")
|
||||
self.projectsBrowse.clicked.connect(partial(self.browse, self.projectsPath))
|
||||
|
||||
#Save button
|
||||
self.saveChangesBtn = QtWidgets.QPushButton("Save Changes")
|
||||
self.widgetLayout.addWidget(self.saveChangesBtn)
|
||||
self.saveChangesBtn.setFont(font)
|
||||
self.saveChangesBtn.setMinimumHeight(35)
|
||||
self.saveChangesBtn.setStyleSheet("background-image: url(" + imageBtnBkrd + ");background-color: rgb(25, 175, 255);")
|
||||
self.saveChangesBtn.clicked.connect(partial(self.saveSettings))
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def browse(self, lineEdit):
|
||||
|
||||
try:
|
||||
newPath = cmds.fileDialog2(dir = self.toolsPath, fm = 3)[0]
|
||||
newPath = utils.returnFriendlyPath(newPath)
|
||||
lineEdit.setText(newPath)
|
||||
|
||||
except Exception:
|
||||
pass #in case user cancels on Maya's browse dialog
|
||||
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def saveSettings(self):
|
||||
|
||||
|
||||
#get data from ui
|
||||
mayaToolsDir = self.locationPath.text()
|
||||
scriptDir = self.scriptsPath.text()
|
||||
iconsDir = self.iconPath.text()
|
||||
projectsDir = self.projectsPath.text()
|
||||
|
||||
#save data
|
||||
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
settings.setValue("toolsPath", mayaToolsDir)
|
||||
settings.setValue("scriptPath", scriptDir)
|
||||
settings.setValue("iconPath", iconsDir)
|
||||
settings.setValue("projectPath", projectsDir)
|
||||
|
||||
|
||||
#Give message regarding data being saved, but it won't take effect until Maya is restarted.
|
||||
cmds.confirmDialog(title = "Settings Saved", message = "Please close Maya and reopen in order to have these settings take effect.")
|
||||
|
||||
#close UI
|
||||
if cmds.window("pyArtSettingsWin", exists = True):
|
||||
cmds.deleteUI("pyArtSettingsWin", wnd = True)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def run():
|
||||
|
||||
if cmds.window("pyArtSettingsWin", exists = True):
|
||||
cmds.deleteUI("pyArtSettingsWin", wnd = True)
|
||||
|
||||
gui = ART_Settings(getMainWindow())
|
||||
gui.show()
|
||||
|
||||
42
plug-ins/ARTv2/Core/Scripts/System/ART_StripFbxNamespace.py
Normal file
42
plug-ins/ARTv2/Core/Scripts/System/ART_StripFbxNamespace.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import maya.standalone as std
|
||||
std.initialize(name = 'python')
|
||||
import maya.cmds as cmds
|
||||
import maya.mel as mel
|
||||
filename = sys.argv[1]
|
||||
|
||||
def stripNamespace(filename):
|
||||
|
||||
try:
|
||||
#open the file
|
||||
cmds.loadPlugin("fbxmaya.mll")
|
||||
string = "FBXImportMode -v \"add\";"
|
||||
string += "FBXImport -file \"" + filename + "\""
|
||||
string += "FBXImportFillTimeline -v true"
|
||||
mel.eval(string)
|
||||
|
||||
|
||||
#remove the namespace
|
||||
cmds.namespace(setNamespace = "::")
|
||||
currentNamespaces = cmds.namespaceInfo(listOnlyNamespaces = True)
|
||||
|
||||
restricted = ['UI', 'shared']
|
||||
|
||||
for namespace in currentNamespaces:
|
||||
if namespace not in restricted:
|
||||
cmds.namespace(mv = (':' + namespace, ':'), force = True)
|
||||
cmds.namespace(removeNamespace = namespace)
|
||||
|
||||
#re-export the file
|
||||
mel.eval("FBXExport -f \""+ filename +"\"")
|
||||
|
||||
#exit
|
||||
std.uninitialize()
|
||||
|
||||
except Exception as e:
|
||||
sys.stderr.write(str(e))
|
||||
sys.exit(-1)
|
||||
|
||||
stripNamespace(filename)
|
||||
613
plug-ins/ARTv2/Core/Scripts/System/ART_Updater.py
Normal file
613
plug-ins/ARTv2/Core/Scripts/System/ART_Updater.py
Normal file
@@ -0,0 +1,613 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Python 2/3 compatibility
|
||||
try:
|
||||
long
|
||||
except NameError:
|
||||
# Python 3
|
||||
long = int
|
||||
from ThirdParty.Qt import QtGui, QtCore, QtWidgets, QtCompat
|
||||
import maya.cmds as cmds
|
||||
import os
|
||||
import json
|
||||
import utils
|
||||
import math
|
||||
import traceback
|
||||
import urllib2
|
||||
import zipfile
|
||||
import shutil
|
||||
import errno
|
||||
import stat
|
||||
import base64
|
||||
import System.git_utils as git
|
||||
|
||||
# Use shiboken from Qt.py for compatibility
|
||||
|
||||
|
||||
|
||||
def getMainWindow():
|
||||
import maya.OpenMayaUI as mui
|
||||
pointer = mui.MQtUtil.mainWindow()
|
||||
#pyside QMainWindow takes in a QWidget rather than QObject
|
||||
return QtCompat.wrapInstance(long(pointer), QtWidgets.QWidget)
|
||||
|
||||
|
||||
|
||||
windowTitle = "ARTv2: Check For Updates"
|
||||
windowObject = "pyArtUpdaterWin"
|
||||
|
||||
|
||||
|
||||
class ART_Updater(QtWidgets.QMainWindow):
|
||||
|
||||
def __init__(self, parent = None):
|
||||
|
||||
super(ART_Updater, self).__init__(parent)
|
||||
|
||||
#get the directory path of the tools
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
|
||||
self.toolsPath = settings.value("toolsPath")
|
||||
self.scriptPath = settings.value("scriptPath")
|
||||
self.iconsPath = settings.value("iconPath")
|
||||
self.projPath = settings.value("projectPath")
|
||||
|
||||
#get github credentials
|
||||
self.credentials = git.getGitCreds()
|
||||
if self.credentials == None:
|
||||
git.gitCredsUI(self)
|
||||
self.credentials = git.getGitCreds()
|
||||
|
||||
|
||||
|
||||
#build the UI
|
||||
self.buildSettingsUi()
|
||||
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def buildSettingsUi(self):
|
||||
|
||||
#fonts
|
||||
self.font = QtGui.QFont()
|
||||
self.font.setPointSize(10)
|
||||
self.font.setBold(False)
|
||||
|
||||
self.fontSmall = QtGui.QFont()
|
||||
self.fontSmall .setPointSize(9)
|
||||
self.fontSmall .setBold(False)
|
||||
|
||||
self.titleFont = QtGui.QFont()
|
||||
self.titleFont.setPointSize(40)
|
||||
self.titleFont.setBold(True)
|
||||
|
||||
|
||||
#images
|
||||
frameBackground = os.path.normcase(os.path.join(self.iconsPath, "System/field_background.png"))
|
||||
if frameBackground.partition("\\")[2] != "":
|
||||
frameBackground = frameBackground.replace("\\", "/")
|
||||
|
||||
imageBkgrd = os.path.normcase(os.path.join(self.iconsPath, "System/toolbar_background.png"))
|
||||
if imageBkgrd.partition("\\")[2] != "":
|
||||
imageBkgrd = imageBkgrd.replace("\\", "/")
|
||||
|
||||
imageBtnBkrd = os.path.normcase(os.path.join(self.iconsPath, "System/blue_field_background.png"))
|
||||
if imageBtnBkrd.partition("\\")[2] != "":
|
||||
imageBtnBkrd = imageBtnBkrd.replace("\\", "/")
|
||||
|
||||
#load stylesheet
|
||||
styleSheetFile = utils.returnNicePath(self.toolsPath, "Core/Scripts/Interfaces/StyleSheets/mainScheme.qss")
|
||||
f = open(styleSheetFile, "r")
|
||||
self.style = f.read()
|
||||
f.close()
|
||||
|
||||
|
||||
self.setStyleSheet(self.style)
|
||||
|
||||
#size policies
|
||||
mainSizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
|
||||
#create the main widget
|
||||
self.mainWidget = QtWidgets.QWidget()
|
||||
self.mainWidget.setStyleSheet(self.style)
|
||||
self.mainWidget.setStyleSheet("background-color: rgb(0, 0, 0);, color: rgb(0,0,0);")
|
||||
self.setCentralWidget(self.mainWidget)
|
||||
|
||||
#set qt object name
|
||||
self.setObjectName(windowObject)
|
||||
self.setWindowTitle(windowTitle)
|
||||
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||
|
||||
#create the mainLayout for the rig creator UI
|
||||
self.layout = QtWidgets.QVBoxLayout(self.mainWidget)
|
||||
|
||||
self.resize(600, 300)
|
||||
self.setSizePolicy(mainSizePolicy)
|
||||
self.setMinimumSize(QtCore.QSize( 600, 300 ))
|
||||
self.setMaximumSize(QtCore.QSize( 600, 300 ))
|
||||
|
||||
|
||||
#create the QFrame
|
||||
self.frame = QtWidgets.QFrame()
|
||||
self.layout.addWidget(self.frame)
|
||||
self.widgetLayout = QtWidgets.QVBoxLayout(self.frame)
|
||||
|
||||
#info page styling
|
||||
self.frame.setStyleSheet("background-image: url(" + imageBkgrd + ");")
|
||||
|
||||
|
||||
#detailed information
|
||||
self.infoText = QtWidgets.QTextEdit()
|
||||
self.infoText.acceptRichText()
|
||||
self.infoText.setStyleSheet("background-color: rgb(120,120,120); background-image: url(" + frameBackground + ");")
|
||||
self.widgetLayout.addWidget(self.infoText)
|
||||
self.infoText.setMinimumSize(QtCore.QSize(550,170))
|
||||
self.infoText.setMaximumSize(QtCore.QSize(550,170))
|
||||
self.infoText.setReadOnly(True)
|
||||
self.infoText.setAutoFormatting(QtWidgets.QTextEdit.AutoBulletList)
|
||||
self.infoText.setLineWrapMode(QtWidgets.QTextEdit.WidgetWidth)
|
||||
|
||||
|
||||
#progress bar
|
||||
self.progressBar = QtWidgets.QProgressBar()
|
||||
self.progressBar.setStyleSheet(self.style)
|
||||
self.progressBar.setMinimumSize(QtCore.QSize(550, 25))
|
||||
self.progressBar.setMaximumSize(QtCore.QSize(550, 25))
|
||||
self.widgetLayout.addWidget(self.progressBar)
|
||||
|
||||
#button bar
|
||||
self.buttonLayout = QtWidgets.QHBoxLayout()
|
||||
self.widgetLayout.addLayout(self.buttonLayout)
|
||||
|
||||
self.cancelButton = QtWidgets.QPushButton("Close")
|
||||
self.buttonLayout.addWidget(self.cancelButton)
|
||||
self.cancelButton.setStyleSheet(self.style)
|
||||
self.cancelButton.setObjectName("blueButton")
|
||||
self.cancelButton.clicked.connect(self.cancel)
|
||||
|
||||
self.updateButton = QtWidgets.QPushButton("Update")
|
||||
self.buttonLayout.addWidget(self.updateButton)
|
||||
self.updateButton.setStyleSheet(self.style)
|
||||
self.updateButton.setObjectName("blueButton")
|
||||
self.updateButton.clicked.connect(self.downloadUpdates)
|
||||
|
||||
if self.credentials != None:
|
||||
self.getInfo()
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def getInfo(self):
|
||||
|
||||
#need to eventually swap this with the real file
|
||||
request = urllib2.Request("https://raw.githubusercontent.com/epicernst/Test/master/ARTv2_VersionInfo.json")
|
||||
base64String = base64.encodestring('%s:%s' % (self.credentials[0], self.credentials[1])).replace('\n', '')
|
||||
request.add_header("Authorization", "Basic %s" % base64String)
|
||||
try:
|
||||
result = urllib2.urlopen(request)
|
||||
except Exception as e:
|
||||
self.infoText.setTextColor(QtGui.QColor(249,241,12))
|
||||
self.infoText.append(str(e))
|
||||
self.infoText.append("Your Github login credentials may be invalid or you do not have access to this repo.\n\n")
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
settings.remove("gitUser")
|
||||
settings.remove("gitPass")
|
||||
|
||||
return
|
||||
|
||||
|
||||
content = json.loads(result.read())
|
||||
versions = content.get("versions")
|
||||
|
||||
newFeatures = []
|
||||
majorFixes = []
|
||||
minorFixes = []
|
||||
|
||||
for version in versions:
|
||||
data = versions.get(version)
|
||||
for key in data:
|
||||
if key == "New":
|
||||
info = data.get(key)
|
||||
for each in info:
|
||||
newFeatures.append(each)
|
||||
|
||||
if key == "Critical":
|
||||
info = data.get(key)
|
||||
for each in info:
|
||||
majorFixes.append(each)
|
||||
|
||||
if key == "Minor":
|
||||
info = data.get(key)
|
||||
for each in info:
|
||||
minorFixes.append(each)
|
||||
|
||||
|
||||
#Compare local version to latest
|
||||
latestVersion = content.get("latest version")
|
||||
localVersion = self.checkLocalVersion()
|
||||
|
||||
if float(latestVersion) > float(localVersion):
|
||||
self.infoText.append("You are not up to date!\n")
|
||||
self.infoText.append("Latest Version: " + str(content.get("latest version")))
|
||||
self.infoText.append("Local Version: " + str(localVersion))
|
||||
|
||||
self.infoText.append("\n")
|
||||
|
||||
|
||||
#release notes
|
||||
self.infoText.setFont(self.titleFont)
|
||||
self.infoText.setTextColor(QtGui.QColor(48,255,0))
|
||||
self.infoText.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.infoText.append("|| NEW FEATURES ||")
|
||||
|
||||
self.infoText.setFont(self.fontSmall)
|
||||
self.infoText.setAlignment(QtCore.Qt.AlignLeft)
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
for feature in newFeatures:
|
||||
self.infoText.append(" *" + str(feature))
|
||||
|
||||
self.infoText.append("\n")
|
||||
self.infoText.setFont(self.titleFont)
|
||||
self.infoText.setTextColor(QtGui.QColor(249,168,12))
|
||||
self.infoText.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.infoText.append("|| MAJOR FIXES ||")
|
||||
|
||||
self.infoText.setFont(self.fontSmall)
|
||||
self.infoText.setAlignment(QtCore.Qt.AlignLeft)
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
for fix in majorFixes:
|
||||
self.infoText.append(" *" + str(fix))
|
||||
|
||||
self.infoText.append("\n")
|
||||
self.infoText.setFont(self.titleFont)
|
||||
self.infoText.setTextColor(QtGui.QColor(249,241,12))
|
||||
self.infoText.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.infoText.append("|| MINOR FIXES ||")
|
||||
|
||||
self.infoText.setFont(self.fontSmall)
|
||||
self.infoText.setAlignment(QtCore.Qt.AlignLeft)
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
for each in minorFixes:
|
||||
self.infoText.append(" *" + str(each))
|
||||
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.Start)
|
||||
|
||||
else:
|
||||
self.infoText.append("You are up-to-date!")
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def checkLocalVersion(self):
|
||||
|
||||
mayaModDir = os.environ["home"] + "/maya/modules/"
|
||||
if cmds.about(os = True) == "mac":
|
||||
mayaModDir = os.environ["home"] + "/Library/Preferences/Autodesk/maya/modules/"
|
||||
|
||||
modName = "ARTv2.mod"
|
||||
modFile = mayaModDir + modName
|
||||
|
||||
modFileObj = file(modFile, mode='r')
|
||||
lines = modFileObj.readlines()
|
||||
modFileObj.close()
|
||||
|
||||
localVersion = float(lines[0].split(" ")[2])
|
||||
|
||||
return localVersion
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def checkLatestVersion(self):
|
||||
|
||||
info = git.getGitCreds()
|
||||
if info != None:
|
||||
user = info[0]
|
||||
password = info[1]
|
||||
|
||||
#need to eventually swap this with the real file
|
||||
request = urllib2.Request("https://raw.githubusercontent.com/epicernst/Test/master/ARTv2_VersionInfo.json")
|
||||
base64String = base64.encodestring('%s:%s' % (user, password)).replace('\n', '')
|
||||
request.add_header("Authorization", "Basic %s" % base64String)
|
||||
result = urllib2.urlopen(request)
|
||||
content = json.loads(result.read())
|
||||
|
||||
latestVersion = content.get("latest version")
|
||||
return latestVersion
|
||||
|
||||
else:
|
||||
self.invalidCreds()
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def updateLocalVersion(self):
|
||||
|
||||
info = git.getGitCreds()
|
||||
if info != None:
|
||||
mayaModDir = cmds.internalVar(uad = True)
|
||||
mayaModDir = os.path.join(mayaModDir, "modules")
|
||||
mayaModDir = utils.returnFriendlyPath(os.path.join(mayaModDir, "ARTv2.mod"))
|
||||
|
||||
if os.path.exists(mayaModDir):
|
||||
f = open(mayaModDir, 'r')
|
||||
line = f.readline()
|
||||
f.close()
|
||||
|
||||
if line.find("+ ARTv2 ") != -1:
|
||||
version = line.partition("+ ARTv2 ")[2].partition(" ")[0]
|
||||
latest = self.checkLatestVersion()
|
||||
newline = line.replace(str(version), str(latest))
|
||||
|
||||
f = open(mayaModDir, 'w')
|
||||
f.write(newline)
|
||||
f.close()
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def findReadOnlyFiles(self, fullPath, listOfFiles):
|
||||
|
||||
#list file contents
|
||||
contents = os.listdir(fullPath)
|
||||
for each in contents:
|
||||
if os.path.isfile(os.path.join(fullPath, each)):
|
||||
fileAttr = os.stat(os.path.join(fullPath, each)).st_mode
|
||||
if not fileAttr & stat.S_IWRITE:
|
||||
try:
|
||||
os.chmod(os.path.join(fullPath, each), stat.S_IWRITE)
|
||||
except Exception as e:
|
||||
listOfFiles.append([each, e])
|
||||
if os.path.isdir(os.path.join(fullPath, each)):
|
||||
self.findReadOnlyFiles(os.path.join(fullPath, each), listOfFiles)
|
||||
|
||||
return listOfFiles
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def downloadUpdates(self):
|
||||
|
||||
info = git.getGitCreds()
|
||||
if info != None:
|
||||
user = info[0]
|
||||
password = info[1]
|
||||
|
||||
else:
|
||||
self.invalidCreds()
|
||||
return
|
||||
|
||||
base64String = base64.encodestring('%s:%s' % (user, password)).replace('\n', '')
|
||||
opener = urllib2.build_opener()
|
||||
opener.addheaders = [("Authorization", "Basic %s" % base64String)]
|
||||
response = opener.open("https://github.com/epicernst/Test/archive/master.zip")
|
||||
|
||||
zipContent = response.read()
|
||||
|
||||
filename = os.path.basename("https://github.com/epicernst/Test/blob/master/master.zip")
|
||||
path = os.environ["home"]
|
||||
filePath = os.path.join(path, filename)
|
||||
|
||||
with open(filePath, 'w') as f:
|
||||
f.write(zipContent)
|
||||
|
||||
|
||||
masterDir = os.path.dirname(filePath)
|
||||
mayaToolsZip = masterDir
|
||||
|
||||
|
||||
with zipfile.ZipFile(filePath, 'r') as zfile:
|
||||
for name in zfile.namelist():
|
||||
if name.find(".zip") != -1:
|
||||
mayaToolsZip = os.path.join(mayaToolsZip, name)
|
||||
zfile.extractall(masterDir)
|
||||
|
||||
|
||||
|
||||
baseToolsDir = os.path.dirname(self.toolsPath)
|
||||
wholeCopy = False
|
||||
|
||||
fileIssues = []
|
||||
with zipfile.ZipFile(mayaToolsZip) as zf:
|
||||
removeDirs = ["MayaTools/Core/Scripts/", "MayaTools/Core/Icons/", "MayaTools/Core/JointMover/", "MayaTools/plug-ins/"]
|
||||
|
||||
#set progress bar range
|
||||
self.progressBar.setMaximum(len(removeDirs) + 1)
|
||||
self.progressBar.setValue(0)
|
||||
|
||||
for dir in removeDirs:
|
||||
fullPath = os.path.normpath(os.path.join(baseToolsDir, dir))
|
||||
|
||||
#list file contents
|
||||
readOnlyFiles = self.findReadOnlyFiles(fullPath, fileIssues)
|
||||
|
||||
#if readOnlyFiles is empty
|
||||
if len(readOnlyFiles) == 0:
|
||||
|
||||
#make a back-up of local versions
|
||||
self.infoText.setTextColor(QtGui.QColor(0,0,0))
|
||||
self.infoText.append("\n########################################################\n")
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
self.infoText.append("Creating Backup of current version.. " + str(dir))
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.End)
|
||||
|
||||
versionNumber = self.checkLocalVersion()
|
||||
backupDir = os.path.join(os.path.dirname(self.toolsPath), "ARTv2/Backups")
|
||||
backupDir = os.path.normpath(os.path.join(backupDir, str(versionNumber)))
|
||||
printDir = backupDir
|
||||
backupDir = utils.returnFriendlyPath(backupDir)
|
||||
if not os.path.exists(backupDir):
|
||||
os.makedirs(backupDir)
|
||||
|
||||
fullPath = utils.returnFriendlyPath(fullPath)
|
||||
|
||||
try:
|
||||
shutil.move(fullPath, backupDir)
|
||||
self.infoText.append(" Backups created in " + str(printDir))
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.End)
|
||||
except Exception as e:
|
||||
self.infoText.setTextColor(QtGui.QColor(249,168,12))
|
||||
self.infoText.append(str(e))
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
wholeCopy = True
|
||||
|
||||
#extract zip file directory to original location
|
||||
if wholeCopy == False:
|
||||
for name in zf.namelist():
|
||||
for each in removeDirs:
|
||||
if name.find(each)!= -1:
|
||||
#extract directly to the base location
|
||||
try:
|
||||
zf.extract(name, baseToolsDir)
|
||||
|
||||
except Exception as e:
|
||||
self.infoText.setTextColor(QtGui.QColor(249,168,12))
|
||||
self.infoText.append(str(e))
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
wholeCopy = True
|
||||
self.infoText.append(" Extracted updated files to " + str(dir))
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.End)
|
||||
|
||||
#report on operations
|
||||
value = self.progressBar.value()
|
||||
self.progressBar.setValue(value + 1)
|
||||
|
||||
|
||||
|
||||
|
||||
#if readOnlyFiles is not empty
|
||||
else:
|
||||
wholeCopy = True
|
||||
if len(readOnlyFiles) > 0:
|
||||
self.infoText.append("The following files were marked as read-only and could not be updated:")
|
||||
for file in readOnlyFiles:
|
||||
self.infoText.append(" " + str(file))
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.End)
|
||||
|
||||
if wholeCopy:
|
||||
#report issues in UI
|
||||
self.infoText.setTextColor(QtGui.QColor(249,168,12))
|
||||
self.infoText.append("Could not apply updates automatically.")
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.End)
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
|
||||
|
||||
#extract all to an Update folder
|
||||
version = self.checkLatestVersion()
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
updateDir = os.path.join(self.toolsPath, "Update_" + str(version))
|
||||
if not os.path.exists(updateDir):
|
||||
os.makedirs(updateDir)
|
||||
|
||||
self.infoText.append("Extracting updated files to:\n " + str(updateDir))
|
||||
try:
|
||||
zf.extractall(updateDir)
|
||||
except Exception as e:
|
||||
self.infoText.setTextColor(QtGui.QColor(249,168,12))
|
||||
self.infoText.append("Operation Failed")
|
||||
self.infoText.append(str(e))
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.End)
|
||||
|
||||
#report on operation
|
||||
self.infoText.append("Update Extracted. Since the automatic operation failed, you will need to manually integrate and apply the updates.")
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.End)
|
||||
|
||||
else:
|
||||
self.infoText.setTextColor(QtGui.QColor(48,255,0))
|
||||
self.infoText.append("\n\nUpdate Operation Completed!")
|
||||
self.infoText.append("You must restart Maya to have updates applied.")
|
||||
self.infoText.moveCursor(QtGui.QTextCursor.End)
|
||||
|
||||
|
||||
#delete zipFile
|
||||
try:
|
||||
os.remove(filePath)
|
||||
|
||||
for each in os.listdir(os.path.dirname(mayaToolsZip)):
|
||||
path = os.path.dirname(mayaToolsZip)
|
||||
path = os.path.join(path, each)
|
||||
os.remove(path)
|
||||
|
||||
os.chmod(os.path.dirname(mayaToolsZip), stat.S_IWRITE)
|
||||
shutil.rmtree(os.path.dirname(mayaToolsZip))
|
||||
|
||||
except Exception as e:
|
||||
self.infoText.append("Unable to clean up temporary files..")
|
||||
self.infoText.append(str(e))
|
||||
|
||||
value = self.progressBar.value()
|
||||
self.progressBar.setValue(value + 1)
|
||||
|
||||
#update .mod file with latest version #
|
||||
self.updateLocalVersion()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def cancel(self):
|
||||
self.close()
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def invalidCreds(self):
|
||||
|
||||
self.infoText.setTextColor(QtGui.QColor(249,241,12))
|
||||
self.infoText.append("You have either not setup your Github credentials under Settings, or your github account is not linked with your Epic Games account.")
|
||||
self.infoText.append("For more information on linking your github and Epic Games accounts, see:\n")
|
||||
self.infoText.append("https://www.unrealengine.com/ue4-on-github")
|
||||
self.infoText.setTextColor(QtGui.QColor(255,255,255))
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def run():
|
||||
|
||||
if cmds.window("pyArtUpdaterWin", exists = True):
|
||||
cmds.deleteUI("pyArtUpdaterWin", wnd = True)
|
||||
|
||||
gui = ART_Updater(getMainWindow())
|
||||
gui.show()
|
||||
0
plug-ins/ARTv2/Core/Scripts/System/__init__.py
Normal file
0
plug-ins/ARTv2/Core/Scripts/System/__init__.py
Normal file
80
plug-ins/ARTv2/Core/Scripts/System/git_utils.py
Normal file
80
plug-ins/ARTv2/Core/Scripts/System/git_utils.py
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Author: Jeremy Ernst
|
||||
|
||||
This module has utility functions for dealing with github interactions.
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
|
||||
from ThirdParty.Qt import QtCore, QtWidgets
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def getGitCreds():
|
||||
"""
|
||||
Get the github credentials stored in the QSettings
|
||||
|
||||
:return: github username and password
|
||||
"""
|
||||
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
|
||||
user = settings.value("gitUser")
|
||||
password = settings.value("gitPass")
|
||||
|
||||
if user is not None and password is not None:
|
||||
return [user, password]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def gitWriteCreds(username, password, ui):
|
||||
"""
|
||||
Set the QSettings values for the username and password with the supplied information.
|
||||
|
||||
:param username: user-entered github username
|
||||
:param password: user-entered github password
|
||||
:param ui: instance of UI where use enters above information
|
||||
"""
|
||||
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
settings.setValue("gitUser", username.text())
|
||||
settings.setValue("gitPass", password.text())
|
||||
ui.close()
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def gitCredsUI(parent):
|
||||
"""
|
||||
Create an interface that allows user to enter github username and password.
|
||||
|
||||
:param parent: interface that this interface will be a child of.
|
||||
"""
|
||||
|
||||
credsDialog = QtWidgets.QDialog(parent)
|
||||
credsDialog.setWindowTitle("Github Credentials")
|
||||
credsDialog.setMinimumSize(QtCore.QSize(200, 120))
|
||||
credsDialog.setMaximumSize(QtCore.QSize(200, 120))
|
||||
|
||||
layout = QtWidgets.QVBoxLayout(credsDialog)
|
||||
userName = QtWidgets.QLineEdit()
|
||||
userName.setPlaceholderText("Github User Name..")
|
||||
layout.addWidget(userName)
|
||||
|
||||
password = QtWidgets.QLineEdit()
|
||||
password.setPlaceholderText("Github Password..")
|
||||
layout.addWidget(password)
|
||||
password.setEchoMode(QtWidgets.QLineEdit.Password)
|
||||
|
||||
confirmButton = QtWidgets.QPushButton("Confirm")
|
||||
layout.addWidget(confirmButton)
|
||||
confirmButton.setObjectName("blueButton")
|
||||
confirmButton.clicked.connect(partial(gitWriteCreds, userName, password, credsDialog))
|
||||
|
||||
credsDialog.exec_()
|
||||
643
plug-ins/ARTv2/Core/Scripts/System/interfaceUtils.py
Normal file
643
plug-ins/ARTv2/Core/Scripts/System/interfaceUtils.py
Normal file
@@ -0,0 +1,643 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# standard imports
|
||||
from __future__ import print_function
|
||||
import os
|
||||
from stat import S_IWUSR, S_IREAD
|
||||
|
||||
import maya.cmds as cmds
|
||||
|
||||
import utils
|
||||
from ThirdParty.Qt import QtGui, QtCore, QtWidgets, QtCompat
|
||||
|
||||
# Use QtCompat from Qt.py for shiboken compatibility
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def getMainWindow():
|
||||
import maya.OpenMayaUI as mui
|
||||
pointer = mui.MQtUtil.mainWindow()
|
||||
# pyside QMainWindow takes in a QWidget rather than QObject
|
||||
return QtCompat.wrapInstance(int(pointer), QtWidgets.QWidget)
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def writeQSS(filePath):
|
||||
# this function takes the qss file given, and finds and replaces any image path URLs using the user's settings for
|
||||
# the icons path and changes the file on disk
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
scriptsPath = settings.value("scriptPath")
|
||||
scriptsPath = utils.returnFriendlyPath(scriptsPath)
|
||||
iconPath = settings.value("iconPath")
|
||||
iconPath = utils.returnFriendlyPath(iconPath)
|
||||
|
||||
f = open(filePath, "r")
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
newLines = []
|
||||
for line in lines:
|
||||
if line.find("url(") != -1:
|
||||
oldPath = line.partition("(")[2].rpartition("/")[0]
|
||||
replacePath = utils.returnNicePath(iconPath, "System")
|
||||
|
||||
newLine = line.replace(oldPath, replacePath)
|
||||
newLines.append(newLine)
|
||||
else:
|
||||
newLines.append(line)
|
||||
|
||||
os.chmod(filePath, S_IWUSR | S_IREAD)
|
||||
f = open(filePath, "w")
|
||||
for line in newLines:
|
||||
f.write(line)
|
||||
f.close()
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def addTextToButton(text, parent, centered=True, top=False, bottom=False):
|
||||
text = QtWidgets.QGraphicsSimpleTextItem(text, parent)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setPointSize(12)
|
||||
|
||||
text.setFont(font)
|
||||
textPos = parent.boundingRect().center()
|
||||
textRect = text.boundingRect()
|
||||
parentRect = parent.boundingRect()
|
||||
|
||||
if centered:
|
||||
text.setPos(textPos.x() - textRect.width() / 2, textPos.y() - textRect.height() / 2)
|
||||
|
||||
if top:
|
||||
text.setPos(textPos.x() - textRect.width() / 2, textPos.y() - (parentRect.height() / 2 + textRect.height()))
|
||||
|
||||
if bottom:
|
||||
text.setPos(textPos.x() - textRect.width() / 2, textPos.y() + (parentRect.height() / 2))
|
||||
|
||||
return text
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
class progressDialog(object):
|
||||
'''
|
||||
range is a tuple (min,max)
|
||||
example:
|
||||
myBar = progressDialog((0,100000), label="Exporting weights")
|
||||
for i in range(0,100000):
|
||||
myBar.setValue(i)
|
||||
'''
|
||||
|
||||
def __init__(self, range, label='Doin Stuff..', freq=10):
|
||||
self.rangeMin, self.rangeMax, self.freq = range[0], range[1], freq
|
||||
self.bar = QtWidgets.QProgressDialog(label, None, self.rangeMin, self.rangeMax)
|
||||
self.bar.setWindowModality(QtCore.Qt.WindowModal)
|
||||
self.bar.autoClose()
|
||||
|
||||
def setValue(self, val):
|
||||
self.bar.show()
|
||||
QtWidgets.QApplication.processEvents()
|
||||
if val % self.freq == 0 or (val + 1) == self.rangeMax:
|
||||
self.bar.setValue(val + 1)
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
class ProgressBar(QtWidgets.QProgressBar):
|
||||
def __init__(self, title, parent=None):
|
||||
super(ProgressBar, self).__init__()
|
||||
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
self.toolsPath = settings.value("toolsPath")
|
||||
|
||||
# load stylesheet
|
||||
styleSheetFile = utils.returnNicePath(self.toolsPath, "Core/Scripts/Interfaces/StyleSheets/mainScheme.qss")
|
||||
f = open(styleSheetFile, "r")
|
||||
self.style = f.read()
|
||||
f.close()
|
||||
|
||||
self.setStyleSheet(self.style)
|
||||
self.setWindowTitle(title)
|
||||
self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowTitleHint | QtCore.Qt.CustomizeWindowHint)
|
||||
|
||||
self.setMinimumSize(QtCore.QSize(400, 40))
|
||||
self.setMaximumSize(QtCore.QSize(400, 40))
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
class commentBoxItem(QtWidgets.QGraphicsRectItem):
|
||||
def __init__(self, x, y, w, h, scene, view, animUI):
|
||||
|
||||
super(commentBoxItem, self).__init__(x, y, w, h)
|
||||
|
||||
self.brush = QtGui.QBrush(QtGui.QColor(60, 60, 60, 125))
|
||||
self.brushColor = self.brush.color()
|
||||
self.width = w
|
||||
self.height = h
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.scale = 1
|
||||
self.menu = QtWidgets.QMenu()
|
||||
self.scene = scene
|
||||
self.view = view
|
||||
self.animUI = animUI
|
||||
|
||||
self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges)
|
||||
|
||||
# add items to context menu
|
||||
self.menu.addAction("Change Color", self.changeBoxColor)
|
||||
self.menu.addAction("Rename", self.changeLabelText)
|
||||
self.menu.addAction("Remove Comment Box", self.deleteCommentBox)
|
||||
|
||||
# add text (Qt5/PySide2 compatible - only takes text and parent)
|
||||
self.textLabel = QtWidgets.QGraphicsTextItem("Comment Box", self)
|
||||
self.textLabel.setPos(x, y - 20)
|
||||
self.textLabel.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
|
||||
# self.textLabel.setTextInteractionFlags(QtCore.Qt.TextEditable)
|
||||
|
||||
self.classType = "comment"
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def boundingRect(self):
|
||||
rect = QtCore.QRectF(self.x, self.y, self.width, self.height)
|
||||
return rect
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def paint(self, painter, option, widget):
|
||||
rec = self.boundingRect()
|
||||
|
||||
self.blackPen = QtGui.QPen(QtCore.Qt.black)
|
||||
self.blackPen.setWidth(0)
|
||||
painter.setPen(self.blackPen)
|
||||
painter.fillRect(rec, self.brush)
|
||||
painter.drawRect(rec)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def contextMenuEvent(self, event):
|
||||
self.menu.exec_(event.screenPos())
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def changeBoxColor(self):
|
||||
|
||||
# launch a color dialog to get a new color
|
||||
newColor = QtGui.QColorDialog.getColor()
|
||||
newColor.setAlpha(100)
|
||||
self.brush.setColor(newColor)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def changeLabelText(self):
|
||||
|
||||
text = QtWidgets.QInputDialog.getText(self.scene.parent(), "Comment Box", "Enter Label Text:")
|
||||
if text:
|
||||
self.textLabel.setPlainText(text[0])
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def deleteCommentBox(self):
|
||||
|
||||
self.scene.removeItem(self)
|
||||
self.animUI.rubberband.hide()
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
class pickerBorderItem(QtWidgets.QGraphicsRectItem):
|
||||
def __init__(self, x, y, w, h, brush, moduleName, niceName=None):
|
||||
|
||||
super(pickerBorderItem, self).__init__(x, y, w, h)
|
||||
|
||||
self.brush = brush
|
||||
self.brushColor = brush.color()
|
||||
self.width = w
|
||||
self.height = h
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.scale = 1
|
||||
|
||||
self.mouseDown = False
|
||||
|
||||
self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
|
||||
self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable)
|
||||
self.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable)
|
||||
self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges)
|
||||
|
||||
self.setData(QtCore.Qt.UserRole, moduleName)
|
||||
self.setData(2, niceName)
|
||||
self.classType = "border"
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def boundingRect(self):
|
||||
rect = QtCore.QRectF(self.x, self.y, self.width, self.height)
|
||||
return rect
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def paint(self, painter, option, widget):
|
||||
rec = self.boundingRect()
|
||||
|
||||
blackPen = QtGui.QPen(QtCore.Qt.transparent)
|
||||
blackPen.setWidth(0)
|
||||
blackPen.setStyle(QtCore.Qt.DotLine)
|
||||
painter.setPen(blackPen)
|
||||
|
||||
flags = self.flags()
|
||||
if flags & QtWidgets.QGraphicsItem.ItemIsMovable:
|
||||
blackPen = QtGui.QPen(QtCore.Qt.black)
|
||||
blackPen.setWidth(0)
|
||||
blackPen.setStyle(QtCore.Qt.DotLine)
|
||||
painter.setPen(blackPen)
|
||||
|
||||
if self.isSelected():
|
||||
blackPen = QtGui.QPen(QtCore.Qt.white)
|
||||
blackPen.setWidth(0)
|
||||
blackPen.setStyle(QtCore.Qt.DotLine)
|
||||
painter.setPen(blackPen)
|
||||
|
||||
painter.fillRect(rec, self.brush)
|
||||
painter.drawRect(rec)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def wheelEvent(self, event):
|
||||
|
||||
# only if the focusable flag is set to true, do we continue
|
||||
flags = self.flags()
|
||||
if flags & QtWidgets.QGraphicsItem.ItemIsFocusable:
|
||||
|
||||
self.scale = self.data(1)
|
||||
if self.scale is None:
|
||||
self.scale = 1
|
||||
scale = float(event.delta() / 8.0)
|
||||
self.scale = float((scale / 15.0) / 10) + self.scale
|
||||
self.setData(1, self.scale)
|
||||
|
||||
self.setTransformOriginPoint(self.boundingRect().center())
|
||||
self.setScale(self.scale)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def keyPressEvent(self, event):
|
||||
|
||||
self.setTransformOriginPoint(self.boundingRect().center())
|
||||
|
||||
if event.key() == QtCore.Qt.Key_Left:
|
||||
self.setRotation(self.rotation() - 10)
|
||||
|
||||
if event.key() == QtCore.Qt.Key_Right:
|
||||
self.setRotation(self.rotation() + 10)
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
class pickerButton(QtWidgets.QGraphicsItem):
|
||||
def __init__(self, width, height, relativePos, controlObj, brush, parent=None):
|
||||
|
||||
super(pickerButton, self).__init__(parent)
|
||||
|
||||
self.parentItem().setZValue(1)
|
||||
self.setZValue(2)
|
||||
|
||||
self.brush = QtGui.QBrush(brush)
|
||||
self.brushColor = brush
|
||||
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.relativePos = relativePos
|
||||
self.object = controlObj
|
||||
|
||||
self.setPos(self.parentItem().boundingRect().topLeft())
|
||||
self.setPos(self.pos().x() + self.relativePos[0], self.pos().y() + self.relativePos[1])
|
||||
self.menu = QtWidgets.QMenu()
|
||||
|
||||
self.classType = "pickerButton"
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def boundingRect(self):
|
||||
rect = QtCore.QRectF(0, 0, self.width, self.height)
|
||||
return rect
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def paint(self, painter, option, widget):
|
||||
rec = self.boundingRect()
|
||||
painter.fillRect(rec, self.brush)
|
||||
painter.drawRect(rec)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def mousePressEvent(self, event):
|
||||
|
||||
mods = cmds.getModifiers()
|
||||
if (mods & 1) > 0:
|
||||
cmds.select(self.object, tgl=True)
|
||||
if (mods & 1) == 0:
|
||||
cmds.select(self.object)
|
||||
|
||||
if self.object in cmds.ls(sl=True):
|
||||
|
||||
self.brush.setColor(QtCore.Qt.white)
|
||||
|
||||
else:
|
||||
self.brush.setColor(self.brushColor)
|
||||
|
||||
self.update()
|
||||
QtWidgets.QGraphicsItem.mousePressEvent(self, event)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def mousePressEventCustom(self, event):
|
||||
|
||||
cmds.select(self.object, tgl=True)
|
||||
self.brush.setColor(self.brushColor)
|
||||
self.update()
|
||||
QtWidgets.QGraphicsItem.mousePressEvent(self, event)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def mouseMoveEvent(self, event):
|
||||
print("mouse move event")
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def dragMoveEvent(self, event):
|
||||
print("drag move event")
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def hoverMoveEvent(self, event):
|
||||
print("hover move event")
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def contextMenuEvent(self, event):
|
||||
self.menu.exec_(event.screenPos())
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
class pickerButtonCustom(QtWidgets.QGraphicsPolygonItem):
|
||||
def __init__(self, width, height, pointArray, relativePos, controlObj, brush, parent=None):
|
||||
|
||||
super(pickerButtonCustom, self).__init__(parent)
|
||||
|
||||
self.parentItem().setZValue(1)
|
||||
self.setZValue(2)
|
||||
|
||||
self.brush = QtGui.QBrush(brush)
|
||||
self.brushColor = brush
|
||||
self.pointArray = pointArray
|
||||
self.poly = self.createPolygon()
|
||||
self.setPolygon(self.poly)
|
||||
|
||||
# position item
|
||||
self.relativePos = relativePos
|
||||
self.object = controlObj
|
||||
self.setPos(self.parentItem().boundingRect().topLeft())
|
||||
self.setPos(self.pos().x() + self.relativePos[0], self.pos().y() + self.relativePos[1])
|
||||
|
||||
# create menu
|
||||
self.menu = QtWidgets.QMenu()
|
||||
self.classType = "pickerButton"
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def createPolygon(self):
|
||||
polygon = QtGui.QPolygonF()
|
||||
for each in self.pointArray:
|
||||
polygon.append(QtCore.QPointF(each[0], each[1]))
|
||||
return polygon
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def paint(self, painter, option, widget):
|
||||
painter.setBrush(self.brush)
|
||||
painter.drawPolygon(self.polygon())
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def mousePressEvent(self, event):
|
||||
|
||||
mods = cmds.getModifiers()
|
||||
if (mods & 1) > 0:
|
||||
cmds.select(self.object, tgl=True)
|
||||
if (mods & 1) == 0:
|
||||
cmds.select(self.object)
|
||||
|
||||
if self.object in cmds.ls(sl=True):
|
||||
|
||||
self.brush.setColor(QtCore.Qt.white)
|
||||
|
||||
else:
|
||||
self.brush.setColor(self.brushColor)
|
||||
|
||||
self.update()
|
||||
QtWidgets.QGraphicsPolygonItem.mousePressEvent(self, event)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def mousePressEventCustom(self, event):
|
||||
|
||||
cmds.select(self.object, tgl=True)
|
||||
self.brush.setColor(self.brushColor)
|
||||
self.update()
|
||||
QtWidgets.QGraphicsItem.mousePressEvent(self, event)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def contextMenuEvent(self, event):
|
||||
self.menu.exec_(event.screenPos())
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
class pickerButtonAll(QtWidgets.QGraphicsItem):
|
||||
def __init__(self, width, height, relativePos, controlObjects, brush, parent=None):
|
||||
|
||||
super(pickerButtonAll, self).__init__(parent)
|
||||
|
||||
self.parentItem().setZValue(1)
|
||||
self.setZValue(2)
|
||||
|
||||
self.brush = QtGui.QBrush(brush)
|
||||
self.brushColor = brush
|
||||
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.relativePos = relativePos
|
||||
self.objects = controlObjects
|
||||
|
||||
self.setPos(self.parentItem().boundingRect().topLeft())
|
||||
self.setPos(self.pos().x() + self.relativePos[0], self.pos().y() + self.relativePos[1])
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def boundingRect(self):
|
||||
rect = QtCore.QRectF(0, 0, self.width, self.height)
|
||||
return rect
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def paint(self, painter, option, widget):
|
||||
rec = self.boundingRect()
|
||||
painter.fillRect(rec, self.brush)
|
||||
painter.drawRect(rec)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def mousePressEvent(self, event):
|
||||
|
||||
mods = cmds.getModifiers()
|
||||
if (mods & 1) > 0:
|
||||
for obj in self.objects:
|
||||
cmds.select(obj, add=True)
|
||||
|
||||
if (mods & 1) == 0:
|
||||
cmds.select(clear=True)
|
||||
for obj in self.objects:
|
||||
cmds.select(obj, tgl=True)
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
class DialogMessage(QtWidgets.QMainWindow):
|
||||
def __init__(self, title, message, elementList, elementSize, parent=None):
|
||||
super(DialogMessage, self).__init__(parent)
|
||||
|
||||
# get the directory path of the
|
||||
settings = QtCore.QSettings("Epic Games", "ARTv2")
|
||||
self.toolsPath = settings.value("toolsPath")
|
||||
self.iconsPath = settings.value("iconPath")
|
||||
|
||||
# load stylesheet
|
||||
styleSheetFile = utils.returnNicePath(self.toolsPath, "Core/Scripts/Interfaces/StyleSheets/mainScheme.qss")
|
||||
f = open(styleSheetFile, "r")
|
||||
style = f.read()
|
||||
f.close()
|
||||
|
||||
self.setStyleSheet(style)
|
||||
|
||||
# size policies
|
||||
mainSizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
|
||||
# create the main widget
|
||||
self.mainWidget = QtWidgets.QWidget()
|
||||
self.setCentralWidget(self.mainWidget)
|
||||
|
||||
# set qt object name
|
||||
self.setObjectName("pyART_customDialogMessageWin")
|
||||
self.setWindowTitle(title)
|
||||
|
||||
# create the mainLayout for the rig creator UI
|
||||
self.mainLayout = QtWidgets.QVBoxLayout(self.mainWidget)
|
||||
self.mainLayout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.resize(300, 200)
|
||||
self.setSizePolicy(mainSizePolicy)
|
||||
self.setMinimumSize(QtCore.QSize(300, 200))
|
||||
self.setMaximumSize(QtCore.QSize(300, 200))
|
||||
|
||||
# create the background image
|
||||
self.frame = QtWidgets.QFrame()
|
||||
self.mainLayout.addWidget(self.frame)
|
||||
|
||||
# create the layout for the widgets
|
||||
self.widgetLayout = QtWidgets.QVBoxLayout(self.frame)
|
||||
|
||||
# add the message to the layout
|
||||
self.messageArea = QtWidgets.QTextEdit()
|
||||
self.messageArea.setReadOnly(True)
|
||||
self.widgetLayout.addWidget(self.messageArea)
|
||||
|
||||
self.messageArea.setTextColor(QtGui.QColor(236, 217, 0))
|
||||
self.messageArea.append(message + "\n\n")
|
||||
|
||||
string = ""
|
||||
for each in elementList:
|
||||
for i in range(elementSize):
|
||||
string += each[i] + " "
|
||||
|
||||
self.messageArea.setTextColor(QtGui.QColor(255, 255, 255))
|
||||
self.messageArea.append(string)
|
||||
|
||||
# add the OK button
|
||||
self.confirmButton = QtWidgets.QPushButton("OK")
|
||||
self.confirmButton.setObjectName("blueButton")
|
||||
self.widgetLayout.addWidget(self.confirmButton)
|
||||
self.confirmButton.clicked.connect(self.closeWindow)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def closeWindow(self):
|
||||
|
||||
cmds.deleteUI("pyART_customDialogMessageWin", wnd=True)
|
||||
210
plug-ins/ARTv2/Core/Scripts/System/mathUtils.py
Normal file
210
plug-ins/ARTv2/Core/Scripts/System/mathUtils.py
Normal file
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Math utilities
|
||||
2015, Epic Games
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import math
|
||||
|
||||
import maya.api.OpenMaya as om
|
||||
import maya.cmds as cmds
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# CLASSES
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
class KDTreeNode():
|
||||
def __init__(self, point, left, right):
|
||||
self.point = point
|
||||
self.left = left
|
||||
self.right = right
|
||||
|
||||
def is_leaf(self):
|
||||
return (self.left is None and self.right is None)
|
||||
|
||||
|
||||
class KDTreeNeighbours():
|
||||
""" Internal structure used in nearest-neighbours search.
|
||||
"""
|
||||
|
||||
def __init__(self, query_point, t):
|
||||
self.query_point = query_point
|
||||
self.t = t # neighbours wanted
|
||||
self.largest_distance = 0 # squared
|
||||
self.current_best = []
|
||||
|
||||
def calculate_largest(self):
|
||||
if self.t >= len(self.current_best):
|
||||
self.largest_distance = self.current_best[-1][1]
|
||||
else:
|
||||
self.largest_distance = self.current_best[self.t - 1][1]
|
||||
|
||||
def add(self, point):
|
||||
sd = square_distance(point, self.query_point)
|
||||
# run through current_best, try to find appropriate place
|
||||
for i, e in enumerate(self.current_best):
|
||||
if i == self.t:
|
||||
return # enough neighbours, this one is farther, let's forget it
|
||||
if e[1] > sd:
|
||||
self.current_best.insert(i, [point, sd])
|
||||
self.calculate_largest()
|
||||
return
|
||||
# append it to the end otherwise
|
||||
self.current_best.append([point, sd])
|
||||
self.calculate_largest()
|
||||
|
||||
def get_best(self):
|
||||
return [element[0] for element in self.current_best[:self.t]]
|
||||
|
||||
|
||||
class KDTree():
|
||||
""" KDTree implementation built from http://en.wikipedia.org/wiki/K-d_tree as a starting point
|
||||
|
||||
Example usage:
|
||||
from kdtree import KDTree
|
||||
|
||||
tree = KDTree.construct_from_data(data)
|
||||
nearest = tree.query(point, t=4) # find nearest 4 points
|
||||
"""
|
||||
|
||||
def __init__(self, data):
|
||||
def build_kdtree(point_list, depth):
|
||||
if not point_list:
|
||||
return None
|
||||
|
||||
# check that all points share the same dimensions
|
||||
dim = len(point_list[0])
|
||||
for point in point_list:
|
||||
if len(point) != dim:
|
||||
print(f'KDTREE: point {point} does not have {dim} dimensions.')
|
||||
|
||||
# select axis based on depth modulo tested dimension
|
||||
axis = depth % dim
|
||||
|
||||
# sort point list
|
||||
point_list.sort(key=lambda point: point[axis])
|
||||
# choose the median
|
||||
median = len(point_list) // 2
|
||||
|
||||
# create node and recursively construct subtrees
|
||||
node = KDTreeNode(point=point_list[median],
|
||||
left=build_kdtree(point_list[0:median], depth + 1),
|
||||
right=build_kdtree(point_list[median + 1:], depth + 1))
|
||||
return node
|
||||
|
||||
self.root_node = build_kdtree(data, depth=0)
|
||||
|
||||
@staticmethod
|
||||
def construct_from_data(data):
|
||||
tree = KDTree(data)
|
||||
return tree
|
||||
|
||||
def query(self, query_point, t=1, debug=1):
|
||||
stats = {'nodes_visited': 0, 'far_search': 0, 'leafs_reached': 0}
|
||||
|
||||
def nn_search(node, query_point, t, depth, best_neighbours):
|
||||
if node is None:
|
||||
return
|
||||
|
||||
stats['nodes_visited'] += 1
|
||||
|
||||
# if we have reached a leaf, let's add to current best neighbours,
|
||||
# (if it's better than the worst one or if there is not enough neighbours)
|
||||
if node.is_leaf():
|
||||
# statistics['leafs_reached'] += 1
|
||||
best_neighbours.add(node.point)
|
||||
return
|
||||
|
||||
# this node is no leaf
|
||||
|
||||
# select dimension for comparison (based on current depth)
|
||||
axis = depth % len(query_point)
|
||||
|
||||
# figure out which subtree to search
|
||||
near_subtree = None # near subtree
|
||||
far_subtree = None # far subtree (perhaps we'll have to traverse it as well)
|
||||
|
||||
# compare query_point and point of current node in selected dimension
|
||||
# and figure out which subtree is farther than the other
|
||||
if query_point[axis] < node.point[axis]:
|
||||
near_subtree = node.left
|
||||
far_subtree = node.right
|
||||
else:
|
||||
near_subtree = node.right
|
||||
far_subtree = node.left
|
||||
|
||||
# recursively search through the tree until a leaf is found
|
||||
nn_search(near_subtree, query_point, t, depth + 1, best_neighbours)
|
||||
|
||||
# while unwinding the recursion, check if the current node
|
||||
# is closer to query point than the current best,
|
||||
# also, until t points have been found, search radius is infinity
|
||||
best_neighbours.add(node.point)
|
||||
|
||||
# check whether there could be any points on the other side of the
|
||||
# splitting plane that are closer to the query point than the current best
|
||||
if (node.point[axis] - query_point[axis]) ** 2 < best_neighbours.largest_distance:
|
||||
# statistics['far_search'] += 1
|
||||
nn_search(far_subtree, query_point, t, depth + 1, best_neighbours)
|
||||
|
||||
return
|
||||
|
||||
# if there's no tree, there's no neighbors
|
||||
if self.root_node is not None:
|
||||
neighbours = KDTreeNeighbours(query_point, t)
|
||||
nn_search(self.root_node, query_point, t, depth=0, best_neighbours=neighbours)
|
||||
result = neighbours.get_best()
|
||||
else:
|
||||
result = []
|
||||
|
||||
# print statistics
|
||||
return result
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# METHODS
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
def square_distance(self, pointA, pointB):
|
||||
# squared euclidean distance
|
||||
distance = 0
|
||||
dimensions = len(pointA) # assumes both points have the same dimensions
|
||||
for dimension in range(dimensions):
|
||||
distance += (pointA[dimension] - pointB[dimension]) ** 2
|
||||
return distance
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def getAngleBetween(object1, object2):
|
||||
point1 = cmds.xform(object1, t=True, q=True, ws=True)
|
||||
vector1 = om.MVector(point1)
|
||||
|
||||
point2 = cmds.xform(object2, t=True, q=True, ws=True)
|
||||
vector2 = om.MVector(point2)
|
||||
|
||||
dotProduct = vector1.normal() * vector2.normal()
|
||||
angle = math.acos(dotProduct) * 180 / math.pi
|
||||
return angle
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
def returnPercentile(incomingRange, percent, key=lambda x: x):
|
||||
floor = math.floor(percent)
|
||||
ceil = math.ceil(percent)
|
||||
|
||||
if percent == 1:
|
||||
return incomingRange[1]
|
||||
|
||||
if percent == 0:
|
||||
return incomingRange[0]
|
||||
|
||||
d0 = key(incomingRange[int(floor)] * (ceil - percent))
|
||||
d1 = key(incomingRange[int(ceil)] * (percent - floor))
|
||||
|
||||
return d0 + d1
|
||||
1451
plug-ins/ARTv2/Core/Scripts/System/riggingUtils.py
Normal file
1451
plug-ins/ARTv2/Core/Scripts/System/riggingUtils.py
Normal file
File diff suppressed because it is too large
Load Diff
1157
plug-ins/ARTv2/Core/Scripts/System/utils.py
Normal file
1157
plug-ins/ARTv2/Core/Scripts/System/utils.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user