More specifically:
As shown in the video, if I have a chain that has 4 bones and I select all of them, I only get returned from Pinocchio 3 columns and incorrect weighting. The num of columns in 'weightFile.weight' = num of bones that were read
However, if I add the bones + the effector, I get 4 columns and correct weighting.
I tried the script on a biped but got errors so moved to a basic hand with 5 chains (4 fingers and 1 wrist) = 5 effectors and 11 bones. If I select just the bones I only get 8 columns and incorrect weighting. I would expect to get 6 columns here to be consistent with the first example. Since its not consistent, I have to choose arbitrary effectors to get my weight column count == num bones.
The result is that the weighting is the same/worse than default linear and takes much longer than it should. If I go into Maya where there are no effectors, the weighting is far superior. There, I use pm_heatweight, a python script that acts as a front end to pinocchio. I translated that to get mine.
Can I turn off the default ik effectors when drawing a chain? Would this make a diff? Is there a problem with the script?
Code: Select all
import subprocess
import tempfile
import os
import os.path
import platform
import traceback
xsi = Application
log = xsi.LogMessage
_PINOCCHIO_DIR = 'C:/Users/aleks/Desktop/pinocchio/'
_PINOCCHIO_BIN = 'C:/Users/aleks/Desktop/pinocchio/AttachWeightsWin.exe'
skelFilePath = 'C:/Users/aleks/Desktop/pinocchio/skelFile.skel'
objFilePath = 'C:/Users/aleks/Desktop/pinocchio/dupe.obj'
objSavePath = 'C:\\Users\\aleks\\Desktop\\pinocchio\\dupe.obj'
weightPath = 'C:/Users/aleks/Desktop/pinocchio/weightFile.weight'
#select the Mesh and then the root
initialSel = xsi.Selection
picked = []
for i in initialSel:
if i.type == 'polymsh':
picked.append(i.name)
if i.type == 'root':
xsi.SelectObj(i, "BRANCH", "")
xsi.SelectChildNodes("", "", "")
sel = xsi.Selection
tempBones = []
tempBonesNames = []
for i in sel:
if i.type == 'root':
pass
else:
tempBones.append(i)
tempBonesNames.append(i.name)
BoneList = (tempBones)
skelFile = open(skelFilePath, 'w')
for idx, i in enumerate(BoneList):
skelFile.write("%d %.5f %.5f %.5f %d\n" % (idx, i.Kinematics.Global.PosX.Value,
i.Kinematics.Global.PosY.Value,
i.Kinematics.Global.PosZ.Value,
idx-1))
skelFile.close()
#Duplicate mesh/cap/triangulate/export/delete
xsi.Duplicate(picked[0], "", 2, 1, 1, 0, 0, 1, 0, 1, "", "", "", "", "", "", "", "", "", "", 0)
objectSelected = xsi.Selection(0)
pntA = objectSelected.ActivePrimitive.Geometry.Points.Count
xsi.SetSelFilter("Edge")
borderEdges = xsi.SelectAllUsingFilter("Border_Edge", "siCheckComponentVisibility", "", "")
if borderEdges.Count > 0:
xsi.DuplicateMeshComponent()
xsi.ApplyTopoOp("Collapse")
#get new point count
pntB = objectSelected.ActivePrimitive.Geometry.Points.Count
#select new points
for i in range(pntA, pntB):
xsi.ActivateVertexSelTool()
xsi.AddToSelection(objectSelected.FullName + ".pnt[" + str(i) + "]")
#collapse them
xsi.ApplyTopoOp("Collapse")
xsi.ActivateObjectSelTool("")
xsi.ApplyTopoOp("TriangulatePolygons", objectSelected, "siUnspecified", "siPersistentOperation", "")
xsi.SelectObj(objectSelected, "", True)
xsi.ObjExport(objSavePath, "", "", "", "", "", "", "", "", "", 0, False, False, False, False)
#delete
xsi.DeleteObj(objectSelected)
##reselect original
xsi.SelectObj(picked[0], "", True)
#envelope bones to object
semi = ';'
theBones = ",".join(tempBonesNames)
createEnvelopeALL = '%s%s%s' %(picked[0], semi, theBones)
xsi.SIApplyFlexEnv(createEnvelopeALL, "False", "", 2)
xsi.SelectObj(picked[0], "", True)
#run Pinocchio
stiffness = 1.0
os.chdir(_PINOCCHIO_DIR)
exeAndArgs = [_PINOCCHIO_BIN, objFilePath,
'-skel', skelFilePath,
'-stiffness', str(stiffness),
'-skelOut', skelFilePath,
'-weightOut', weightPath]
returnVal = subprocess.call(exeAndArgs)
#apply the weights
weightFileImport = open(weightPath, 'r')
weightList = []
for line in weightFileImport:
weightList.append([float(x) for x in line.strip().split(' ')])
weightFileImport.close()
weighListLength = len(weightList)
xsi.SetSelFilter("Object")
xsi.SelectObj(picked[0], "", True)
for i in xsi.Selection:
if i.Envelopes.Count > 0:
env = i.Envelopes(0)
envCls = (p.Target2 for p in env.InputPorts if p.Target2.Type == "envweights").next()
for idx, b in enumerate(tempBones):
for vert in range(0, weighListLength):
if b.type == 'eff':
pass
else:
weightFileImport = open(weightPath, 'r')
weightList = []
for line in weightFileImport:
weightList.append([float(x) for x in line.strip().split(' ')])
weightFileImport.close()
first = '.pnt['
middle = vert
last = ']'
allTogether = '%s%s%s' %(first, middle, last)
xsi.SIModifyFlexEnvWght(envCls.FullName, b.Name, i.FullName+allTogether, 2, (weightList[vert].pop(idx)), False)