Skip to content

Commit ff31173

Browse files
authored
Hotfix/smpx sppedup (#8)
* Speed up smpx import in Maya
1 parent ef49009 commit ff31173

File tree

1 file changed

+117
-48
lines changed

1 file changed

+117
-48
lines changed

scripts/SimplexUI/mayaInterface.py

Lines changed: 117 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,10 @@
2525
import maya.OpenMaya as om
2626
from loadUiType import QtCore, Signal, QApplication, QSplashScreen, QDialog, QMainWindow
2727

28-
# Blur sys.path management puts an improper alembic import before Maya's
29-
# Do a little dance so that the proper alembic module gets imported
30-
# Shouldn't be needed externally
3128
#sys.path.insert(0, r'C:\Program Files\Autodesk\Maya2016\Python\lib\site-packages')
32-
#import alembic
33-
#from alembic.Abc import V3fTPTraits, Int32TPTraits
34-
#from alembic.AbcGeom import OPolyMeshSchemaSample
29+
import alembic
30+
from alembic.Abc import V3fTPTraits, Int32TPTraits
31+
from alembic.AbcGeom import OPolyMeshSchemaSample
3532
#sys.path.pop(0) # make sure to undo my stupid little hack
3633

3734

@@ -155,7 +152,8 @@ def loadConnections(self, simp, create=True):
155152
if not s:
156153
if not create:
157154
raise RuntimeError("Shape {0} not found with creation turned off".format(shape.name))
158-
self.createRawShape(shape.name, shape)
155+
shp = self.createRawShape(shape.name, shape)
156+
cmds.delete(shp)
159157
else:
160158
shape.thing = s[0]
161159
shapeIdx = self.simplex.shapes.index(shape)
@@ -206,34 +204,115 @@ def buildRestABC(self, abcMesh, js):
206204
om.MFnDependencyNode(meshMObj).setName(cName)
207205
cmds.sets(cName, e=True, forceElement="initialShadingGroup")
208206
return cName
209-
207+
208+
209+
#@undoable
210+
#def loadABC_OLD(self, abcMesh, js, pBar=None):
211+
#meshSchema = abcMesh.getSchema()
212+
#rawFaces = meshSchema.getFaceIndicesProperty().samples[0]
213+
#rawCounts = meshSchema.getFaceCountsProperty().samples[0]
214+
#rawPos = meshSchema.getPositionsProperty().samples[0]
215+
#shapes = js["shapes"]
216+
#shapeDict = {i.name:i for i in self.simplex.shapes}
217+
218+
#numVerts = len(rawPos)
219+
#numFaces = len(rawCounts)
220+
221+
#counts = om.MIntArray()
222+
#faces = om.MIntArray()
223+
#ptr = 0
224+
#for i in rawCounts:
225+
#counts.append(i)
226+
#for j in reversed(rawFaces[ptr: ptr+i]):
227+
#faces.append(j)
228+
#ptr += i
229+
230+
#restVertArray = om.MFloatPointArray()
231+
#restVertArray.setLength(numVerts)
232+
#for i, v in enumerate(rawPos):
233+
#fp = om.MFloatPoint(v[0], v[1], v[2])
234+
#restVertArray.set(fp, i)
235+
236+
##xferDeltas = []
237+
#xferDeltas = om.MVectorArray()
238+
#xferDeltas.setLength(numVerts)
239+
#restPos = self._getMeshVertices(self.mesh)
240+
#sameBase = True
241+
#for idx, (i, j) in enumerate(zip(restPos, rawPos)):
242+
#fp = om.MVector(i[0]-j[0], i[1]-j[1], i[2]-j[2])
243+
#if sameBase:
244+
#vlen = fp.length()
245+
#if vlen > 0.00001:
246+
#sameBase = False
247+
#xferDeltas.set(fp, idx)
248+
249+
#if pBar is not None:
250+
#pBar.show()
251+
#pBar.setMaximum(len(shapes))
252+
#longName = max(shapes, key=len)
253+
#pBar.setValue(1)
254+
#pBar.setLabelText("Loading:\n{0}".format("_"*len(longName)))
255+
256+
#posProp = meshSchema.getPositionsProperty()
257+
258+
## Create the mesh only once
259+
#meshFn = om.MFnMesh()
260+
#meshMObj = meshFn.create(numVerts, numFaces, restVertArray, counts, faces)
261+
#cName = "AbcConnect"
262+
#om.MFnDependencyNode(meshMObj).setName(cName)
263+
264+
#vertexArray = om.MPointArray()
265+
#vertexArray.setLength(numVerts)
266+
#for i, shapeName in enumerate(shapes):
267+
#if pBar is not None:
268+
#pBar.setValue(i)
269+
#pBar.setLabelText("Loading:\n{0}".format(shapeName))
270+
#QApplication.processEvents()
271+
#if pBar.wasCanceled():
272+
#return
273+
274+
#verts = posProp.samples[i]
275+
#for j in xrange(numVerts):
276+
#fp = om.MPoint(verts[j][0], verts[j][1], verts[j][2])
277+
#if not sameBase:
278+
#fp += xferDeltas[j]
279+
#vertexArray.set(fp, j)
280+
281+
#meshFn.setPoints(vertexArray)
282+
## Finally connect the blendshape
283+
#self.connectShape(shapeDict[shapeName], cName, live=False, delete=False)
284+
285+
#cmds.delete(cName)
286+
287+
#if pBar is not None:
288+
#pBar.setValue(len(shapes))
289+
210290
@undoable
211291
def loadABC(self, abcMesh, js, pBar=None):
212-
meshSchema = abcMesh.getSchema()
213-
rawFaces = meshSchema.getFaceIndicesProperty().samples[0]
214-
rawCounts = meshSchema.getFaceCountsProperty().samples[0]
215-
rawPos = meshSchema.getPositionsProperty().samples[0]
292+
# UGH, I *REALLY* hate that this is faster
293+
# But if I want to be "pure" about it, I should just bite the bullet
294+
# and do the direct alembic manipulation in C++
295+
abcPath = str(abcMesh.getArchive())
296+
297+
abcNode = cmds.createNode('AlembicNode')
298+
cmds.setAttr(abcNode + ".abc_File", abcPath, type="string")
299+
cmds.setAttr(abcNode + ".speed", 24)
216300
shapes = js["shapes"]
217301
shapeDict = {i.name:i for i in self.simplex.shapes}
218302

219-
numVerts = len(rawPos)
220-
numFaces = len(rawCounts)
221-
222-
counts = om.MIntArray()
223-
faces = om.MIntArray()
224-
ptr = 0
225-
for i in rawCounts:
226-
counts.append(i)
227-
for j in reversed(rawFaces[ptr: ptr+i]):
228-
faces.append(j)
229-
ptr += i
303+
importHead = cmds.polySphere(name='importHead', constructionHistory=False)[0]
304+
importHeadShape = [i for i in cmds.listRelatives(importHead, shapes=True)][0]
230305

231-
vertexArray = om.MFloatPointArray()
306+
cmds.connectAttr(abcNode+".outPolyMesh[0]", importHeadShape+".inMesh")
307+
vertCount = cmds.polyEvaluate(importHead, vertex=True) # force update
308+
cmds.disconnectAttr(abcNode+".outPolyMesh[0]", importHeadShape+".inMesh")
232309

233-
xferDeltas = []
234-
restPos = self._getMeshVertices(self.mesh)
235-
for i, j in zip(restPos, rawPos):
236-
xferDeltas.append((i[0]-j[0], i[1]-j[1], i[2]-j[2]))
310+
importBS = cmds.blendShape(self.mesh, importHead)[0]
311+
cmds.blendShape(importBS, edit=True, weight=[(0, 1.0)])
312+
# Maybe get shapeNode from self.mesh??
313+
cmds.disconnectAttr(self.mesh+'.worldMesh[0]', importBS+'.inputTarget[0].inputTargetGroup[0].inputTargetItem[6000].inputGeomTarget')
314+
importOrig = [i for i in cmds.listRelatives(importHead, shapes=True) if i.endswith('Orig')][0]
315+
cmds.connectAttr(abcNode+".outPolyMesh[0]", importOrig+".inMesh")
237316

238317
if pBar is not None:
239318
pBar.show()
@@ -242,34 +321,24 @@ def loadABC(self, abcMesh, js, pBar=None):
242321
pBar.setValue(1)
243322
pBar.setLabelText("Loading:\n{0}".format("_"*len(longName)))
244323

245-
posProp = meshSchema.getPositionsProperty()
246324
for i, shapeName in enumerate(shapes):
247325
if pBar is not None:
248326
pBar.setValue(i)
249327
pBar.setLabelText("Loading:\n{0}".format(shapeName))
250328
QApplication.processEvents()
251329
if pBar.wasCanceled():
252330
return
253-
verts = posProp.samples[i]
254-
vertexArray = om.MFloatPointArray()
255-
256-
for j in xrange(numVerts):
257-
fp = om.MFloatPoint(
258-
verts[j][0] + xferDeltas[j][0],
259-
verts[j][1] + xferDeltas[j][1],
260-
verts[j][2] + xferDeltas[j][2]
261-
)
262-
vertexArray.append(fp)
263-
264-
meshFn = om.MFnMesh()
265-
meshMObj = meshFn.create(numVerts, numFaces, vertexArray, counts, faces)
266-
cName = "{0}_AbcConnect".format(shapeName)
267-
om.MFnDependencyNode(meshMObj).setName(cName)
268-
# Finally connect the blendshape
269-
self.connectShape(shapeDict[shapeName], cName, live=True, delete=True)
331+
index = self._getShapeIndex(shapeDict[shapeName])
332+
cmds.setAttr(abcNode + ".time", i)
270333

271-
if pBar is not None:
272-
pBar.setValue(len(shapes))
334+
outAttr = "{0}.worldMesh[0]".format(importHead)
335+
tgn = "{0}.inputTarget[0].inputTargetGroup[{1}]".format(self.shapeNode, index)
336+
inAttr = "{0}.inputTargetItem[6000].inputGeomTarget".format(tgn)
337+
338+
cmds.connectAttr(outAttr, inAttr, force=True)
339+
cmds.disconnectAttr(outAttr, inAttr)
340+
cmds.delete(abcNode)
341+
cmds.delete(importHead)
273342

274343
def _getMeshVertices(self, mesh):
275344
# Get the MDagPath from the name of the mesh

0 commit comments

Comments
 (0)