Skip to content

Commit cf66585

Browse files
committed
Initial Commit
1 parent 4925501 commit cf66585

32 files changed

+1242
-0
lines changed

Maya/BatchPlacer.py

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
from PySide import QtGui, QtCore
2+
import pysideuic
3+
import xml.etree.ElementTree as xml
4+
from cStringIO import StringIO
5+
from pymel.core import *
6+
import pymel.core as pm
7+
from pymel import *
8+
import maya.OpenMayaUI as apiUI
9+
import maya.OpenMaya as om
10+
import maya.cmds as cmds
11+
from itertools import izip
12+
import math
13+
14+
def pairwise(iterable):
15+
a = iter(iterable)
16+
return izip(a, a)
17+
18+
# Helper for loading Qt ui files from nathanhorne.com/?p=451
19+
def loadUiType(uiFile):
20+
"""
21+
Pyside lacks the "loadUiType" command, so we have to convert the ui file to py code in-memory first
22+
and then execute it in a special frame to retrieve the form_class.
23+
"""
24+
parsed = xml.parse(uiFile)
25+
widget_class = parsed.find('widget').get('class')
26+
form_class = parsed.find('class').text
27+
28+
with open(uiFile, 'r') as f:
29+
o = StringIO()
30+
frame = {}
31+
32+
pysideuic.compileUi(f, o, indent=0)
33+
pyc = compile(o.getvalue(), '<string>', 'exec')
34+
exec pyc in frame
35+
36+
#Fetch the base_class and form class based on their type in the xml from designer
37+
form_class = frame['Ui_%s'%form_class]
38+
base_class = eval('QtGui.%s'%widget_class)
39+
return form_class, base_class
40+
41+
# UE4 Static Mesh strings
42+
ue4_static_header = "Begin Map\r\n Begin Level\r\n"
43+
ue4_static_footer = " End Level\r\nBegin Surface\r\nEnd Map\r\n"
44+
ue4_static_template_body = " Begin Actor Class=StaticMeshActor Name=$MAYANAME$_1 Archetype=StaticMeshActor'/Script/Engine.Default__StaticMeshActor'\r\n Begin Object Class=StaticMeshComponent Name=\"StaticMeshComponent0\" Archetype=StaticMeshComponent'Default__StaticMeshActor:StaticMeshComponent0'\r\n End Object\r\n Begin Object Name=\"StaticMeshComponent0\"\r\n StaticMesh=$UNREALNAME$\r\n RelativeLocation=(X=$LOC_X$,Y=$LOC_Y$,Z=$LOC_Z$)\r\n RelativeScale3D=(X=$SCALE_X$,Y=$SCALE_Y$,Z=$SCALE_Z$)\r\n BodyInstance=(Scale3D=(X=$SCALE_X$,Y=$SCALE_Y$,Z=$SCALE_Z$))\r\n RelativeRotation=(Pitch=$ROT_Y$,Yaw=$ROT_Z$,Roll=$ROT_X$)\r\n End Object\r\n StaticMeshComponent=StaticMeshComponent0\r\n RootComponent=StaticMeshComponent0\r\n ActorLabel=\"$MAYANAME$\"\r\n End Actor\r\n"
45+
46+
def GetTemplatedExportBody(MayaName, UnrealName, LocX, LocY, LocZ, RotX, RotY, RotZ, ScaleX, ScaleY, ScaleZ):
47+
body = ue4_static_template_body.replace("$MAYANAME$", MayaName)
48+
body = body.replace("$UNREALNAME$", UnrealName)
49+
body = body.replace("$LOC_X$", str(LocX))
50+
body = body.replace("$LOC_Y$", str(LocY))
51+
body = body.replace("$LOC_Z$", str(LocZ))
52+
body = body.replace("$ROT_X$", str(RotX))
53+
body = body.replace("$ROT_Y$", str(RotY))
54+
body = body.replace("$ROT_Z$", str(RotZ))
55+
body = body.replace("$SCALE_X$", str(ScaleX))
56+
body = body.replace("$SCALE_Y$", str(ScaleY))
57+
body = body.replace("$SCALE_Z$", str(ScaleZ))
58+
return body
59+
60+
# Paths to Files
61+
homedir = os.environ['UE4_PRODUCTIVITY'].replace("\\","/") + "/"
62+
usersettings = homedir + "Maya/batchplacer.config"
63+
main_ui_filename = homedir + "Maya/batchplacer.ui"
64+
main_form_class, main_base_class = loadUiType(main_ui_filename)
65+
slot_ui_filename = homedir + "Maya/batchplacer_slotrow.ui"
66+
slot_form_class, slot_base_class = loadUiType(slot_ui_filename)
67+
68+
# Slot Class
69+
class BatchPlacerExportSlotUI(slot_form_class, slot_base_class):
70+
def __init__(self, mainui, parent=None):
71+
super(BatchPlacerExportSlotUI, self).__init__(parent)
72+
self.setupUi(self)
73+
self.connectInterface()
74+
self.parentui = mainui
75+
self.setLayout(self.horizontalLayout)
76+
77+
def connectInterface(self):
78+
QtCore.QObject.connect(self.btnRemoveSlot, QtCore.SIGNAL("clicked()"), self.removeFromParent)
79+
QtCore.QObject.connect(self.btnMoveUpSlot, QtCore.SIGNAL("clicked()"), self.moveUpInParent)
80+
QtCore.QObject.connect(self.btnMoveDownSlot, QtCore.SIGNAL("clicked()"), self.moveDownInParent)
81+
QtCore.QObject.connect(self.lineObjName, QtCore.SIGNAL("textEdited(QString)"), self.saveAllSlots)
82+
QtCore.QObject.connect(self.lineUnrealName, QtCore.SIGNAL("textEdited(QString)"), self.saveAllSlots)
83+
84+
def removeFromParent(self):
85+
for i in xrange(self.parentui.listWidget.count()):
86+
slotWidget = self.parentui.listWidget.itemWidget(self.parentui.listWidget.item(i))
87+
if (self == slotWidget):
88+
self.parentui.listWidget.takeItem(i)
89+
self.parentui.saveAllSlots()
90+
return
91+
92+
def moveUpInParent(self):
93+
self.parentui.moveUpSlot(self)
94+
95+
def moveDownInParent(self):
96+
self.parentui.moveDownSlot(self)
97+
98+
def saveAllSlots(self, newtext):
99+
self.parentui.saveAllSlots()
100+
101+
102+
# Interface Class
103+
class BatchPlacerUI(main_form_class, main_base_class):
104+
def __init__(self, parent=None):
105+
super(BatchPlacerUI, self).__init__(parent)
106+
self.setupUi(self)
107+
self.setObjectName('UE4BatchPlacer')
108+
self.connectInterface()
109+
110+
lines = [line.strip() for line in open(usersettings)]
111+
112+
for x, y in pairwise(lines):
113+
item_widget = self.addExportSlot()
114+
item_widget.lineObjName.setText(x)
115+
item_widget.lineUnrealName.setText(y)
116+
117+
def connectInterface(self):
118+
QtCore.QObject.connect(self.btnExportSelected, QtCore.SIGNAL("clicked()"), self.exportSelected)
119+
QtCore.QObject.connect(self.btnAddExportSlot, QtCore.SIGNAL("clicked()"), self.addExportSlot)
120+
121+
def getUnrealMesh(self, inputName):
122+
if inputName is None:
123+
return None;
124+
for i in xrange(self.listWidget.count()):
125+
slotWidget = self.listWidget.itemWidget(self.listWidget.item(i))
126+
if slotWidget.lineObjName.text() not in inputName: continue
127+
return slotWidget.lineUnrealName.text()
128+
129+
def moveUpSlot(self, slotitem):
130+
taken = None
131+
foundId = 0
132+
mayaName = None
133+
unrealName = None
134+
for i in xrange(self.listWidget.count()):
135+
slotWidget = self.listWidget.itemWidget(self.listWidget.item(i))
136+
if (slotitem == slotWidget):
137+
if (i is not 0):
138+
mayaName = slotitem.lineObjName.text()
139+
unrealName = slotitem.lineUnrealName.text()
140+
taken = self.listWidget.takeItem(i)
141+
foundId = i
142+
break
143+
if (taken is not None):
144+
self.listWidget.insertItem(foundId-1,taken)
145+
item_widget = BatchPlacerExportSlotUI(self, self)
146+
item_widget.lineObjName.setText(mayaName)
147+
item_widget.lineUnrealName.setText(unrealName)
148+
taken.setSizeHint(item_widget.sizeHint())
149+
self.listWidget.setItemWidget(taken, item_widget)
150+
self.saveAllSlots()
151+
152+
def moveDownSlot(self, slotitem):
153+
taken = None
154+
foundId = 0
155+
mayaName = None
156+
unrealName = None
157+
for i in xrange(self.listWidget.count()):
158+
slotWidget = self.listWidget.itemWidget(self.listWidget.item(i))
159+
if (slotitem == slotWidget):
160+
if (i is not self.listWidget.count()-1):
161+
mayaName = slotitem.lineObjName.text()
162+
unrealName = slotitem.lineUnrealName.text()
163+
taken = self.listWidget.takeItem(i)
164+
foundId = i
165+
break
166+
if (taken is not None):
167+
self.listWidget.insertItem(foundId+1,taken)
168+
item_widget = BatchPlacerExportSlotUI(self, self)
169+
item_widget.lineObjName.setText(mayaName)
170+
item_widget.lineUnrealName.setText(unrealName)
171+
taken.setSizeHint(item_widget.sizeHint())
172+
self.listWidget.setItemWidget(taken, item_widget)
173+
self.saveAllSlots()
174+
175+
def addExportSlot(self):
176+
item = QtGui.QListWidgetItem(self.listWidget)
177+
item_widget = BatchPlacerExportSlotUI(self, self)
178+
item_widget.setLayout(item_widget.horizontalLayout)
179+
item.setSizeHint(item_widget.sizeHint())
180+
self.listWidget.addItem(item)
181+
self.listWidget.setItemWidget(item, item_widget)
182+
return item_widget
183+
184+
def exportSelected(self):
185+
exportable = False
186+
export_body = ""
187+
selection = om.MSelectionList()
188+
om.MGlobal.getActiveSelectionList(selection)
189+
selection_iter = om.MItSelectionList(selection)
190+
while not selection_iter.isDone():
191+
obj = om.MObject()
192+
dagPath = om.MDagPath()
193+
selection_iter.getDependNode(obj)
194+
selection_iter.getDagPath(dagPath)
195+
node = om.MFnDependencyNode(obj)
196+
unrealName = self.getUnrealMesh(node.name())
197+
if (unrealName is not None):
198+
exportable = True
199+
mt = om.MTransformationMatrix(dagPath.inclusiveMatrix())
200+
loc = mt.translation(om.MSpace.kWorld)
201+
rot = mt.rotation().asEulerRotation()
202+
scaleUtil = om.MScriptUtil()
203+
scaleUtil.createFromList([0,0,0],3)
204+
scaleVec = scaleUtil.asDoublePtr()
205+
mt.getScale(scaleVec, om.MSpace.kWorld)
206+
scale = [om.MScriptUtil.getDoubleArrayItem(scaleVec, i) for i in range(0,3)]
207+
if (cmds.upAxis(q=True,axis=True) == "y"):
208+
export_body += GetTemplatedExportBody(node.name(), unrealName, loc.x, loc.z, loc.y, math.degrees(rot.x), math.degrees(rot.z), math.degrees(rot.y), scale[0], scale[2], scale[1])
209+
else:
210+
export_body += GetTemplatedExportBody(node.name(), unrealName, loc.x, loc.y, loc.z, math.degrees(rot.x), math.degrees(rot.y), math.degrees(rot.z), scale[0], scale[1], scale[2])
211+
selection_iter.next()
212+
if (exportable is True):
213+
export = ue4_static_header + export_body + ue4_static_footer
214+
clipboard = QtGui.QApplication.clipboard()
215+
clipboard.setText(export)
216+
217+
218+
def saveAllSlots(self):
219+
f = open(usersettings, 'w')
220+
for i in xrange(self.listWidget.count()):
221+
slotWidget = self.listWidget.itemWidget(self.listWidget.item(i))
222+
f.write(slotWidget.lineObjName.text() + '\n')
223+
f.write(slotWidget.lineUnrealName.text() + '\n')
224+
f.close()
225+
226+
# main
227+
def main():
228+
global ui
229+
ui = BatchPlacerUI()
230+
ui.show()
231+
232+
def show():
233+
global ui
234+
if (ui != None):
235+
ui.show()
236+
else:
237+
main()
238+
239+
if __name__ == "__main__":
240+
main()

Maya/LoadProductivityTools.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import sys
2+
try: BatchPlacer.show()
3+
except:
4+
Dir = 'D:/allarjealdepot/Engine/Extras/ProductivityPlugin/Maya'
5+
if Dir not in sys.path:
6+
sys.path.append(Dir)
7+
try: reload(BatchPlacer)
8+
except: import BatchPlacer
9+
BatchPlacer.main()

0 commit comments

Comments
 (0)